@@ -752,6 +752,17 @@ const trait Foo {
752
752
753
753
where you still need to annotate the trait, but also annotate the const methods.
754
754
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
+
755
766
# Prior art
756
767
[ prior-art ] : #prior-art
757
768
@@ -846,3 +857,46 @@ So what we additionally need is some syntax like `const || {}` to declare a clos
846
857
While it may seem tempting to just automatically implement ` const Fn() ` (or ` ~const Fn() ` ) where applicable,
847
858
it's not clear that this can be done, and there are definite situations where it can't be done.
848
859
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