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
+40-36
Original file line number
Diff line number
Diff line change
@@ -15,17 +15,17 @@ Make trait methods callable in const contexts. This includes the following parts
15
15
Fully contained example ([Playground of currently working example](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=2ab8d572c63bcf116b93c632705ddc1b)):
@@ -66,7 +66,7 @@ This RFC requires familarity with "const contexts", so you may have to read [the
66
66
67
67
Calling functions during const eval requires those functions' bodies to only use statements that const eval can handle. While it's possible to just run any code until it hits a statement const eval cannot handle, that would mean the function body is part of its semver guarantees. Something as innocent as a logging statement would make the function uncallable during const eval.
68
68
69
-
Thus we have a marker (`const`) to add in front of functions that requires the function body to only contain things const eval can handle. This in turn allows a `const` annotated function to be called from const contexts, as you now have a guarantee it will stay callable.
69
+
Thus we have a marker, `const`, to add in front of functions that requires the function body to only contain things const eval can handle. This in turn allows a `const` annotated function to be called from const contexts, as you now have a guarantee it will stay callable.
70
70
71
71
When calling a trait method, this simple scheme (that works great for free functions and inherent methods) does not work.
Traits need to opt-in to allowing their impls to have const methods. Thus you need to prefix the methods you want to be const callable with `(const)`:
156
+
Traits need to opt-in to allowing their impls to have const methods. Thus you need to mark the trait as `const` and prefix the methods you want to be const callable with `(const)`.
157
+
Doing this at the same time is not a breaking change. Adding more `(const)` methods later is a breaking change (unless they are entirely new methods with default bodies).
157
158
158
159
```rust
159
-
traitTrait {
160
+
consttraitTrait {
160
161
(const) fnthing();
161
162
}
162
163
```
@@ -173,33 +174,34 @@ trait Trait {
173
174
}
174
175
```
175
176
176
-
and a result of this RFC would be that we would remove the attribute and add the `(const) fn` syntax for *methods*.
177
+
and a result of this RFC would be that we would remove the attribute and add the `(const) fn` syntax for *methods* and the `const trait` syntax
178
+
for trait declarations.
177
179
Free functions are unaffected and will stay as `const fn`.
178
180
179
181
### Impls for conditionally const methods
180
182
181
-
Methods that are declared as `(const)` on a trait can now be made `const` in an impl:
183
+
Methods that are declared as `(const)` on a trait can now be made `const` in an impl, if that impl is marked as `impl cosnt Trait`:
182
184
183
185
```rust
184
-
implTraitforType {
186
+
implconstTraitforType {
185
187
constfnthing() {}
186
188
}
187
189
```
188
190
189
-
If a single `(const)` method is declared as `const` in the impl, all `(const)` methods must be declared as such.
190
-
It is still completely fine to just declare no methods `const` and keep the existing behaviour. Thus adding `(const)`
191
-
methods to traits is not a breaking change. Only marking more methods as `(const)` if there are already some `(const)`
192
-
methods is.
191
+
193
192
194
193
### `const` methods and non-`const` methods on the same trait
195
194
195
+
If there is no `(const)` modifier on a method in a `const trait`, it is treated as any normal method is today.
196
+
So `impl const Trait` blocks cannot mark them as `const` either.
197
+
196
198
```rust
197
-
traitFoo {
199
+
consttraitFoo {
198
200
(const) fnfoo(&self);
199
201
fnbar(&self);
200
202
}
201
203
202
-
implFoofor () {
204
+
implconstFoofor () {
203
205
constfnfoo(&self) {}
204
206
fnbar(&self) {
205
207
println!("writing to terminal is not possible in const eval");
@@ -209,20 +211,20 @@ impl Foo for () {
209
211
210
212
### Conditionally-const trait bounds
211
213
212
-
Many generic `const fn` and especially many trait impls of traits with `(const)` methods do not actually require a const methods in the trait impl for their generic parameters.
214
+
Many generic `const fn` and especially many `const trait`s do not actually require a const methods in the trait impl for their generic parameters.
213
215
As `const fn` can also be called at runtime, it would be too strict to require it to only be able to call things with const methods in the trait impls.
214
216
Picking up the example from [the beginning](#summary):
215
217
216
218
```rust
217
-
traitDefault {
219
+
consttraitDefault {
218
220
(const) fndefault() ->Self;
219
221
}
220
222
221
-
implDefaultfor () {
223
+
implconstDefaultfor () {
222
224
constfndefault() {}
223
225
}
224
226
225
-
impl<T:Default> DefaultforBox<T> {
227
+
impl<T:Default> constDefaultforBox<T> {
226
228
fndefault() ->Self { Box::new(T::default()) }
227
229
}
228
230
@@ -294,20 +296,20 @@ which we definitely do not support and have historically rejected over and over
294
296
295
297
### Impls with const methods for conditionally const trait methods
296
298
297
-
trait impls with const methods for generic types work similarly to generic `const fn`.
298
-
Any `impl Trait for Type` is allowed to have `(const)` trait bounds if it has `const` methods:
299
+
`const trait` impls for generic types work similarly to generic `const fn`.
300
+
Any `impl const Trait for Type` is allowed to have `(const)` trait bounds:
0 commit comments