@@ -136,10 +136,10 @@ fn check_rvalue(
136136) -> McfResult {
137137 match rvalue {
138138 Rvalue :: Repeat ( operand, _) | Rvalue :: Use ( operand) => {
139- check_operand ( tcx , mir , operand, span)
139+ check_operand ( operand, span)
140140 }
141141 Rvalue :: Len ( place) | Rvalue :: Discriminant ( place) | Rvalue :: Ref ( _, _, place) => {
142- check_place ( tcx , mir , place, span)
142+ check_place ( place, span)
143143 }
144144 Rvalue :: Cast ( CastKind :: Misc , operand, cast_ty) => {
145145 use rustc:: ty:: cast:: CastTy ;
@@ -153,11 +153,11 @@ fn check_rvalue(
153153 ( CastTy :: RPtr ( _) , CastTy :: Float ) => bug ! ( ) ,
154154 ( CastTy :: RPtr ( _) , CastTy :: Int ( _) ) => bug ! ( ) ,
155155 ( CastTy :: Ptr ( _) , CastTy :: RPtr ( _) ) => bug ! ( ) ,
156- _ => check_operand ( tcx , mir , operand, span) ,
156+ _ => check_operand ( operand, span) ,
157157 }
158158 }
159159 Rvalue :: Cast ( CastKind :: Pointer ( PointerCast :: MutToConstPointer ) , operand, _) => {
160- check_operand ( tcx , mir , operand, span)
160+ check_operand ( operand, span)
161161 }
162162 Rvalue :: Cast ( CastKind :: Pointer ( PointerCast :: UnsafeFnPointer ) , _, _) |
163163 Rvalue :: Cast ( CastKind :: Pointer ( PointerCast :: ClosureFnPointer ( _) ) , _, _) |
@@ -171,8 +171,8 @@ fn check_rvalue(
171171 ) ) ,
172172 // binops are fine on integers
173173 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) ?;
176176 let ty = lhs. ty ( mir, tcx) ;
177177 if ty. is_integral ( ) || ty. is_bool ( ) || ty. is_char ( ) {
178178 Ok ( ( ) )
@@ -191,7 +191,7 @@ fn check_rvalue(
191191 Rvalue :: UnaryOp ( _, operand) => {
192192 let ty = operand. ty ( mir, tcx) ;
193193 if ty. is_integral ( ) || ty. is_bool ( ) {
194- check_operand ( tcx , mir , operand, span)
194+ check_operand ( operand, span)
195195 } else {
196196 Err ( (
197197 span,
@@ -201,7 +201,7 @@ fn check_rvalue(
201201 }
202202 Rvalue :: Aggregate ( _, operands) => {
203203 for operand in operands {
204- check_operand ( tcx , mir , operand, span) ?;
204+ check_operand ( operand, span) ?;
205205 }
206206 Ok ( ( ) )
207207 }
@@ -216,11 +216,11 @@ fn check_statement(
216216 let span = statement. source_info . span ;
217217 match & statement. kind {
218218 StatementKind :: Assign ( place, rval) => {
219- check_place ( tcx , mir , place, span) ?;
219+ check_place ( place, span) ?;
220220 check_rvalue ( tcx, mir, rval, span)
221221 }
222222
223- StatementKind :: FakeRead ( _, place) => check_place ( tcx , mir , place, span) ,
223+ StatementKind :: FakeRead ( _, place) => check_place ( place, span) ,
224224
225225 // just an assignment
226226 StatementKind :: SetDiscriminant { .. } => Ok ( ( ) ) ,
@@ -239,43 +239,40 @@ fn check_statement(
239239}
240240
241241fn check_operand (
242- tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
243- mir : & ' a Mir < ' tcx > ,
244242 operand : & Operand < ' tcx > ,
245243 span : Span ,
246244) -> McfResult {
247245 match operand {
248246 Operand :: Move ( place) | Operand :: Copy ( place) => {
249- check_place ( tcx , mir , place, span)
247+ check_place ( place, span)
250248 }
251249 Operand :: Constant ( _) => Ok ( ( ) ) ,
252250 }
253251}
254252
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 {
268256 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 ( ) ) ) ;
275259 }
260+ ProjectionElem :: ConstantIndex { .. }
261+ | ProjectionElem :: Subslice { .. }
262+ | ProjectionElem :: Deref
263+ | ProjectionElem :: Field ( ..)
264+ | ProjectionElem :: Index ( _) => { }
276265 }
277266 }
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+ } )
279276}
280277
281278fn check_terminator (
@@ -290,11 +287,11 @@ fn check_terminator(
290287 | TerminatorKind :: Resume => Ok ( ( ) ) ,
291288
292289 TerminatorKind :: Drop { location, .. } => {
293- check_place ( tcx , mir , location, span)
290+ check_place ( location, span)
294291 }
295292 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)
298295 } ,
299296
300297 TerminatorKind :: FalseEdges { .. } | TerminatorKind :: SwitchInt { .. } => Err ( (
@@ -346,10 +343,10 @@ fn check_terminator(
346343 ) ) ,
347344 }
348345
349- check_operand ( tcx , mir , func, span) ?;
346+ check_operand ( func, span) ?;
350347
351348 for arg in args {
352- check_operand ( tcx , mir , arg, span) ?;
349+ check_operand ( arg, span) ?;
353350 }
354351 Ok ( ( ) )
355352 } else {
@@ -363,7 +360,7 @@ fn check_terminator(
363360 msg : _,
364361 target : _,
365362 cleanup : _,
366- } => check_operand ( tcx , mir , cond, span) ,
363+ } => check_operand ( cond, span) ,
367364
368365 TerminatorKind :: FalseUnwind { .. } => {
369366 Err ( ( span, "loops are not allowed in const fn" . into ( ) ) )
0 commit comments