1
1
//! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations.
2
2
3
- use rustc_errors:: { struct_span_err, Applicability , Diagnostic } ;
3
+ use rustc_errors:: { struct_span_err, Applicability , Diagnostic , ErrorReported } ;
4
4
use rustc_hir:: def_id:: DefId ;
5
5
use rustc_hir:: { self as hir, HirId , LangItem } ;
6
6
use rustc_infer:: infer:: TyCtxtInferExt ;
@@ -123,7 +123,11 @@ impl Qualifs<'mir, 'tcx> {
123
123
has_mut_interior. get ( ) . contains ( local) || self . indirectly_mutable ( ccx, local, location)
124
124
}
125
125
126
- fn in_return_place ( & mut self , ccx : & ' mir ConstCx < ' mir , ' tcx > ) -> ConstQualifs {
126
+ fn in_return_place (
127
+ & mut self ,
128
+ ccx : & ' mir ConstCx < ' mir , ' tcx > ,
129
+ error_occured : Option < ErrorReported > ,
130
+ ) -> ConstQualifs {
127
131
// Find the `Return` terminator if one exists.
128
132
//
129
133
// If no `Return` terminator exists, this MIR is divergent. Just return the conservative
@@ -139,7 +143,7 @@ impl Qualifs<'mir, 'tcx> {
139
143
. map ( |( bb, _) | bb) ;
140
144
141
145
let return_block = match return_block {
142
- None => return qualifs:: in_any_value_of_ty ( ccx, ccx. body . return_ty ( ) ) ,
146
+ None => return qualifs:: in_any_value_of_ty ( ccx, ccx. body . return_ty ( ) , error_occured ) ,
143
147
Some ( bb) => bb,
144
148
} ;
145
149
@@ -170,6 +174,7 @@ impl Qualifs<'mir, 'tcx> {
170
174
needs_drop : self . needs_drop ( ccx, RETURN_PLACE , return_loc) ,
171
175
has_mut_interior : self . has_mut_interior ( ccx, RETURN_PLACE , return_loc) ,
172
176
custom_eq,
177
+ error_occured,
173
178
}
174
179
}
175
180
}
@@ -181,7 +186,7 @@ pub struct Validator<'mir, 'tcx> {
181
186
/// The span of the current statement.
182
187
span : Span ,
183
188
184
- error_emitted : bool ,
189
+ error_emitted : Option < ErrorReported > ,
185
190
secondary_errors : Vec < Diagnostic > ,
186
191
}
187
192
@@ -199,7 +204,7 @@ impl Validator<'mir, 'tcx> {
199
204
span : ccx. body . span ,
200
205
ccx,
201
206
qualifs : Default :: default ( ) ,
202
- error_emitted : false ,
207
+ error_emitted : None ,
203
208
secondary_errors : Vec :: new ( ) ,
204
209
}
205
210
}
@@ -266,7 +271,7 @@ impl Validator<'mir, 'tcx> {
266
271
// If we got through const-checking without emitting any "primary" errors, emit any
267
272
// "secondary" errors if they occurred.
268
273
let secondary_errors = mem:: take ( & mut self . secondary_errors ) ;
269
- if ! self . error_emitted {
274
+ if self . error_emitted . is_none ( ) {
270
275
for error in secondary_errors {
271
276
self . tcx . sess . diagnostic ( ) . emit_diagnostic ( & error) ;
272
277
}
@@ -276,7 +281,7 @@ impl Validator<'mir, 'tcx> {
276
281
}
277
282
278
283
pub fn qualifs_in_return_place ( & mut self ) -> ConstQualifs {
279
- self . qualifs . in_return_place ( self . ccx )
284
+ self . qualifs . in_return_place ( self . ccx , self . error_emitted )
280
285
}
281
286
282
287
/// Emits an error if an expression cannot be evaluated in the current context.
@@ -318,7 +323,7 @@ impl Validator<'mir, 'tcx> {
318
323
319
324
match op. importance ( ) {
320
325
ops:: DiagnosticImportance :: Primary => {
321
- self . error_emitted = true ;
326
+ self . error_emitted = Some ( ErrorReported ) ;
322
327
err. emit ( ) ;
323
328
}
324
329
0 commit comments