@@ -339,23 +339,48 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
339
339
Some ( name) => ( format ! ( "`{name}`" ) , format ! ( "`{name}`" ) , format ! ( "`{name}` " ) ) ,
340
340
None => ( "value" . to_string ( ) , "the variable" . to_string ( ) , String :: new ( ) ) ,
341
341
} ;
342
+
343
+ // We use the statements were the binding was initialized, and inspect the HIR to look
344
+ // for the branching codepaths that aren't covered, to point at them.
345
+ let hir_id = self . mir_hir_id ( ) ;
346
+ let map = self . infcx . tcx . hir ( ) ;
347
+ let body_id = map. body_owned_by ( hir_id) ;
348
+ let body = map. body ( body_id) ;
349
+
350
+ let mut visitor = ConditionVisitor { spans : & spans, name : & name, errors : vec ! [ ] } ;
351
+ visitor. visit_body ( & body) ;
352
+
342
353
let isnt_initialized =
343
354
if let InitializationRequiringAction :: PartialAssignment = desired_action {
344
355
// The same error is emitted for bindings that are *sometimes* initialized and the ones
345
356
// that are *partially* initialized by assigning to a field of an uninitialized
346
357
// binding. We differentiate between them for more accurate wording here.
347
358
"isn't fully initialized"
348
- } else if spans. iter ( ) . filter ( |i| !i. contains ( span) ) . count ( ) == 0 {
349
- // We filter above to avoid misleading wording in cases like the following, where `x`
350
- // has an `init`, but it is in the same place we're looking at:
351
- // ```
352
- // let x;
353
- // x += 1;
354
- // ```
359
+ } else if spans
360
+ . iter ( )
361
+ . filter ( |i| {
362
+ // We filter these to avoid misleading wording in cases like the following,
363
+ // where `x` has an `init`, but it is in the same place we're looking at:
364
+ // ```
365
+ // let x;
366
+ // x += 1;
367
+ // ```
368
+ !i. contains ( span)
369
+ // We filter these to avoid incorrect main message on `match-cfg-fake-edges.rs`
370
+ && !visitor
371
+ . errors
372
+ . iter ( )
373
+ . map ( |( sp, _) | * sp)
374
+ . any ( |sp| span < sp && !sp. contains ( span) )
375
+ } )
376
+ . count ( )
377
+ == 0
378
+ {
355
379
"isn't initialized"
356
380
} else {
357
381
"is possibly-uninitialized"
358
382
} ;
383
+
359
384
let used = desired_action. as_general_verb_in_past_tense ( ) ;
360
385
let mut err =
361
386
struct_span_err ! ( self , span, E0381 , "{used} binding {desc}{isnt_initialized}" ) ;
@@ -372,22 +397,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
372
397
}
373
398
err. span_label ( span, format ! ( "{binding} {used} here but it {isnt_initialized}" ) ) ;
374
399
375
- // We use the statements were the binding was initialized, and inspect the HIR to look
376
- // for the branching codepaths that aren't covered, to point at them.
377
- let hir_id = self . mir_hir_id ( ) ;
378
- let map = self . infcx . tcx . hir ( ) ;
379
- let body_id = map. body_owned_by ( hir_id) ;
380
- let body = map. body ( body_id) ;
381
-
382
- let mut visitor = ConditionVisitor { spans : & spans, name : & name, errors : vec ! [ ] } ;
383
- visitor. visit_body ( & body) ;
384
- if visitor. errors . is_empty ( ) {
385
- for sp in & spans {
386
- if * sp < span && !sp. overlaps ( span) {
387
- err. span_label ( * sp, "binding initialized here in some conditions" ) ;
388
- }
389
- }
390
- }
400
+ let mut shown = false ;
391
401
for ( sp, label) in visitor. errors {
392
402
if sp < span && !sp. overlaps ( span) {
393
403
// When we have a case like `match-cfg-fake-edges.rs`, we don't want to mention
@@ -404,6 +414,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
404
414
// };
405
415
// ```
406
416
err. span_label ( sp, & label) ;
417
+ shown = true ;
418
+ }
419
+ }
420
+ if !shown {
421
+ for sp in & spans {
422
+ if * sp < span && !sp. overlaps ( span) {
423
+ err. span_label ( * sp, "binding initialized here in some conditions" ) ;
424
+ }
407
425
}
408
426
}
409
427
err. span_label ( decl_span, "binding declared here but left uninitialized" ) ;
0 commit comments