@@ -641,6 +641,43 @@ With the opt-out scheme that would still compile, but suddenly require callers t
641
641
The safe default (and the one folks are used to for a few years now), is that trait bounds just work, you just
642
642
can't call methods on them. To get more capabilities, you add more syntax. Thus the opt-out approach was not taken.
643
643
644
+ ## Per-method constness instead of per-trait
645
+
646
+ We could require trait authors to declare which methods can be const:
647
+
648
+ ``` rust
649
+ trait Default {
650
+ const fn default () -> Self ;
651
+ }
652
+ ```
653
+
654
+ This has two major advantages:
655
+
656
+ * you can now have const and non-const methods in your trait without requiring an opt-out
657
+ * you can add new methods with default bodies and don't have to worry about new kinds of breaking changes
658
+
659
+ The specific syntax given here may be confusing though, as it looks like the function is always const, but
660
+ implementations can use non-const impls and thus make the impl not usable for ` T: ~const Trait ` bounds.
661
+
662
+ Though this means that changing a non-const fn in the trait to a const fn is a breaking change, as the user may
663
+ have that previous-non-const fn as a non-const fn in the impl, causing the entire impl now to not be usable for
664
+ ` T: ~const Trait ` anymore.
665
+
666
+ See also: out of scope RTN notation in [ Unresolved questions] ( #unresolved-questions )
667
+
668
+ ## Per-method and per-trait constness together:
669
+
670
+ A mixed version of the above could be
671
+
672
+ ``` rust
673
+ const trait Foo {
674
+ const fn foo ();
675
+ fn bar ();
676
+ }
677
+ ```
678
+
679
+ where you still need to annotate the trait, but also annotate the const methods.
680
+
644
681
# Prior art
645
682
[ prior-art ] : #prior-art
646
683
@@ -669,9 +706,10 @@ can't call methods on them. To get more capabilities, you add more syntax. Thus
669
706
* ` T: Iterator<Item = U> ` and don't require ` where T: Iterator, <T as Iterator>::Item = U ` .
670
707
* ` T: Iterator<Item: Debug> ` and don't require ` where T: Iterator, <T as Iterator>::Item: Debug ` .
671
708
* RTN for per-method bounds: ` T: Trait<some_fn(..): ~const Fn(A, B) -> C> ` could supplement this feature in the future.
709
+ * Alternatively ` where <T as Trait>::some_fn(..): ~const ` or ` where <T as Trait>::some_fn \ {const} ` .
672
710
* Very verbose (need to specify arguments and return type).
673
711
* Want short hand sugar anyway to make it trivial to change a normal function to a const function by just adding some minor annotations.
674
- * Significantly would delay const trait stabilization.
712
+ * Significantly would delay const trait stabilization (by years) .
675
713
* Usually requires editing the trait anyway, so there's no "can constify impls without trait author opt in" silver bullet.
676
714
* New RTN-like per-method bounds: ` T: Trait<some_fn(_): ~const> ` .
677
715
* Unclear if soundly possible.
0 commit comments