@@ -46,23 +46,26 @@ impl const Add for MyInt {
46
46
}
47
47
```
48
48
49
- The const requirement is propagated to all bounds of the impl or its methods,
49
+ The const requirement is required on all bounds of the impl and its methods,
50
50
so in the following ` H ` is required to have a const impl of ` Hasher ` , so that
51
51
methods on ` state ` are callable.
52
52
53
53
``` rust
54
54
impl const Hash for MyInt {
55
- fn hash <H >(
55
+ const fn hash <H >(
56
56
& self ,
57
57
state : & mut H ,
58
58
)
59
- where H : Hasher
59
+ where H : const Hasher
60
60
{
61
61
state . write (& [self . 0 as u8 ]);
62
62
}
63
63
}
64
64
```
65
65
66
+ While these ` const ` keywords could be inferred (after all, they are required), requiring them is
67
+ forward compatible to schemes in the future that allow more fine grained control.
68
+
66
69
## Drop
67
70
68
71
A notable use case of ` impl const ` is defining ` Drop ` impls. If you write
@@ -80,17 +83,67 @@ Then you are allowed to actually let a value of `SomeDropType` get dropped withi
80
83
evaluation. This means ` (SomeDropType(&Cell::new(42)), 42).1 ` is now allowed, because we can prove
81
84
that everything from the creation of the value to the destruction is const evaluable.
82
85
86
+ ## Runtime uses don't have ` const ` restrictions?
87
+
88
+ ` impl const ` blocks additionally generate impls that are not const if any generic
89
+ parameters are not const.
90
+
91
+ E.g.
92
+
93
+ ``` rust
94
+ impl <T : const Add > const Add for Foo <T > {
95
+ fn add (self , other : Self ) -> Self {
96
+ Foo (self . 0 + other . 0 )
97
+ }
98
+ }
99
+ ```
100
+
101
+ allows calling ` Foo(String::from("foo")) + Foo(String::from("bar")) ` even though that is (at the time
102
+ of writing this RFC) most definitely not const, because ` String ` only has an ` impl Add for String `
103
+ and not an ` impl const Add for String ` .
104
+
105
+ This goes in hand with the current scheme for const functions, which may also be called
106
+ at runtime with runtime arguments, but are checked for soundness as if they were called in
107
+ a const context. E.g. the following function may be called as
108
+ ` add(String::from("foo"), String::from("bar")) ` at runtime.
109
+
110
+ ``` rust
111
+ const fn add <T : const Add >(a : T , b : T ) -> T {
112
+ a + b
113
+ }
114
+ ```
115
+
116
+ This feature could have been added in the future in a backwards compatible manner, but without it
117
+ the use of ` const ` impls is very restricted for the generic types of the standard library due to
118
+ backwards compatibility.
119
+ Changing an impl to only allow generic types which have a ` const ` impl for their bounds would break
120
+ situations like the one described above.
121
+
83
122
# Reference-level explanation
84
123
[ reference-level-explanation ] : #reference-level-explanation
85
124
86
125
The implementation of this RFC is (in contrast to some of its alternatives) mostly
87
- changes around the syntax of the language (adding ` const ` modifiers in a few places)
126
+ changes around the syntax of the language (allowing ` const ` modifiers in a few places)
88
127
and ensuring that lowering to HIR and MIR keeps track of that.
89
128
The miri engine already fully supports calling methods on generic
90
129
bounds, there's just no way of declaring them. Checking methods for constness is already implemented
91
130
for inherent methods. The implementation will have to extend those checks to also run on methods
92
131
of ` impl const ` items.
93
132
133
+ ## Implementation instructions
134
+
135
+ 1 . Add an ` is_const ` field to the AST's ` TraitRef `
136
+ 2 . Adjust the Parser to support ` const ` modifiers before trait bounds
137
+ 3 . Add an ` is_const ` field to the HIR's ` TraitRef `
138
+ 4 . Adjust lowering to pass through the ` is_const ` field from AST to HIR
139
+ 5 . Add a a check to ` librustc_typeck/check/wfcheck.rs ` ensuring that all generic bounds
140
+ in an ` impl const ` block have the ` in_const ` flag set and all methods' ` constness ` field is
141
+ ` Const ` .
142
+ 6 . Feature gate instead of ban ` Predicate::Trait ` other than ` Sized ` in
143
+ ` librustc_mir/transform/qualify_min_const_fn.rs `
144
+ 7 . Remove the call in https://github.com/rust-lang/rust/blob/f8caa321c7c7214a6c5415e4b3694e65b4ff73a7/src/librustc_passes/ast_validation.rs#L306
145
+ 8 . Adjust the reference and the book to reflect these changes.
146
+
94
147
# Drawbacks
95
148
[ drawbacks ] : #drawbacks
96
149
@@ -211,45 +264,4 @@ and `const` modifiers on `impl` blocks.
211
264
# Unresolved questions
212
265
[ unresolved-questions ] : #unresolved-questions
213
266
214
- ## Runtime uses don't have ` const ` restrictions?
215
-
216
- Should ` impl const ` blocks additionally generate impls that are not const if any generic
217
- parameters are not const?
218
-
219
- E.g.
220
-
221
- ``` rust
222
- impl <T : Add > const Add for Foo <T > {
223
- fn add (self , other : Self ) -> Self {
224
- Foo (self . 0 + other . 0 )
225
- }
226
- }
227
- ```
228
-
229
- would allow calling ` Foo(String::from("foo")) + Foo(String::from("bar")) ` even though that is (at the time
230
- of writing this RFC) most definitely not const, because ` String ` only has an ` impl Add for String `
231
- and not an ` impl const Add for String ` .
232
-
233
- This would go in hand with the current scheme for const functions, which may also be called
234
- at runtime with runtime arguments, but are checked for soundness as if they were called in
235
- a const context.
236
-
237
- ## Require ` const ` bounds on everything inside an ` impl const ` block?
238
-
239
- Instead of inferring ` const ` ness on all bounds and functions inside a ` impl const ` block,
240
- we force the user to supply these bounds. This is more consistent with not inferring ` const `
241
- on ` const ` function argument types and generic bounds. The ` Hash ` example from above would
242
- then look like
243
-
244
- ``` rust
245
- impl const Hash for MyInt {
246
- const fn hash <H >(
247
- & self ,
248
- state : & mut H ,
249
- )
250
- where H : const Hasher
251
- {
252
- state . write (& [self . 0 as u8 ]);
253
- }
254
- }
255
- ```
267
+ Everything has been addressed in the reviews
0 commit comments