@@ -5,13 +5,12 @@ use rustc_index::bit_set::BitSet;
5
5
use rustc_index:: vec:: IndexVec ;
6
6
use rustc_infer:: traits:: Reveal ;
7
7
use 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 } ;
10
9
use rustc_middle:: mir:: {
11
10
traversal, BasicBlock , BinOp , Body , BorrowKind , CastKind , CopyNonOverlapping , Local , Location ,
12
11
MirPass , MirPhase , NonDivergingIntrinsic , Operand , Place , PlaceElem , PlaceRef , ProjectionElem ,
13
12
RetagKind , RuntimePhase , Rvalue , SourceScope , Statement , StatementKind , Terminator ,
14
- TerminatorKind , UnOp , START_BLOCK ,
13
+ TerminatorKind , UnOp , VarDebugInfo , VarDebugInfoContents , START_BLOCK ,
15
14
} ;
16
15
use rustc_middle:: ty:: { self , InstanceDef , ParamEnv , Ty , TyCtxt , TypeVisitableExt } ;
17
16
use rustc_mir_dataflow:: impls:: MaybeStorageLive ;
@@ -419,13 +418,49 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
419
418
self . super_projection_elem ( local, proj_base, elem, context, location) ;
420
419
}
421
420
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
+
422
457
fn visit_place ( & mut self , place : & Place < ' tcx > , cntxt : PlaceContext , location : Location ) {
423
458
// Set off any `bug!`s in the type computation code
424
459
let _ = place. ty ( & self . body . local_decls , self . tcx ) ;
425
460
426
461
if self . mir_phase >= MirPhase :: Runtime ( RuntimePhase :: Initial )
427
462
&& place. projection . len ( ) > 1
428
- && cntxt != PlaceContext :: NonUse ( VarDebugInfo )
463
+ && cntxt != PlaceContext :: NonUse ( NonUseContext :: VarDebugInfo )
429
464
&& place. projection [ 1 ..] . contains ( & ProjectionElem :: Deref )
430
465
{
431
466
self . fail ( location, format ! ( "{:?}, has deref at the wrong place" , place) ) ;
0 commit comments