@@ -5,13 +5,12 @@ use rustc_index::bit_set::BitSet;
55use rustc_index:: vec:: IndexVec ;
66use rustc_infer:: traits:: Reveal ;
77use rustc_middle:: mir:: interpret:: Scalar ;
8- use rustc_middle:: mir:: visit:: NonUseContext :: VarDebugInfo ;
9- use rustc_middle:: mir:: visit:: { PlaceContext , Visitor } ;
8+ use rustc_middle:: mir:: visit:: { NonUseContext , PlaceContext , Visitor } ;
109use rustc_middle:: mir:: {
1110 traversal, BasicBlock , BinOp , Body , BorrowKind , CastKind , CopyNonOverlapping , Local , Location ,
1211 MirPass , MirPhase , NonDivergingIntrinsic , Operand , Place , PlaceElem , PlaceRef , ProjectionElem ,
1312 RetagKind , RuntimePhase , Rvalue , SourceScope , Statement , StatementKind , Terminator ,
14- TerminatorKind , UnOp , START_BLOCK ,
13+ TerminatorKind , UnOp , VarDebugInfo , VarDebugInfoContents , START_BLOCK ,
1514} ;
1615use rustc_middle:: ty:: { self , InstanceDef , ParamEnv , Ty , TyCtxt , TypeVisitableExt } ;
1716use rustc_mir_dataflow:: impls:: MaybeStorageLive ;
@@ -419,13 +418,49 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
419418 self . super_projection_elem ( local, proj_base, elem, context, location) ;
420419 }
421420
421+ fn visit_var_debug_info ( & mut self , debuginfo : & VarDebugInfo < ' tcx > ) {
422+ let check_place = |place : Place < ' _ > | {
423+ if place. projection . iter ( ) . any ( |p| !p. can_use_in_debuginfo ( ) ) {
424+ self . fail (
425+ START_BLOCK . start_location ( ) ,
426+ format ! ( "illegal place {:?} in debuginfo for {:?}" , place, debuginfo. name) ,
427+ ) ;
428+ }
429+ } ;
430+ match debuginfo. value {
431+ VarDebugInfoContents :: Const ( _) => { }
432+ VarDebugInfoContents :: Place ( place) => check_place ( place) ,
433+ VarDebugInfoContents :: Composite { ty, ref fragments } => {
434+ for f in fragments {
435+ check_place ( f. contents ) ;
436+ if ty. is_union ( ) || ty. is_enum ( ) {
437+ self . fail (
438+ START_BLOCK . start_location ( ) ,
439+ format ! ( "invalid type {:?} for composite debuginfo" , ty) ,
440+ ) ;
441+ }
442+ if f. projection . iter ( ) . any ( |p| !matches ! ( p, PlaceElem :: Field ( ..) ) ) {
443+ self . fail (
444+ START_BLOCK . start_location ( ) ,
445+ format ! (
446+ "illegal projection {:?} in debuginfo for {:?}" ,
447+ f. projection, debuginfo. name
448+ ) ,
449+ ) ;
450+ }
451+ }
452+ }
453+ }
454+ self . super_var_debug_info ( debuginfo) ;
455+ }
456+
422457 fn visit_place ( & mut self , place : & Place < ' tcx > , cntxt : PlaceContext , location : Location ) {
423458 // Set off any `bug!`s in the type computation code
424459 let _ = place. ty ( & self . body . local_decls , self . tcx ) ;
425460
426461 if self . mir_phase >= MirPhase :: Runtime ( RuntimePhase :: Initial )
427462 && place. projection . len ( ) > 1
428- && cntxt != PlaceContext :: NonUse ( VarDebugInfo )
463+ && cntxt != PlaceContext :: NonUse ( NonUseContext :: VarDebugInfo )
429464 && place. projection [ 1 ..] . contains ( & ProjectionElem :: Deref )
430465 {
431466 self . fail ( location, format ! ( "{:?}, has deref at the wrong place" , place) ) ;
0 commit comments