@@ -136,10 +136,10 @@ fn check_rvalue(
136
136
) -> McfResult {
137
137
match rvalue {
138
138
Rvalue :: Repeat ( operand, _) | Rvalue :: Use ( operand) => {
139
- check_operand ( tcx , mir , operand, span)
139
+ check_operand ( operand, span)
140
140
}
141
141
Rvalue :: Len ( place) | Rvalue :: Discriminant ( place) | Rvalue :: Ref ( _, _, place) => {
142
- check_place ( tcx , mir , place, span)
142
+ check_place ( place, span)
143
143
}
144
144
Rvalue :: Cast ( CastKind :: Misc , operand, cast_ty) => {
145
145
use rustc:: ty:: cast:: CastTy ;
@@ -153,11 +153,11 @@ fn check_rvalue(
153
153
( CastTy :: RPtr ( _) , CastTy :: Float ) => bug ! ( ) ,
154
154
( CastTy :: RPtr ( _) , CastTy :: Int ( _) ) => bug ! ( ) ,
155
155
( CastTy :: Ptr ( _) , CastTy :: RPtr ( _) ) => bug ! ( ) ,
156
- _ => check_operand ( tcx , mir , operand, span) ,
156
+ _ => check_operand ( operand, span) ,
157
157
}
158
158
}
159
159
Rvalue :: Cast ( CastKind :: Pointer ( PointerCast :: MutToConstPointer ) , operand, _) => {
160
- check_operand ( tcx , mir , operand, span)
160
+ check_operand ( operand, span)
161
161
}
162
162
Rvalue :: Cast ( CastKind :: Pointer ( PointerCast :: UnsafeFnPointer ) , _, _) |
163
163
Rvalue :: Cast ( CastKind :: Pointer ( PointerCast :: ClosureFnPointer ( _) ) , _, _) |
@@ -171,8 +171,8 @@ fn check_rvalue(
171
171
) ) ,
172
172
// binops are fine on integers
173
173
Rvalue :: BinaryOp ( _, lhs, rhs) | Rvalue :: CheckedBinaryOp ( _, lhs, rhs) => {
174
- check_operand ( tcx , mir , lhs, span) ?;
175
- check_operand ( tcx , mir , rhs, span) ?;
174
+ check_operand ( lhs, span) ?;
175
+ check_operand ( rhs, span) ?;
176
176
let ty = lhs. ty ( mir, tcx) ;
177
177
if ty. is_integral ( ) || ty. is_bool ( ) || ty. is_char ( ) {
178
178
Ok ( ( ) )
@@ -191,7 +191,7 @@ fn check_rvalue(
191
191
Rvalue :: UnaryOp ( _, operand) => {
192
192
let ty = operand. ty ( mir, tcx) ;
193
193
if ty. is_integral ( ) || ty. is_bool ( ) {
194
- check_operand ( tcx , mir , operand, span)
194
+ check_operand ( operand, span)
195
195
} else {
196
196
Err ( (
197
197
span,
@@ -201,7 +201,7 @@ fn check_rvalue(
201
201
}
202
202
Rvalue :: Aggregate ( _, operands) => {
203
203
for operand in operands {
204
- check_operand ( tcx , mir , operand, span) ?;
204
+ check_operand ( operand, span) ?;
205
205
}
206
206
Ok ( ( ) )
207
207
}
@@ -216,11 +216,11 @@ fn check_statement(
216
216
let span = statement. source_info . span ;
217
217
match & statement. kind {
218
218
StatementKind :: Assign ( place, rval) => {
219
- check_place ( tcx , mir , place, span) ?;
219
+ check_place ( place, span) ?;
220
220
check_rvalue ( tcx, mir, rval, span)
221
221
}
222
222
223
- StatementKind :: FakeRead ( _, place) => check_place ( tcx , mir , place, span) ,
223
+ StatementKind :: FakeRead ( _, place) => check_place ( place, span) ,
224
224
225
225
// just an assignment
226
226
StatementKind :: SetDiscriminant { .. } => Ok ( ( ) ) ,
@@ -239,43 +239,40 @@ fn check_statement(
239
239
}
240
240
241
241
fn check_operand (
242
- tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
243
- mir : & ' a Mir < ' tcx > ,
244
242
operand : & Operand < ' tcx > ,
245
243
span : Span ,
246
244
) -> McfResult {
247
245
match operand {
248
246
Operand :: Move ( place) | Operand :: Copy ( place) => {
249
- check_place ( tcx , mir , place, span)
247
+ check_place ( place, span)
250
248
}
251
249
Operand :: Constant ( _) => Ok ( ( ) ) ,
252
250
}
253
251
}
254
252
255
- fn check_place (
256
- tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
257
- mir : & ' a Mir < ' tcx > ,
258
- place : & Place < ' tcx > ,
259
- span : Span ,
260
- ) -> McfResult {
261
- match place {
262
- Place :: Base ( PlaceBase :: Local ( _) ) => Ok ( ( ) ) ,
263
- // promoteds are always fine, they are essentially constants
264
- Place :: Base ( PlaceBase :: Static ( box Static { kind : StaticKind :: Promoted ( _) , .. } ) ) => Ok ( ( ) ) ,
265
- Place :: Base ( PlaceBase :: Static ( box Static { kind : StaticKind :: Static ( _) , .. } ) ) =>
266
- Err ( ( span, "cannot access `static` items in const fn" . into ( ) ) ) ,
267
- Place :: Projection ( proj) => {
253
+ fn check_place ( place : & Place < ' tcx > , span : Span ) -> McfResult {
254
+ place. iterate ( |place_base, place_projection| {
255
+ for proj in place_projection {
268
256
match proj. elem {
269
- | ProjectionElem :: ConstantIndex { .. } | ProjectionElem :: Subslice { .. }
270
- | ProjectionElem :: Deref | ProjectionElem :: Field ( ..) | ProjectionElem :: Index ( _) => {
271
- check_place ( tcx, mir, & proj. base , span)
272
- }
273
- | ProjectionElem :: Downcast ( ..) => {
274
- Err ( ( span, "`match` or `if let` in `const fn` is unstable" . into ( ) ) )
257
+ ProjectionElem :: Downcast ( ..) => {
258
+ return Err ( ( span, "`match` or `if let` in `const fn` is unstable" . into ( ) ) ) ;
275
259
}
260
+ ProjectionElem :: ConstantIndex { .. }
261
+ | ProjectionElem :: Subslice { .. }
262
+ | ProjectionElem :: Deref
263
+ | ProjectionElem :: Field ( ..)
264
+ | ProjectionElem :: Index ( _) => { }
276
265
}
277
266
}
278
- }
267
+
268
+ match place_base {
269
+ PlaceBase :: Static ( box Static { kind : StaticKind :: Static ( _) , .. } ) => {
270
+ Err ( ( span, "cannot access `static` items in const fn" . into ( ) ) )
271
+ }
272
+ PlaceBase :: Local ( _)
273
+ | PlaceBase :: Static ( box Static { kind : StaticKind :: Promoted ( _) , .. } ) => Ok ( ( ) ) ,
274
+ }
275
+ } )
279
276
}
280
277
281
278
fn check_terminator (
@@ -290,11 +287,11 @@ fn check_terminator(
290
287
| TerminatorKind :: Resume => Ok ( ( ) ) ,
291
288
292
289
TerminatorKind :: Drop { location, .. } => {
293
- check_place ( tcx , mir , location, span)
290
+ check_place ( location, span)
294
291
}
295
292
TerminatorKind :: DropAndReplace { location, value, .. } => {
296
- check_place ( tcx , mir , location, span) ?;
297
- check_operand ( tcx , mir , value, span)
293
+ check_place ( location, span) ?;
294
+ check_operand ( value, span)
298
295
} ,
299
296
300
297
TerminatorKind :: FalseEdges { .. } | TerminatorKind :: SwitchInt { .. } => Err ( (
@@ -346,10 +343,10 @@ fn check_terminator(
346
343
) ) ,
347
344
}
348
345
349
- check_operand ( tcx , mir , func, span) ?;
346
+ check_operand ( func, span) ?;
350
347
351
348
for arg in args {
352
- check_operand ( tcx , mir , arg, span) ?;
349
+ check_operand ( arg, span) ?;
353
350
}
354
351
Ok ( ( ) )
355
352
} else {
@@ -363,7 +360,7 @@ fn check_terminator(
363
360
msg : _,
364
361
target : _,
365
362
cleanup : _,
366
- } => check_operand ( tcx , mir , cond, span) ,
363
+ } => check_operand ( cond, span) ,
367
364
368
365
TerminatorKind :: FalseUnwind { .. } => {
369
366
Err ( ( span, "loops are not allowed in const fn" . into ( ) ) )
0 commit comments