7
7
[ summary ] : #summary
8
8
9
9
Relaxes the rules for repeat expressions, ` [x; N] ` such that ` x ` may also be
10
- ` const ` , in addition to ` typeof(x): Copy ` . The result of ` [x; N] ` where ` x ` is
11
- ` const ` is itself also ` const ` .
10
+ ` const ` * (strictly speaking rvalue promotable) * , in addition to ` typeof(x): Copy ` .
11
+ The result of ` [x; N] ` where ` x ` is ` const ` is itself also ` const ` .
12
12
13
13
# Motivation
14
14
[ motivation ] : #motivation
@@ -107,34 +107,51 @@ fn main() {
107
107
internally as:
108
108
109
109
``` rust
110
- // This is the value to be repeated and typeof(X) the type it has.
111
- // If a `VALUE` panics, it happens during compile time at this point
112
- // and not later.
113
- const X : typeof (X ) = VALUE ;
114
-
115
- // N is the size of the array and how many times to repeat X.
116
- const N : usize = SIZE ;
117
-
118
- {
119
- let mut data : [typeof (X ); N ];
120
-
121
- unsafe {
122
- data = mem :: uninitialized ();
123
-
124
- let mut iter = (& mut data [.. ]). into_iter ();
125
- while let Some (elem ) = iter . next () {
126
- // ptr::write does not run destructor of elem already in array.
127
- // Since X is const, it can not panic at this point.
128
- ptr :: write (elem , X );
110
+ fn main () {
111
+ type T = Option <Box <u32 >>;
112
+
113
+ // This is the value to be repeated.
114
+ // In this case, a panic won't happen, but if it did, that panic
115
+ // would happen during compile time at this point and not later.
116
+ const X : T = None ;
117
+
118
+ let mut arr = {
119
+ let mut data : [T ; 2 ];
120
+
121
+ unsafe {
122
+ data = mem :: uninitialized ();
123
+
124
+ let mut iter = (& mut data [.. ]). into_iter ();
125
+ while let Some (elem ) = iter . next () {
126
+ // ptr::write does not run destructor of elem already in array.
127
+ // Since X is const, it can not panic at this point.
128
+ ptr :: write (elem , X );
129
+ }
129
130
}
130
- }
131
131
132
- data
132
+ data
133
+ };
134
+
135
+ arr [0 ] = Some (Box :: new (1 ));
133
136
}
134
137
```
135
138
136
- Additionally, the pass that checks ` const ` ness must treat ` [X; N] ` as a ` const `
137
- value.
139
+ Additionally, the pass that checks ` const ` ness must treat ` [expr; N] ` as a
140
+ ` const ` value such that ` [expr; N] ` is assignable to a ` const ` item as well
141
+ as permitted inside a ` const fn ` .
142
+
143
+ Strictly speaking, the set of values permitted in the expression ` [expr; N] `
144
+ are those where ` is_rvalue_promotable(expr) ` or ` typeof(expr): Copy ` .
145
+ Specifically, in ` [expr; N] ` the expression ` expr ` is evaluated:
146
+ + never, if ` N == 0 ` ,
147
+ + one time, if ` N == 1 ` ,
148
+ + ` N ` times, otherwise.
149
+
150
+ For values that are not freely duplicatable, evaluating ` expr ` will result in
151
+ a move, which results in an error if ` expr ` is moved more than once (including
152
+ moves outside of the repeat expression). These semantics are intentionally
153
+ conservative and intended to be forward-compatible with a more expansive
154
+ ` is_const(expr) ` check.
138
155
139
156
# Drawbacks
140
157
[ drawbacks ] : #drawbacks
@@ -153,8 +170,16 @@ other constructs such as [`mem::uninitialized()`], for loops over iterators,
153
170
this RFC is therefore the simplest and most non-intrusive design. It is also
154
171
the most consistent.
155
172
173
+ Another alternative is to allow a more expansive set of values ` is_const(expr) `
174
+ rather than ` is_rvalue_promotable(expr) ` . A consequence of this is that checking
175
+ constness would be done earlier on the HIR. Instead, checking if ` expr ` is
176
+ rvalue promotable can be done on the MIR and does not require significant
177
+ changes to the compiler. If we decide to expand to ` is_const(expr) ` in the
178
+ future, we may still do so as the changes proposed in this RFC are
179
+ compatible with such future changes.
180
+
156
181
The impact of not doing this change is to not enable generically sized arrays to
157
- be ` const ` .
182
+ be ` const ` as well as encouraging the use of ` mem::uninitialized ` .
158
183
159
184
# Unresolved questions
160
185
[ unresolved ] : #unresolved-questions
0 commit comments