@@ -339,23 +339,48 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
339339 Some ( name) => ( format ! ( "`{name}`" ) , format ! ( "`{name}`" ) , format ! ( "`{name}` " ) ) ,
340340 None => ( "value" . to_string ( ) , "the variable" . to_string ( ) , String :: new ( ) ) ,
341341 } ;
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+
342353 let isnt_initialized =
343354 if let InitializationRequiringAction :: PartialAssignment = desired_action {
344355 // The same error is emitted for bindings that are *sometimes* initialized and the ones
345356 // that are *partially* initialized by assigning to a field of an uninitialized
346357 // binding. We differentiate between them for more accurate wording here.
347358 "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+ {
355379 "isn't initialized"
356380 } else {
357381 "is possibly-uninitialized"
358382 } ;
383+
359384 let used = desired_action. as_general_verb_in_past_tense ( ) ;
360385 let mut err =
361386 struct_span_err ! ( self , span, E0381 , "{used} binding {desc}{isnt_initialized}" ) ;
@@ -372,22 +397,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
372397 }
373398 err. span_label ( span, format ! ( "{binding} {used} here but it {isnt_initialized}" ) ) ;
374399
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 ;
391401 for ( sp, label) in visitor. errors {
392402 if sp < span && !sp. overlaps ( span) {
393403 // 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> {
404414 // };
405415 // ```
406416 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+ }
407425 }
408426 }
409427 err. span_label ( decl_span, "binding declared here but left uninitialized" ) ;
0 commit comments