@@ -18,11 +18,7 @@ use std::borrow::Cow;
18
18
19
19
type McfResult = Result < ( ) , ( Span , Cow < ' static , str > ) > ;
20
20
21
- pub fn is_min_const_fn < ' a , ' tcx > (
22
- tcx : TyCtxt < ' tcx > ,
23
- body : & ' a Body < ' tcx > ,
24
- msrv : Option < RustcVersion > ,
25
- ) -> McfResult {
21
+ pub fn is_min_const_fn < ' a , ' tcx > ( tcx : TyCtxt < ' tcx > , body : & ' a Body < ' tcx > , msrv : Option < RustcVersion > ) -> McfResult {
26
22
let def_id = body. source . def_id ( ) ;
27
23
let mut current = def_id;
28
24
loop {
@@ -37,18 +33,10 @@ pub fn is_min_const_fn<'a, 'tcx>(
37
33
| ty:: PredicateKind :: ConstEquate ( ..)
38
34
| ty:: PredicateKind :: Trait ( ..)
39
35
| ty:: PredicateKind :: TypeWellFormedFromEnv ( ..) => continue ,
40
- ty:: PredicateKind :: ObjectSafe ( _) => {
41
- panic ! ( "object safe predicate on function: {:#?}" , predicate)
42
- }
43
- ty:: PredicateKind :: ClosureKind ( ..) => {
44
- panic ! ( "closure kind predicate on function: {:#?}" , predicate)
45
- }
46
- ty:: PredicateKind :: Subtype ( _) => {
47
- panic ! ( "subtype predicate on function: {:#?}" , predicate)
48
- }
49
- ty:: PredicateKind :: Coerce ( _) => {
50
- panic ! ( "coerce predicate on function: {:#?}" , predicate)
51
- }
36
+ ty:: PredicateKind :: ObjectSafe ( _) => panic ! ( "object safe predicate on function: {:#?}" , predicate) ,
37
+ ty:: PredicateKind :: ClosureKind ( ..) => panic ! ( "closure kind predicate on function: {:#?}" , predicate) ,
38
+ ty:: PredicateKind :: Subtype ( _) => panic ! ( "subtype predicate on function: {:#?}" , predicate) ,
39
+ ty:: PredicateKind :: Coerce ( _) => panic ! ( "coerce predicate on function: {:#?}" , predicate) ,
52
40
}
53
41
}
54
42
match predicates. parent {
@@ -89,23 +77,22 @@ fn check_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) -> McfResult {
89
77
match ty. kind ( ) {
90
78
ty:: Ref ( _, _, hir:: Mutability :: Mut ) => {
91
79
return Err ( ( span, "mutable references in const fn are unstable" . into ( ) ) ) ;
92
- }
80
+ } ,
93
81
ty:: Opaque ( ..) => return Err ( ( span, "`impl Trait` in const fn is unstable" . into ( ) ) ) ,
94
82
ty:: FnPtr ( ..) => {
95
83
return Err ( ( span, "function pointers in const fn are unstable" . into ( ) ) ) ;
96
- }
84
+ } ,
97
85
ty:: Dynamic ( preds, _, _) => {
98
86
for pred in preds. iter ( ) {
99
87
match pred. skip_binder ( ) {
100
- ty:: ExistentialPredicate :: AutoTrait ( _)
101
- | ty:: ExistentialPredicate :: Projection ( _) => {
88
+ ty:: ExistentialPredicate :: AutoTrait ( _) | ty:: ExistentialPredicate :: Projection ( _) => {
102
89
return Err ( (
103
90
span,
104
91
"trait bounds other than `Sized` \
105
92
on const fn parameters are unstable"
106
93
. into ( ) ,
107
94
) ) ;
108
- }
95
+ } ,
109
96
ty:: ExistentialPredicate :: Trait ( trait_ref) => {
110
97
if Some ( trait_ref. def_id ) != tcx. lang_items ( ) . sized_trait ( ) {
111
98
return Err ( (
@@ -115,11 +102,11 @@ fn check_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) -> McfResult {
115
102
. into ( ) ,
116
103
) ) ;
117
104
}
118
- }
105
+ } ,
119
106
}
120
107
}
121
- }
122
- _ => { }
108
+ } ,
109
+ _ => { } ,
123
110
}
124
111
}
125
112
Ok ( ( ) )
@@ -133,13 +120,10 @@ fn check_rvalue<'tcx>(
133
120
span : Span ,
134
121
) -> McfResult {
135
122
match rvalue {
136
- Rvalue :: ThreadLocalRef ( _) => {
137
- Err ( ( span, "cannot access thread local storage in const fn" . into ( ) ) )
138
- }
139
- Rvalue :: Len ( place)
140
- | Rvalue :: Discriminant ( place)
141
- | Rvalue :: Ref ( _, _, place)
142
- | Rvalue :: AddressOf ( _, place) => check_place ( tcx, * place, span, body) ,
123
+ Rvalue :: ThreadLocalRef ( _) => Err ( ( span, "cannot access thread local storage in const fn" . into ( ) ) ) ,
124
+ Rvalue :: Len ( place) | Rvalue :: Discriminant ( place) | Rvalue :: Ref ( _, _, place) | Rvalue :: AddressOf ( _, place) => {
125
+ check_place ( tcx, * place, span, body)
126
+ } ,
143
127
Rvalue :: CopyForDeref ( place) => check_place ( tcx, * place, span, body) ,
144
128
Rvalue :: Repeat ( operand, _)
145
129
| Rvalue :: Use ( operand)
@@ -152,9 +136,7 @@ fn check_rvalue<'tcx>(
152
136
) => check_operand ( tcx, operand, span, body) ,
153
137
Rvalue :: Cast (
154
138
CastKind :: Pointer (
155
- PointerCast :: UnsafeFnPointer
156
- | PointerCast :: ClosureFnPointer ( _)
157
- | PointerCast :: ReifyFnPointer ,
139
+ PointerCast :: UnsafeFnPointer | PointerCast :: ClosureFnPointer ( _) | PointerCast :: ReifyFnPointer ,
158
140
) ,
159
141
_,
160
142
_,
@@ -164,10 +146,7 @@ fn check_rvalue<'tcx>(
164
146
deref_ty. ty
165
147
} else {
166
148
// We cannot allow this for now.
167
- return Err ( (
168
- span,
169
- "unsizing casts are only allowed for references right now" . into ( ) ,
170
- ) ) ;
149
+ return Err ( ( span, "unsizing casts are only allowed for references right now" . into ( ) ) ) ;
171
150
} ;
172
151
let unsized_ty = tcx. struct_tail_erasing_lifetimes ( pointee_ty, tcx. param_env ( def_id) ) ;
173
152
if let ty:: Slice ( _) | ty:: Str = unsized_ty. kind ( ) {
@@ -178,14 +157,14 @@ fn check_rvalue<'tcx>(
178
157
// We just can't allow trait objects until we have figured out trait method calls.
179
158
Err ( ( span, "unsizing casts are not allowed in const fn" . into ( ) ) )
180
159
}
181
- }
160
+ } ,
182
161
Rvalue :: Cast ( CastKind :: PointerExposeAddress , _, _) => {
183
162
Err ( ( span, "casting pointers to ints is unstable in const fn" . into ( ) ) )
184
- }
163
+ } ,
185
164
Rvalue :: Cast ( CastKind :: DynStar , _, _) => {
186
165
// FIXME(dyn-star)
187
166
unimplemented ! ( )
188
- }
167
+ } ,
189
168
// binops are fine on integers
190
169
Rvalue :: BinaryOp ( _, box ( lhs, rhs) ) | Rvalue :: CheckedBinaryOp ( _, box ( lhs, rhs) ) => {
191
170
check_operand ( tcx, lhs, span, body) ?;
@@ -194,26 +173,27 @@ fn check_rvalue<'tcx>(
194
173
if ty. is_integral ( ) || ty. is_bool ( ) || ty. is_char ( ) {
195
174
Ok ( ( ) )
196
175
} else {
197
- Err ( ( span, "only int, `bool` and `char` operations are stable in const fn" . into ( ) ) )
176
+ Err ( (
177
+ span,
178
+ "only int, `bool` and `char` operations are stable in const fn" . into ( ) ,
179
+ ) )
198
180
}
199
- }
200
- Rvalue :: NullaryOp ( NullOp :: SizeOf | NullOp :: AlignOf , _) | Rvalue :: ShallowInitBox ( _, _) => {
201
- Ok ( ( ) )
202
- }
181
+ } ,
182
+ Rvalue :: NullaryOp ( NullOp :: SizeOf | NullOp :: AlignOf , _) | Rvalue :: ShallowInitBox ( _, _) => Ok ( ( ) ) ,
203
183
Rvalue :: UnaryOp ( _, operand) => {
204
184
let ty = operand. ty ( body, tcx) ;
205
185
if ty. is_integral ( ) || ty. is_bool ( ) {
206
186
check_operand ( tcx, operand, span, body)
207
187
} else {
208
188
Err ( ( span, "only int and `bool` operations are stable in const fn" . into ( ) ) )
209
189
}
210
- }
190
+ } ,
211
191
Rvalue :: Aggregate ( _, operands) => {
212
192
for operand in operands {
213
193
check_operand ( tcx, operand, span, body) ?;
214
194
}
215
195
Ok ( ( ) )
216
- }
196
+ } ,
217
197
}
218
198
}
219
199
@@ -228,7 +208,7 @@ fn check_statement<'tcx>(
228
208
StatementKind :: Assign ( box ( place, rval) ) => {
229
209
check_place ( tcx, * place, span, body) ?;
230
210
check_rvalue ( tcx, body, def_id, rval, span)
231
- }
211
+ } ,
232
212
233
213
StatementKind :: FakeRead ( box ( _, place) ) => check_place ( tcx, * place, span, body) ,
234
214
// just an assignment
@@ -238,15 +218,13 @@ fn check_statement<'tcx>(
238
218
239
219
StatementKind :: Intrinsic ( box NonDivergingIntrinsic :: Assume ( op) ) => check_operand ( tcx, op, span, body) ,
240
220
241
- StatementKind :: CopyNonOverlapping ( box rustc_middle:: mir:: CopyNonOverlapping {
242
- dst,
243
- src,
244
- count,
245
- } ) => {
221
+ StatementKind :: Intrinsic ( box NonDivergingIntrinsic :: CopyNonOverlapping (
222
+ rustc_middle:: mir:: CopyNonOverlapping { dst, src, count } ,
223
+ ) ) => {
246
224
check_operand ( tcx, dst, span, body) ?;
247
225
check_operand ( tcx, src, span, body) ?;
248
226
check_operand ( tcx, count, span, body)
249
- }
227
+ } ,
250
228
// These are all NOPs
251
229
StatementKind :: StorageLive ( _)
252
230
| StatementKind :: StorageDead ( _)
@@ -257,12 +235,7 @@ fn check_statement<'tcx>(
257
235
}
258
236
}
259
237
260
- fn check_operand < ' tcx > (
261
- tcx : TyCtxt < ' tcx > ,
262
- operand : & Operand < ' tcx > ,
263
- span : Span ,
264
- body : & Body < ' tcx > ,
265
- ) -> McfResult {
238
+ fn check_operand < ' tcx > ( tcx : TyCtxt < ' tcx > , operand : & Operand < ' tcx > , span : Span , body : & Body < ' tcx > ) -> McfResult {
266
239
match operand {
267
240
Operand :: Move ( place) | Operand :: Copy ( place) => check_place ( tcx, * place, span, body) ,
268
241
Operand :: Constant ( c) => match c. check_static_ptr ( tcx) {
@@ -272,12 +245,7 @@ fn check_operand<'tcx>(
272
245
}
273
246
}
274
247
275
- fn check_place < ' tcx > (
276
- tcx : TyCtxt < ' tcx > ,
277
- place : Place < ' tcx > ,
278
- span : Span ,
279
- body : & Body < ' tcx > ,
280
- ) -> McfResult {
248
+ fn check_place < ' tcx > ( tcx : TyCtxt < ' tcx > , place : Place < ' tcx > , span : Span , body : & Body < ' tcx > ) -> McfResult {
281
249
let mut cursor = place. projection . as_ref ( ) ;
282
250
while let [ ref proj_base @ .., elem] = * cursor {
283
251
cursor = proj_base;
@@ -290,12 +258,12 @@ fn check_place<'tcx>(
290
258
return Err ( ( span, "accessing union fields is unstable" . into ( ) ) ) ;
291
259
}
292
260
}
293
- }
261
+ } ,
294
262
ProjectionElem :: ConstantIndex { .. }
295
263
| ProjectionElem :: Downcast ( ..)
296
264
| ProjectionElem :: Subslice { .. }
297
265
| ProjectionElem :: Deref
298
- | ProjectionElem :: Index ( _) => { }
266
+ | ProjectionElem :: Index ( _) => { } ,
299
267
}
300
268
}
301
269
@@ -321,16 +289,18 @@ fn check_terminator<'a, 'tcx>(
321
289
TerminatorKind :: DropAndReplace { place, value, .. } => {
322
290
check_place ( tcx, * place, span, body) ?;
323
291
check_operand ( tcx, value, span, body)
324
- }
292
+ } ,
325
293
326
- TerminatorKind :: SwitchInt { discr, switch_ty : _, targets : _ } => {
327
- check_operand ( tcx, discr, span, body)
328
- }
294
+ TerminatorKind :: SwitchInt {
295
+ discr,
296
+ switch_ty : _,
297
+ targets : _,
298
+ } => check_operand ( tcx, discr, span, body) ,
329
299
330
300
TerminatorKind :: Abort => Err ( ( span, "abort is not stable in const fn" . into ( ) ) ) ,
331
301
TerminatorKind :: GeneratorDrop | TerminatorKind :: Yield { .. } => {
332
302
Err ( ( span, "const fn generators are unstable" . into ( ) ) )
333
- }
303
+ } ,
334
304
335
305
TerminatorKind :: Call {
336
306
func,
@@ -375,15 +345,17 @@ fn check_terminator<'a, 'tcx>(
375
345
} else {
376
346
Err ( ( span, "can only call other const fns within const fn" . into ( ) ) )
377
347
}
378
- }
348
+ } ,
379
349
380
- TerminatorKind :: Assert { cond, expected : _, msg : _, target : _, cleanup : _ } => {
381
- check_operand ( tcx, cond, span, body)
382
- }
350
+ TerminatorKind :: Assert {
351
+ cond,
352
+ expected : _,
353
+ msg : _,
354
+ target : _,
355
+ cleanup : _,
356
+ } => check_operand ( tcx, cond, span, body) ,
383
357
384
- TerminatorKind :: InlineAsm { .. } => {
385
- Err ( ( span, "cannot use inline assembly in const fn" . into ( ) ) )
386
- }
358
+ TerminatorKind :: InlineAsm { .. } => Err ( ( span, "cannot use inline assembly in const fn" . into ( ) ) ) ,
387
359
}
388
360
}
389
361
0 commit comments