Skip to content

Commit f793c0b

Browse files
committedMay 31, 2020
always print MIR Location when validator finds a problem
1 parent 9a4bdbf commit f793c0b

File tree

1 file changed

+36
-32
lines changed

1 file changed

+36
-32
lines changed
 

‎src/librustc_mir/transform/validate.rs

+36-32
Original file line numberDiff line numberDiff line change
@@ -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

1414
pub struct Validator {
1515
/// Describes at which point in the pipeline this validation is happening.
@@ -33,18 +33,25 @@ struct TypeChecker<'a, 'tcx> {
3333
}
3434

3535
impl<'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

Comments
 (0)