Skip to content

Commit 73e06e4

Browse files
committed
Const fn traits and not doing this RFC
1 parent fb621b6 commit 73e06e4

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed

text/0000-const-trait-impls.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,41 @@ will likely be tracked under a separate feature gate under the purview of T-libs
341341
Similarly other traits will be made `const` over time, but doing so will be
342342
unblocked by this feature.
343343

344+
### `const Fn*` traits
345+
346+
All `const fn` implement the corresponding `const Fn()` trait:
347+
348+
```rust
349+
const fn foo<F: ~const Fn()>(f: F) {
350+
f()
351+
}
352+
353+
const fn bar() {
354+
foo(baz)
355+
}
356+
357+
const fn baz() {}
358+
```
359+
360+
Arguments and the return type of such functions and bounds follow the same rules as
361+
their non-const equivalents, so you may have to add `~const` bounds to other generic
362+
parameters, too:
363+
364+
365+
```rust
366+
const fn foo<T: ~const Debug, F: ~const Fn(T)>(f: F, arg: T) {
367+
f(arg)
368+
}
369+
370+
const fn bar<T: ~const Debug>(arg: T) {
371+
foo(baz, arg)
372+
}
373+
374+
const fn baz<T: ~const Debug>() {}
375+
```
376+
377+
For closures and them implementing the `Fn` traits, see the [Future possibilities](#future-possibilities) section.
378+
344379
## Crate authors: Making your own custom types easier to use
345380

346381
You can write const trait impls of many standard library traits for your own types.
@@ -681,6 +716,62 @@ trait Foo: InitFoo {
681716
# Alternatives
682717
[alternatives]: #alternatives
683718

719+
## What is the impact of not doing this?
720+
721+
We would require everything that wants a const-equivalent to have duplicated traits and not
722+
use `const` fn at all, but use associated consts instead. Similarly this would likely forbid
723+
invoking builtin operators. This same concern had been brought up for the `const fn` stabilization
724+
[7 years ago](https://github.com/rust-lang/rust/issues/24111#issuecomment-385046163).
725+
726+
Basically what we can do is create
727+
728+
```rust
729+
trait ConstDefault {
730+
const DEFAULT: Self;
731+
}
732+
```
733+
734+
and require users to use
735+
736+
```rust
737+
const FOO: Vec<u8> = ConstDefault::DEFAULT;
738+
```
739+
740+
instead of
741+
742+
```rust
743+
const fn FOO: Vec<u8> = Default::default();
744+
```
745+
746+
This duplication is what this RFC is suggesting to avoid.
747+
748+
Since it has already been possible to do all of this on stable Rust for years, and no major
749+
crates have popped and gotten used widely, I assume that is either because
750+
751+
* it's too much duplication, or
752+
* everyone was waiting for the work (that this RFC wants to stabilize) to finish, or
753+
* both.
754+
755+
So while it is entirely possible that rejecting this RFC and deciding not to go down this route
756+
will lead to an ecosystem for const operations to be created, it would result in duplication and
757+
inconsistencies that we'd rather like to avoid.
758+
759+
Such an ecosystem would also make `const fn` obsolete, as every `const fn` can in theory be represented
760+
as a trait, it would just be very different to use from normal rust code and not really allow nice abstractions to be built.
761+
762+
```rust
763+
const fn add(a: u32, b: u32) -> u32 { a + b }
764+
765+
struct Add<const A: u32, const B: u32>;
766+
767+
impl<const A: u32, const B:u32> Add<A, B> {
768+
const RESULT: u32 = A + B;
769+
}
770+
771+
const FOO: u32 = add(5, 6);
772+
const BAR: u32 = Add<5, 6>::RESULT;
773+
```
774+
684775
## use `const Trait` bounds for conditionally-const, invent new syntax for always-const
685776

686777
It may seem tempting to use `const fn foo<T: const Trait>` to mean what in this RFC is `~const Trait`, and then add new syntax for bounds that allow using trait methods in const blocks.

0 commit comments

Comments
 (0)