@@ -11,6 +11,7 @@ use rustc_middle::{
11
11
} ;
12
12
use rustc_span:: def_id:: DefId ;
13
13
14
+ #[ derive( Copy , Clone , Debug ) ]
14
15
enum EdgeKind {
15
16
Unwind ,
16
17
Normal ,
@@ -54,7 +55,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
54
55
) ;
55
56
}
56
57
57
- fn check_bb ( & self , location : Location , bb : BasicBlock , edge_kind : EdgeKind ) {
58
+ fn check_edge ( & self , location : Location , bb : BasicBlock , edge_kind : EdgeKind ) {
58
59
if let Some ( bb) = self . body . basic_blocks ( ) . get ( bb) {
59
60
let src = self . body . basic_blocks ( ) . get ( location. block ) . unwrap ( ) ;
60
61
match ( src. is_cleanup , bb. is_cleanup , edge_kind) {
@@ -68,7 +69,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
68
69
_ => {
69
70
self . fail (
70
71
location,
71
- format ! ( "encountered jump that does not respect unwind invariants {:?}" , bb)
72
+ format ! (
73
+ "{:?} edge to {:?} violates unwind invariants (cleanup {:?} -> {:?})" ,
74
+ edge_kind,
75
+ bb,
76
+ src. is_cleanup,
77
+ bb. is_cleanup,
78
+ )
72
79
)
73
80
}
74
81
}
@@ -114,7 +121,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
114
121
fn visit_terminator ( & mut self , terminator : & Terminator < ' tcx > , location : Location ) {
115
122
match & terminator. kind {
116
123
TerminatorKind :: Goto { target } => {
117
- self . check_bb ( location, * target, EdgeKind :: Normal ) ;
124
+ self . check_edge ( location, * target, EdgeKind :: Normal ) ;
118
125
}
119
126
TerminatorKind :: SwitchInt { targets, values, .. } => {
120
127
if targets. len ( ) != values. len ( ) + 1 {
@@ -128,19 +135,19 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
128
135
) ;
129
136
}
130
137
for target in targets {
131
- self . check_bb ( location, * target, EdgeKind :: Normal ) ;
138
+ self . check_edge ( location, * target, EdgeKind :: Normal ) ;
132
139
}
133
140
}
134
141
TerminatorKind :: Drop { target, unwind, .. } => {
135
- self . check_bb ( location, * target, EdgeKind :: Normal ) ;
142
+ self . check_edge ( location, * target, EdgeKind :: Normal ) ;
136
143
if let Some ( unwind) = unwind {
137
- self . check_bb ( location, * unwind, EdgeKind :: Unwind ) ;
144
+ self . check_edge ( location, * unwind, EdgeKind :: Unwind ) ;
138
145
}
139
146
}
140
147
TerminatorKind :: DropAndReplace { target, unwind, .. } => {
141
- self . check_bb ( location, * target, EdgeKind :: Normal ) ;
148
+ self . check_edge ( location, * target, EdgeKind :: Normal ) ;
142
149
if let Some ( unwind) = unwind {
143
- self . check_bb ( location, * unwind, EdgeKind :: Unwind ) ;
150
+ self . check_edge ( location, * unwind, EdgeKind :: Unwind ) ;
144
151
}
145
152
}
146
153
TerminatorKind :: Call { func, destination, cleanup, .. } => {
@@ -153,10 +160,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
153
160
) ,
154
161
}
155
162
if let Some ( ( _, target) ) = destination {
156
- self . check_bb ( location, * target, EdgeKind :: Normal ) ;
163
+ self . check_edge ( location, * target, EdgeKind :: Normal ) ;
157
164
}
158
165
if let Some ( cleanup) = cleanup {
159
- self . check_bb ( location, * cleanup, EdgeKind :: Unwind ) ;
166
+ self . check_edge ( location, * cleanup, EdgeKind :: Unwind ) ;
160
167
}
161
168
}
162
169
TerminatorKind :: Assert { cond, target, cleanup, .. } => {
@@ -170,30 +177,30 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
170
177
) ,
171
178
) ;
172
179
}
173
- self . check_bb ( location, * target, EdgeKind :: Normal ) ;
180
+ self . check_edge ( location, * target, EdgeKind :: Normal ) ;
174
181
if let Some ( cleanup) = cleanup {
175
- self . check_bb ( location, * cleanup, EdgeKind :: Unwind ) ;
182
+ self . check_edge ( location, * cleanup, EdgeKind :: Unwind ) ;
176
183
}
177
184
}
178
185
TerminatorKind :: Yield { resume, drop, .. } => {
179
- self . check_bb ( location, * resume, EdgeKind :: Normal ) ;
186
+ self . check_edge ( location, * resume, EdgeKind :: Normal ) ;
180
187
if let Some ( drop) = drop {
181
- self . check_bb ( location, * drop, EdgeKind :: Normal ) ;
188
+ self . check_edge ( location, * drop, EdgeKind :: Normal ) ;
182
189
}
183
190
}
184
191
TerminatorKind :: FalseEdge { real_target, imaginary_target } => {
185
- self . check_bb ( location, * real_target, EdgeKind :: Normal ) ;
186
- self . check_bb ( location, * imaginary_target, EdgeKind :: Normal ) ;
192
+ self . check_edge ( location, * real_target, EdgeKind :: Normal ) ;
193
+ self . check_edge ( location, * imaginary_target, EdgeKind :: Normal ) ;
187
194
}
188
195
TerminatorKind :: FalseUnwind { real_target, unwind } => {
189
- self . check_bb ( location, * real_target, EdgeKind :: Normal ) ;
196
+ self . check_edge ( location, * real_target, EdgeKind :: Normal ) ;
190
197
if let Some ( unwind) = unwind {
191
- self . check_bb ( location, * unwind, EdgeKind :: Unwind ) ;
198
+ self . check_edge ( location, * unwind, EdgeKind :: Unwind ) ;
192
199
}
193
200
}
194
201
TerminatorKind :: InlineAsm { destination, .. } => {
195
202
if let Some ( destination) = destination {
196
- self . check_bb ( location, * destination, EdgeKind :: Normal ) ;
203
+ self . check_edge ( location, * destination, EdgeKind :: Normal ) ;
197
204
}
198
205
}
199
206
// Nothing to validate for these.
0 commit comments