You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: text/0000-const-trait-impls.md
+41-1
Original file line number
Diff line number
Diff line change
@@ -641,6 +641,45 @@ 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
+
traitDefault {
650
+
constfndefault() ->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
+
To get the advantages of the per-method constness alternative above, while avoiding the new kind of breaking change, we can require per-method and per-trait constness:
671
+
672
+
A mixed version of the above could be
673
+
674
+
```rust
675
+
consttraitFoo {
676
+
constfnfoo();
677
+
fnbar();
678
+
}
679
+
```
680
+
681
+
where you still need to annotate the trait, but also annotate the const methods.
682
+
644
683
# Prior art
645
684
[prior-art]: #prior-art
646
685
@@ -669,9 +708,10 @@ can't call methods on them. To get more capabilities, you add more syntax. Thus
669
708
*`T: Iterator<Item = U>` and don't require `where T: Iterator, <T as Iterator>::Item = U`.
670
709
*`T: Iterator<Item: Debug>` and don't require `where T: Iterator, <T as Iterator>::Item: Debug`.
671
710
* RTN for per-method bounds: `T: Trait<some_fn(..): ~const Fn(A, B) -> C>` could supplement this feature in the future.
711
+
* Alternatively `where <T as Trait>::some_fn(..): ~const` or `where <T as Trait>::some_fn \ {const}`.
672
712
* Very verbose (need to specify arguments and return type).
673
713
* 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.
714
+
* Significantly would delay const trait stabilization (by years).
675
715
* Usually requires editing the trait anyway, so there's no "can constify impls without trait author opt in" silver bullet.
676
716
* New RTN-like per-method bounds: `T: Trait<some_fn(_): ~const>`.
0 commit comments