Skip to content

Commit f7cc5e6

Browse files
committed
Elaborate on some extensions
1 parent 64c0773 commit f7cc5e6

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

text/0000-const-trait-impls.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,17 @@ const trait Foo {
752752

753753
where you still need to annotate the trait, but also annotate the const methods.
754754

755+
But it makes it much harder/more confusing to add
756+
757+
```rust
758+
trait Tr {
759+
const C: u8 = Self::f();
760+
const fn f() -> u8;
761+
}
762+
```
763+
764+
later, where even non-const traits can have const methods, that all impls must implement as a const fn.
765+
755766
# Prior art
756767
[prior-art]: #prior-art
757768

@@ -846,3 +857,46 @@ So what we additionally need is some syntax like `const || {}` to declare a clos
846857
While it may seem tempting to just automatically implement `const Fn()` (or `~const Fn()`) where applicable,
847858
it's not clear that this can be done, and there are definite situations where it can't be done.
848859
As further experimentation is needed here, const closures are not part of this RFC.
860+
861+
## Allow impls to refine any trait's methods
862+
863+
We could allow writing `const fn` in impls without the trait opting into it.
864+
This would not affect `T: Trait` bounds, but still allow non-generic calls.
865+
866+
This is simialar to other refinings in impls, as the function still satisfies everything from the trait.
867+
868+
Example: without adjusting `rand` for const trait support at all, users could write
869+
870+
```rust
871+
struct CountingRng(u64);
872+
873+
impl RngCore for CountingRng {
874+
const fn next_u32(&mut self) -> u32 {
875+
self.next_u64() as u32
876+
}
877+
878+
const fn next_u64(&mut self) -> u64 {
879+
self.0 += 1;
880+
self.0
881+
}
882+
883+
const fn fill_bytes(&mut self, dest: &mut [u8]) {
884+
let mut left = dest;
885+
while left.len() >= 8 {
886+
let (l, r) = { left }.split_at_mut(8);
887+
left = r;
888+
let chunk: [u8; 8] = rng.next_u64().to_le_bytes();
889+
l.copy_from_slice(&chunk);
890+
}
891+
let n = left.len();
892+
let chunk: [u8; 8] = rng.next_u64().to_le_bytes();
893+
left.copy_from_slice(&chunk[..n]);
894+
}
895+
896+
const fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
897+
Ok(self.fill_bytes(dest))
898+
}
899+
}
900+
```
901+
902+
and use it in non-generic code.

0 commit comments

Comments
 (0)