@@ -329,32 +329,36 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
329
329
for init_idx in inits {
330
330
let init = & self . move_data . inits [ * init_idx] ;
331
331
let span = init. span ( & self . body ) ;
332
- spans. push ( span) ;
332
+ if !span. is_dummy ( ) {
333
+ spans. push ( span) ;
334
+ }
333
335
}
334
336
335
337
let ( binding, name, desc) =
336
338
match self . describe_place_with_options ( used_place, IncludingDowncast ( true ) ) {
337
339
Some ( name) => ( format ! ( "`{name}`" ) , format ! ( "`{name}`" ) , format ! ( "`{name}` " ) ) ,
338
340
None => ( "value" . to_string ( ) , "the variable" . to_string ( ) , String :: new ( ) ) ,
339
341
} ;
340
- let initialized = if let InitializationRequiringAction :: PartialAssignment = desired_action {
341
- // The same error is emitted for bindings that are *sometimes* initialized and the ones
342
- // that are *partially* initialized by assigning to a field of an uninitialized
343
- // binding. We differentiate between them for more accurate wording here.
344
- "fully initialized"
345
- } else if spans. iter ( ) . filter ( |i| !i. contains ( span) ) . count ( ) == 0 {
346
- // We filter above to avoid misleading wording in cases like:
347
- // ```
348
- // let x;
349
- // x += 1;
350
- // ```
351
- "initialized"
352
- } else {
353
- "initialized in all conditions"
354
- } ;
342
+ let isnt_initialized =
343
+ if let InitializationRequiringAction :: PartialAssignment = desired_action {
344
+ // The same error is emitted for bindings that are *sometimes* initialized and the ones
345
+ // that are *partially* initialized by assigning to a field of an uninitialized
346
+ // binding. We differentiate between them for more accurate wording here.
347
+ "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
+ // ```
355
+ "isn't initialized"
356
+ } else {
357
+ "is possibly-uninitialized"
358
+ } ;
355
359
let used = desired_action. as_general_verb_in_past_tense ( ) ;
356
360
let mut err =
357
- struct_span_err ! ( self , span, E0381 , "{used} binding {desc}isn't {initialized }" ) ;
361
+ struct_span_err ! ( self , span, E0381 , "{used} binding {desc}{isnt_initialized }" ) ;
358
362
use_spans. var_span_label_path_only (
359
363
& mut err,
360
364
format ! ( "{} occurs due to use{}" , desired_action. as_noun( ) , use_spans. describe( ) ) ,
@@ -366,7 +370,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
366
370
default value and mutate it, or use `std::mem::MaybeUninit`",
367
371
) ;
368
372
}
369
- err. span_label ( span, format ! ( "{binding} {used} here but it isn't {initialized }" ) ) ;
373
+ err. span_label ( span, format ! ( "{binding} {used} here but it {isnt_initialized }" ) ) ;
370
374
371
375
// We use the statements were the binding was initialized, and inspect the HIR to look
372
376
// for the branching codepaths that aren't covered, to point at them.
@@ -2561,13 +2565,16 @@ impl<'b, 'v> Visitor<'v> for ConditionVisitor<'b> {
2561
2565
v. visit_expr ( body) ;
2562
2566
if v. 1 {
2563
2567
self . errors . push ( (
2564
- ex . span . to ( cond. span ) ,
2568
+ cond. span ,
2565
2569
format ! (
2566
- "this `if` expression might be missing an `else` arm that initializes \
2567
- {}",
2570
+ "if this `if` condition is `false`, {} is not initialized" ,
2568
2571
self . name,
2569
2572
) ,
2570
2573
) ) ;
2574
+ self . errors . push ( (
2575
+ ex. span . shrink_to_hi ( ) ,
2576
+ format ! ( "an `else` arm might be missing here, initializing {}" , self . name) ,
2577
+ ) ) ;
2571
2578
}
2572
2579
}
2573
2580
hir:: ExprKind :: If ( cond, body, Some ( other) ) => {
@@ -2584,16 +2591,17 @@ impl<'b, 'v> Visitor<'v> for ConditionVisitor<'b> {
2584
2591
self . errors . push ( (
2585
2592
cond. span ,
2586
2593
format ! (
2587
- "{} is uninitialized if this condition isn't met and the \
2588
- `while` loop runs 0 times ",
2594
+ "if this condition isn't met and the `while` loop runs 0 \
2595
+ times, {} is not initialized ",
2589
2596
self . name
2590
2597
) ,
2591
2598
) ) ;
2592
2599
} else {
2593
2600
self . errors . push ( (
2594
2601
body. span . shrink_to_hi ( ) . until ( other. span ) ,
2595
2602
format ! (
2596
- "{} is uninitialized if this `else` arm is executed" ,
2603
+ "if the `if` condition is `false` and this `else` arm is \
2604
+ executed, {} is not initialized",
2597
2605
self . name
2598
2606
) ,
2599
2607
) ) ;
@@ -2602,7 +2610,10 @@ impl<'b, 'v> Visitor<'v> for ConditionVisitor<'b> {
2602
2610
( false , true ) => {
2603
2611
self . errors . push ( (
2604
2612
cond. span ,
2605
- format ! ( "{} is uninitialized if this condition is met" , self . name) ,
2613
+ format ! (
2614
+ "if this condition is `true`, {} is not initialized" ,
2615
+ self . name
2616
+ ) ,
2606
2617
) ) ;
2607
2618
}
2608
2619
}
@@ -2625,24 +2636,24 @@ impl<'b, 'v> Visitor<'v> for ConditionVisitor<'b> {
2625
2636
self . errors . push ( (
2626
2637
e. span ,
2627
2638
format ! (
2628
- "{} is uninitialized if the `for` loop runs 0 times" ,
2639
+ "if the `for` loop runs 0 times, {} is not initialized " ,
2629
2640
self . name
2630
2641
) ,
2631
2642
) ) ;
2632
2643
} else if let Some ( guard) = & arm. guard {
2633
2644
self . errors . push ( (
2634
2645
arm. pat . span . to ( guard. body ( ) . span ) ,
2635
2646
format ! (
2636
- "{} is uninitialized if this pattern and condition are \
2637
- matched ",
2647
+ "if this pattern and condition are matched, {} is not \
2648
+ initialized ",
2638
2649
self . name
2639
2650
) ,
2640
2651
) ) ;
2641
2652
} else {
2642
2653
self . errors . push ( (
2643
2654
arm. pat . span ,
2644
2655
format ! (
2645
- "{} is uninitialized if this pattern is matched" ,
2656
+ "if this pattern is matched, {} is not initialized " ,
2646
2657
self . name
2647
2658
) ,
2648
2659
) ) ;
0 commit comments