@@ -641,6 +641,43 @@ With the opt-out scheme that would still compile, but suddenly require callers t
641641The safe default (and the one folks are used to for a few years now), is that trait bounds just work, you just
642642can't call methods on them. To get more capabilities, you add more syntax. Thus the opt-out approach was not taken.
643643
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+
644681# Prior art
645682[ prior-art ] : #prior-art
646683
@@ -669,9 +706,10 @@ can't call methods on them. To get more capabilities, you add more syntax. Thus
669706 * ` T: Iterator<Item = U> ` and don't require ` where T: Iterator, <T as Iterator>::Item = U ` .
670707 * ` T: Iterator<Item: Debug> ` and don't require ` where T: Iterator, <T as Iterator>::Item: Debug ` .
671708 * 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} ` .
672710 * Very verbose (need to specify arguments and return type).
673711 * 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) .
675713 * Usually requires editing the trait anyway, so there's no "can constify impls without trait author opt in" silver bullet.
676714 * New RTN-like per-method bounds: ` T: Trait<some_fn(_): ~const> ` .
677715 * Unclear if soundly possible.
0 commit comments