@@ -3,7 +3,7 @@ use rustc_hir::def_id::DefId;
3
3
use rustc_middle:: mir:: * ;
4
4
use rustc_middle:: ty:: subst:: GenericArgKind ;
5
5
use rustc_middle:: ty:: { self , adjustment:: PointerCast , Ty , TyCtxt } ;
6
- use rustc_span:: symbol:: { sym} ;
6
+ use rustc_span:: symbol:: sym;
7
7
use rustc_span:: Span ;
8
8
use rustc_target:: spec:: abi:: Abi :: RustIntrinsic ;
9
9
use std:: borrow:: Cow ;
@@ -23,15 +23,9 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId, body: &'a Body<'tcx>) -
23
23
| ty:: PredicateAtom :: ConstEvaluatable ( ..)
24
24
| ty:: PredicateAtom :: ConstEquate ( ..)
25
25
| ty:: PredicateAtom :: TypeWellFormedFromEnv ( ..) => continue ,
26
- ty:: PredicateAtom :: ObjectSafe ( _) => {
27
- panic ! ( "object safe predicate on function: {:#?}" , predicate)
28
- }
29
- ty:: PredicateAtom :: ClosureKind ( ..) => {
30
- panic ! ( "closure kind predicate on function: {:#?}" , predicate)
31
- }
32
- ty:: PredicateAtom :: Subtype ( _) => {
33
- panic ! ( "subtype predicate on function: {:#?}" , predicate)
34
- }
26
+ ty:: PredicateAtom :: ObjectSafe ( _) => panic ! ( "object safe predicate on function: {:#?}" , predicate) ,
27
+ ty:: PredicateAtom :: ClosureKind ( ..) => panic ! ( "closure kind predicate on function: {:#?}" , predicate) ,
28
+ ty:: PredicateAtom :: Subtype ( _) => panic ! ( "subtype predicate on function: {:#?}" , predicate) ,
35
29
ty:: PredicateAtom :: Trait ( pred, _) => {
36
30
if Some ( pred. def_id ( ) ) == tcx. lang_items ( ) . sized_trait ( ) {
37
31
continue ;
@@ -47,12 +41,12 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId, body: &'a Body<'tcx>) -
47
41
on const fn parameters are unstable"
48
42
. into ( ) ,
49
43
) ) ;
50
- }
44
+ } ,
51
45
// other kinds of bounds are either tautologies
52
46
// or cause errors in other passes
53
47
_ => continue ,
54
48
}
55
- }
49
+ } ,
56
50
}
57
51
}
58
52
match predicates. parent {
@@ -92,24 +86,23 @@ fn check_ty(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) -> McfResult {
92
86
93
87
match ty. kind ( ) {
94
88
ty:: Ref ( _, _, hir:: Mutability :: Mut ) => {
95
- return Err ( ( span, "mutable references in const fn are unstable" . into ( ) ) ) ;
96
- }
89
+ return Err ( ( span, "mutable references in const fn are unstable" . into ( ) ) ) ;
90
+ } ,
97
91
ty:: Opaque ( ..) => return Err ( ( span, "`impl Trait` in const fn is unstable" . into ( ) ) ) ,
98
92
ty:: FnPtr ( ..) => {
99
- return Err ( ( span, "function pointers in const fn are unstable" . into ( ) ) ) ;
100
- }
93
+ return Err ( ( span, "function pointers in const fn are unstable" . into ( ) ) ) ;
94
+ } ,
101
95
ty:: Dynamic ( preds, _) => {
102
96
for pred in preds. iter ( ) {
103
97
match pred. skip_binder ( ) {
104
- ty:: ExistentialPredicate :: AutoTrait ( _)
105
- | ty:: ExistentialPredicate :: Projection ( _) => {
98
+ ty:: ExistentialPredicate :: AutoTrait ( _) | ty:: ExistentialPredicate :: Projection ( _) => {
106
99
return Err ( (
107
100
span,
108
101
"trait bounds other than `Sized` \
109
102
on const fn parameters are unstable"
110
103
. into ( ) ,
111
104
) ) ;
112
- }
105
+ } ,
113
106
ty:: ExistentialPredicate :: Trait ( trait_ref) => {
114
107
if Some ( trait_ref. def_id ) != tcx. lang_items ( ) . sized_trait ( ) {
115
108
return Err ( (
@@ -119,55 +112,40 @@ fn check_ty(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) -> McfResult {
119
112
. into ( ) ,
120
113
) ) ;
121
114
}
122
- }
115
+ } ,
123
116
}
124
117
}
125
- }
126
- _ => { }
118
+ } ,
119
+ _ => { } ,
127
120
}
128
121
}
129
122
Ok ( ( ) )
130
123
}
131
124
132
- fn check_rvalue (
133
- tcx : TyCtxt < ' tcx > ,
134
- body : & Body < ' tcx > ,
135
- def_id : DefId ,
136
- rvalue : & Rvalue < ' tcx > ,
137
- span : Span ,
138
- ) -> McfResult {
125
+ fn check_rvalue ( tcx : TyCtxt < ' tcx > , body : & Body < ' tcx > , def_id : DefId , rvalue : & Rvalue < ' tcx > , span : Span ) -> McfResult {
139
126
match rvalue {
140
- Rvalue :: ThreadLocalRef ( _) => {
141
- Err ( ( span, "cannot access thread local storage in const fn" . into ( ) ) )
142
- }
143
- Rvalue :: Repeat ( operand, _) | Rvalue :: Use ( operand) => {
144
- check_operand ( tcx, operand, span, body)
145
- }
146
- Rvalue :: Len ( place)
147
- | Rvalue :: Discriminant ( place)
148
- | Rvalue :: Ref ( _, _, place)
149
- | Rvalue :: AddressOf ( _, place) => check_place ( tcx, * place, span, body) ,
127
+ Rvalue :: ThreadLocalRef ( _) => Err ( ( span, "cannot access thread local storage in const fn" . into ( ) ) ) ,
128
+ Rvalue :: Repeat ( operand, _) | Rvalue :: Use ( operand) => check_operand ( tcx, operand, span, body) ,
129
+ Rvalue :: Len ( place) | Rvalue :: Discriminant ( place) | Rvalue :: Ref ( _, _, place) | Rvalue :: AddressOf ( _, place) => {
130
+ check_place ( tcx, * place, span, body)
131
+ } ,
150
132
Rvalue :: Cast ( CastKind :: Misc , operand, cast_ty) => {
151
133
use rustc_middle:: ty:: cast:: CastTy ;
152
134
let cast_in = CastTy :: from_ty ( operand. ty ( body, tcx) ) . expect ( "bad input type for cast" ) ;
153
135
let cast_out = CastTy :: from_ty ( cast_ty) . expect ( "bad output type for cast" ) ;
154
136
match ( cast_in, cast_out) {
155
137
( CastTy :: Ptr ( _) | CastTy :: FnPtr , CastTy :: Int ( _) ) => {
156
138
Err ( ( span, "casting pointers to ints is unstable in const fn" . into ( ) ) )
157
- }
139
+ } ,
158
140
_ => check_operand ( tcx, operand, span, body) ,
159
141
}
160
- }
161
- Rvalue :: Cast (
162
- CastKind :: Pointer ( PointerCast :: MutToConstPointer | PointerCast :: ArrayToPointer ) ,
163
- operand,
164
- _,
165
- ) => check_operand ( tcx, operand, span, body) ,
142
+ } ,
143
+ Rvalue :: Cast ( CastKind :: Pointer ( PointerCast :: MutToConstPointer | PointerCast :: ArrayToPointer ) , operand, _) => {
144
+ check_operand ( tcx, operand, span, body)
145
+ } ,
166
146
Rvalue :: Cast (
167
147
CastKind :: Pointer (
168
- PointerCast :: UnsafeFnPointer
169
- | PointerCast :: ClosureFnPointer ( _)
170
- | PointerCast :: ReifyFnPointer ,
148
+ PointerCast :: UnsafeFnPointer | PointerCast :: ClosureFnPointer ( _) | PointerCast :: ReifyFnPointer ,
171
149
) ,
172
150
_,
173
151
_,
@@ -177,10 +155,7 @@ fn check_rvalue(
177
155
deref_ty. ty
178
156
} else {
179
157
// We cannot allow this for now.
180
- return Err ( (
181
- span,
182
- "unsizing casts are only allowed for references right now" . into ( ) ,
183
- ) ) ;
158
+ return Err ( ( span, "unsizing casts are only allowed for references right now" . into ( ) ) ) ;
184
159
} ;
185
160
let unsized_ty = tcx. struct_tail_erasing_lifetimes ( pointee_ty, tcx. param_env ( def_id) ) ;
186
161
if let ty:: Slice ( _) | ty:: Str = unsized_ty. kind ( ) {
@@ -191,7 +166,7 @@ fn check_rvalue(
191
166
// We just can't allow trait objects until we have figured out trait method calls.
192
167
Err ( ( span, "unsizing casts are not allowed in const fn" . into ( ) ) )
193
168
}
194
- }
169
+ } ,
195
170
// binops are fine on integers
196
171
Rvalue :: BinaryOp ( _, lhs, rhs) | Rvalue :: CheckedBinaryOp ( _, lhs, rhs) => {
197
172
check_operand ( tcx, lhs, span, body) ?;
@@ -200,53 +175,45 @@ fn check_rvalue(
200
175
if ty. is_integral ( ) || ty. is_bool ( ) || ty. is_char ( ) {
201
176
Ok ( ( ) )
202
177
} else {
203
- Err ( ( span, "only int, `bool` and `char` operations are stable in const fn" . into ( ) ) )
178
+ Err ( (
179
+ span,
180
+ "only int, `bool` and `char` operations are stable in const fn" . into ( ) ,
181
+ ) )
204
182
}
205
- }
183
+ } ,
206
184
Rvalue :: NullaryOp ( NullOp :: SizeOf , _) => Ok ( ( ) ) ,
207
- Rvalue :: NullaryOp ( NullOp :: Box , _) => {
208
- Err ( ( span, "heap allocations are not allowed in const fn" . into ( ) ) )
209
- }
185
+ Rvalue :: NullaryOp ( NullOp :: Box , _) => Err ( ( span, "heap allocations are not allowed in const fn" . into ( ) ) ) ,
210
186
Rvalue :: UnaryOp ( _, operand) => {
211
187
let ty = operand. ty ( body, tcx) ;
212
188
if ty. is_integral ( ) || ty. is_bool ( ) {
213
189
check_operand ( tcx, operand, span, body)
214
190
} else {
215
191
Err ( ( span, "only int and `bool` operations are stable in const fn" . into ( ) ) )
216
192
}
217
- }
193
+ } ,
218
194
Rvalue :: Aggregate ( _, operands) => {
219
195
for operand in operands {
220
196
check_operand ( tcx, operand, span, body) ?;
221
197
}
222
198
Ok ( ( ) )
223
- }
199
+ } ,
224
200
}
225
201
}
226
202
227
- fn check_statement (
228
- tcx : TyCtxt < ' tcx > ,
229
- body : & Body < ' tcx > ,
230
- def_id : DefId ,
231
- statement : & Statement < ' tcx > ,
232
- ) -> McfResult {
203
+ fn check_statement ( tcx : TyCtxt < ' tcx > , body : & Body < ' tcx > , def_id : DefId , statement : & Statement < ' tcx > ) -> McfResult {
233
204
let span = statement. source_info . span ;
234
205
match & statement. kind {
235
206
StatementKind :: Assign ( box ( place, rval) ) => {
236
- check_place ( tcx, * place, span, body) ?;
207
+ check_place ( tcx, * place, span, body) ?;
237
208
check_rvalue ( tcx, body, def_id, rval, span)
238
- }
209
+ } ,
239
210
240
211
StatementKind :: FakeRead ( _, place) => check_place ( tcx, * * place, span, body) ,
241
212
242
213
// just an assignment
243
- StatementKind :: SetDiscriminant { place, .. } => {
244
- check_place ( tcx, * * place, span, body)
245
- }
214
+ StatementKind :: SetDiscriminant { place, .. } => check_place ( tcx, * * place, span, body) ,
246
215
247
- StatementKind :: LlvmInlineAsm { .. } => {
248
- Err ( ( span, "cannot use inline assembly in const fn" . into ( ) ) )
249
- }
216
+ StatementKind :: LlvmInlineAsm { .. } => Err ( ( span, "cannot use inline assembly in const fn" . into ( ) ) ) ,
250
217
251
218
// These are all NOPs
252
219
StatementKind :: StorageLive ( _)
@@ -258,12 +225,7 @@ fn check_statement(
258
225
}
259
226
}
260
227
261
- fn check_operand (
262
- tcx : TyCtxt < ' tcx > ,
263
- operand : & Operand < ' tcx > ,
264
- span : Span ,
265
- body : & Body < ' tcx > ,
266
- ) -> McfResult {
228
+ fn check_operand ( tcx : TyCtxt < ' tcx > , operand : & Operand < ' tcx > , span : Span , body : & Body < ' tcx > ) -> McfResult {
267
229
match operand {
268
230
Operand :: Move ( place) | Operand :: Copy ( place) => check_place ( tcx, * place, span, body) ,
269
231
Operand :: Constant ( c) => match c. check_static_ptr ( tcx) {
@@ -273,12 +235,7 @@ fn check_operand(
273
235
}
274
236
}
275
237
276
- fn check_place (
277
- tcx : TyCtxt < ' tcx > ,
278
- place : Place < ' tcx > ,
279
- span : Span ,
280
- body : & Body < ' tcx > ,
281
- ) -> McfResult {
238
+ fn check_place ( tcx : TyCtxt < ' tcx > , place : Place < ' tcx > , span : Span , body : & Body < ' tcx > ) -> McfResult {
282
239
let mut cursor = place. projection . as_ref ( ) ;
283
240
while let & [ ref proj_base @ .., elem] = cursor {
284
241
cursor = proj_base;
@@ -288,26 +245,22 @@ fn check_place(
288
245
if let Some ( def) = base_ty. ty_adt_def ( ) {
289
246
// No union field accesses in `const fn`
290
247
if def. is_union ( ) {
291
- return Err ( ( span, "accessing union fields is unstable" . into ( ) ) ) ;
248
+ return Err ( ( span, "accessing union fields is unstable" . into ( ) ) ) ;
292
249
}
293
250
}
294
- }
251
+ } ,
295
252
ProjectionElem :: ConstantIndex { .. }
296
253
| ProjectionElem :: Downcast ( ..)
297
254
| ProjectionElem :: Subslice { .. }
298
255
| ProjectionElem :: Deref
299
- | ProjectionElem :: Index ( _) => { }
256
+ | ProjectionElem :: Index ( _) => { } ,
300
257
}
301
258
}
302
259
303
260
Ok ( ( ) )
304
261
}
305
262
306
- fn check_terminator (
307
- tcx : TyCtxt < ' tcx > ,
308
- body : & ' a Body < ' tcx > ,
309
- terminator : & Terminator < ' tcx > ,
310
- ) -> McfResult {
263
+ fn check_terminator ( tcx : TyCtxt < ' tcx > , body : & ' a Body < ' tcx > , terminator : & Terminator < ' tcx > ) -> McfResult {
311
264
let span = terminator. source_info . span ;
312
265
match & terminator. kind {
313
266
TerminatorKind :: FalseEdge { .. }
@@ -317,20 +270,23 @@ fn check_terminator(
317
270
| TerminatorKind :: Resume
318
271
| TerminatorKind :: Unreachable => Ok ( ( ) ) ,
319
272
320
- TerminatorKind :: Drop { place, .. } => check_place ( tcx, * place, span, body) ,
273
+ TerminatorKind :: Drop { place, .. } => check_place ( tcx, * place, span, body) ,
321
274
TerminatorKind :: DropAndReplace { place, value, .. } => {
322
- check_place ( tcx, * place, span, body) ?;
275
+ check_place ( tcx, * place, span, body) ?;
323
276
check_operand ( tcx, value, span, body)
324
- }
277
+ } ,
325
278
326
- TerminatorKind :: SwitchInt { discr, switch_ty : _, values : _, targets : _ } => {
327
- check_operand ( tcx, discr, span, body)
328
- }
279
+ TerminatorKind :: SwitchInt {
280
+ discr,
281
+ switch_ty : _,
282
+ values : _,
283
+ targets : _,
284
+ } => check_operand ( tcx, discr, span, body) ,
329
285
330
286
TerminatorKind :: Abort => Err ( ( span, "abort is not stable in const fn" . into ( ) ) ) ,
331
287
TerminatorKind :: GeneratorDrop | TerminatorKind :: Yield { .. } => {
332
288
Err ( ( span, "const fn generators are unstable" . into ( ) ) )
333
- }
289
+ } ,
334
290
335
291
TerminatorKind :: Call {
336
292
func,
@@ -342,8 +298,7 @@ fn check_terminator(
342
298
} => {
343
299
let fn_ty = func. ty ( body, tcx) ;
344
300
if let ty:: FnDef ( fn_def_id, _) = * fn_ty. kind ( ) {
345
- if !rustc_mir:: const_eval:: is_min_const_fn ( tcx, fn_def_id)
346
- {
301
+ if !rustc_mir:: const_eval:: is_min_const_fn ( tcx, fn_def_id) {
347
302
return Err ( (
348
303
span,
349
304
format ! (
@@ -359,9 +314,7 @@ fn check_terminator(
359
314
// within const fns. `transmute` is allowed in all other const contexts.
360
315
// This won't really scale to more intrinsics or functions. Let's allow const
361
316
// transmutes in const fn before we add more hacks to this.
362
- if tcx. fn_sig ( fn_def_id) . abi ( ) == RustIntrinsic
363
- && tcx. item_name ( fn_def_id) == sym:: transmute
364
- {
317
+ if tcx. fn_sig ( fn_def_id) . abi ( ) == RustIntrinsic && tcx. item_name ( fn_def_id) == sym:: transmute {
365
318
return Err ( (
366
319
span,
367
320
"can only call `transmute` from const items, not `const fn`" . into ( ) ,
@@ -377,14 +330,16 @@ fn check_terminator(
377
330
} else {
378
331
Err ( ( span, "can only call other const fns within const fn" . into ( ) ) )
379
332
}
380
- }
333
+ } ,
381
334
382
- TerminatorKind :: Assert { cond, expected : _, msg : _, target : _, cleanup : _ } => {
383
- check_operand ( tcx, cond, span, body)
384
- }
335
+ TerminatorKind :: Assert {
336
+ cond,
337
+ expected : _,
338
+ msg : _,
339
+ target : _,
340
+ cleanup : _,
341
+ } => check_operand ( tcx, cond, span, body) ,
385
342
386
- TerminatorKind :: InlineAsm { .. } => {
387
- Err ( ( span, "cannot use inline assembly in const fn" . into ( ) ) )
388
- }
343
+ TerminatorKind :: InlineAsm { .. } => Err ( ( span, "cannot use inline assembly in const fn" . into ( ) ) ) ,
389
344
}
390
345
}
0 commit comments