Skip to content

Commit fe1331e

Browse files
committed
Add per-method annotations alternative
1 parent 545099b commit fe1331e

File tree

1 file changed

+39
-1
lines changed

1 file changed

+39
-1
lines changed

text/0000-const-trait-impls.md

+39-1
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,43 @@ With the opt-out scheme that would still compile, but suddenly require callers t
641641
The safe default (and the one folks are used to for a few years now), is that trait bounds just work, you just
642642
can'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

Comments
 (0)