@@ -9,7 +9,7 @@ use rustc_middle::{
99 } ,
1010 ty:: { self , ParamEnv , TyCtxt } ,
1111} ;
12- use rustc_span:: { def_id:: DefId , Span , DUMMY_SP } ;
12+ use rustc_span:: def_id:: DefId ;
1313
1414pub struct Validator {
1515 /// Describes at which point in the pipeline this validation is happening.
@@ -33,18 +33,25 @@ struct TypeChecker<'a, 'tcx> {
3333}
3434
3535impl < ' a , ' tcx > TypeChecker < ' a , ' tcx > {
36- fn fail ( & self , span : Span , msg : impl AsRef < str > ) {
36+ fn fail ( & self , location : Location , msg : impl AsRef < str > ) {
37+ let span = self . body . source_info ( location) . span ;
3738 // We use `delay_span_bug` as we might see broken MIR when other errors have already
3839 // occurred.
3940 self . tcx . sess . diagnostic ( ) . delay_span_bug (
4041 span,
41- & format ! ( "broken MIR in {:?} ({}): {}" , self . def_id, self . when, msg. as_ref( ) ) ,
42+ & format ! (
43+ "broken MIR in {:?} ({}) at {:?}:\n {}" ,
44+ self . def_id,
45+ self . when,
46+ location,
47+ msg. as_ref( )
48+ ) ,
4249 ) ;
4350 }
4451
45- fn check_bb ( & self , span : Span , bb : BasicBlock ) {
52+ fn check_bb ( & self , location : Location , bb : BasicBlock ) {
4653 if self . body . basic_blocks ( ) . get ( bb) . is_none ( ) {
47- self . fail ( span , format ! ( "encountered jump to invalid basic block {:?}" , bb) )
54+ self . fail ( location , format ! ( "encountered jump to invalid basic block {:?}" , bb) )
4855 }
4956 }
5057}
@@ -57,7 +64,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
5764 let span = self . body . source_info ( location) . span ;
5865
5966 if !ty. is_copy_modulo_regions ( self . tcx , self . param_env , span) {
60- self . fail ( span , format ! ( "`Operand::Copy` with non-`Copy` type {}" , ty) ) ;
67+ self . fail ( location , format ! ( "`Operand::Copy` with non-`Copy` type {}" , ty) ) ;
6168 }
6269 }
6370
@@ -72,11 +79,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
7279 Rvalue :: Use ( Operand :: Copy ( src) | Operand :: Move ( src) ) => {
7380 if dest == src {
7481 self . fail (
75- DUMMY_SP ,
76- format ! (
77- "encountered `Assign` statement with overlapping memory at {:?}" ,
78- location
79- ) ,
82+ location,
83+ "encountered `Assign` statement with overlapping memory" ,
8084 ) ;
8185 }
8286 }
@@ -85,15 +89,15 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
8589 }
8690 }
8791
88- fn visit_terminator ( & mut self , terminator : & Terminator < ' tcx > , _location : Location ) {
92+ fn visit_terminator ( & mut self , terminator : & Terminator < ' tcx > , location : Location ) {
8993 match & terminator. kind {
9094 TerminatorKind :: Goto { target } => {
91- self . check_bb ( terminator . source_info . span , * target) ;
95+ self . check_bb ( location , * target) ;
9296 }
9397 TerminatorKind :: SwitchInt { targets, values, .. } => {
9498 if targets. len ( ) != values. len ( ) + 1 {
9599 self . fail (
96- terminator . source_info . span ,
100+ location ,
97101 format ! (
98102 "encountered `SwitchInt` terminator with {} values, but {} targets (should be values+1)" ,
99103 values. len( ) ,
@@ -102,72 +106,72 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
102106 ) ;
103107 }
104108 for target in targets {
105- self . check_bb ( terminator . source_info . span , * target) ;
109+ self . check_bb ( location , * target) ;
106110 }
107111 }
108112 TerminatorKind :: Drop { target, unwind, .. } => {
109- self . check_bb ( terminator . source_info . span , * target) ;
113+ self . check_bb ( location , * target) ;
110114 if let Some ( unwind) = unwind {
111- self . check_bb ( terminator . source_info . span , * unwind) ;
115+ self . check_bb ( location , * unwind) ;
112116 }
113117 }
114118 TerminatorKind :: DropAndReplace { target, unwind, .. } => {
115- self . check_bb ( terminator . source_info . span , * target) ;
119+ self . check_bb ( location , * target) ;
116120 if let Some ( unwind) = unwind {
117- self . check_bb ( terminator . source_info . span , * unwind) ;
121+ self . check_bb ( location , * unwind) ;
118122 }
119123 }
120124 TerminatorKind :: Call { func, destination, cleanup, .. } => {
121125 let func_ty = func. ty ( & self . body . local_decls , self . tcx ) ;
122126 match func_ty. kind {
123127 ty:: FnPtr ( ..) | ty:: FnDef ( ..) => { }
124128 _ => self . fail (
125- terminator . source_info . span ,
129+ location ,
126130 format ! ( "encountered non-callable type {} in `Call` terminator" , func_ty) ,
127131 ) ,
128132 }
129133 if let Some ( ( _, target) ) = destination {
130- self . check_bb ( terminator . source_info . span , * target) ;
134+ self . check_bb ( location , * target) ;
131135 }
132136 if let Some ( cleanup) = cleanup {
133- self . check_bb ( terminator . source_info . span , * cleanup) ;
137+ self . check_bb ( location , * cleanup) ;
134138 }
135139 }
136140 TerminatorKind :: Assert { cond, target, cleanup, .. } => {
137141 let cond_ty = cond. ty ( & self . body . local_decls , self . tcx ) ;
138142 if cond_ty != self . tcx . types . bool {
139143 self . fail (
140- terminator . source_info . span ,
144+ location ,
141145 format ! (
142146 "encountered non-boolean condition of type {} in `Assert` terminator" ,
143147 cond_ty
144148 ) ,
145149 ) ;
146150 }
147- self . check_bb ( terminator . source_info . span , * target) ;
151+ self . check_bb ( location , * target) ;
148152 if let Some ( cleanup) = cleanup {
149- self . check_bb ( terminator . source_info . span , * cleanup) ;
153+ self . check_bb ( location , * cleanup) ;
150154 }
151155 }
152156 TerminatorKind :: Yield { resume, drop, .. } => {
153- self . check_bb ( terminator . source_info . span , * resume) ;
157+ self . check_bb ( location , * resume) ;
154158 if let Some ( drop) = drop {
155- self . check_bb ( terminator . source_info . span , * drop) ;
159+ self . check_bb ( location , * drop) ;
156160 }
157161 }
158162 TerminatorKind :: FalseEdges { real_target, imaginary_target } => {
159- self . check_bb ( terminator . source_info . span , * real_target) ;
160- self . check_bb ( terminator . source_info . span , * imaginary_target) ;
163+ self . check_bb ( location , * real_target) ;
164+ self . check_bb ( location , * imaginary_target) ;
161165 }
162166 TerminatorKind :: FalseUnwind { real_target, unwind } => {
163- self . check_bb ( terminator . source_info . span , * real_target) ;
167+ self . check_bb ( location , * real_target) ;
164168 if let Some ( unwind) = unwind {
165- self . check_bb ( terminator . source_info . span , * unwind) ;
169+ self . check_bb ( location , * unwind) ;
166170 }
167171 }
168172 TerminatorKind :: InlineAsm { destination, .. } => {
169173 if let Some ( destination) = destination {
170- self . check_bb ( terminator . source_info . span , * destination) ;
174+ self . check_bb ( location , * destination) ;
171175 }
172176 }
173177 // Nothing to validate for these.
0 commit comments