Skip to content

Commit 89682a5

Browse files
downgrade borrowck suggestion level due to possible span conflict
1 parent e2120a7 commit 89682a5

File tree

4 files changed

+108
-48
lines changed

4 files changed

+108
-48
lines changed

compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs

+29-14
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
128128
&& pat.span.can_be_used_for_suggestions()
129129
&& let Ok(pat) = tcx.sess.source_map().span_to_snippet(pat.span)
130130
{
131-
suggest_rewrite_if_let(expr, &pat, init, conseq, alt, err);
131+
suggest_rewrite_if_let(tcx, expr, &pat, init, conseq, alt, err);
132132
} else if path_span.map_or(true, |path_span| path_span == var_or_use_span) {
133133
// We can use `var_or_use_span` if either `path_span` is not present, or both spans are the same
134134
if borrow_span.map_or(true, |sp| !sp.overlaps(var_or_use_span)) {
@@ -292,7 +292,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
292292
&& pat.span.can_be_used_for_suggestions()
293293
&& let Ok(pat) = tcx.sess.source_map().span_to_snippet(pat.span)
294294
{
295-
suggest_rewrite_if_let(expr, &pat, init, conseq, alt, err);
295+
suggest_rewrite_if_let(tcx, expr, &pat, init, conseq, alt, err);
296296
}
297297
}
298298
}
@@ -428,34 +428,49 @@ impl<'tcx> BorrowExplanation<'tcx> {
428428
}
429429
}
430430

431-
fn suggest_rewrite_if_let<'tcx>(
432-
expr: &hir::Expr<'tcx>,
431+
fn suggest_rewrite_if_let(
432+
tcx: TyCtxt<'_>,
433+
expr: &hir::Expr<'_>,
433434
pat: &str,
434-
init: &hir::Expr<'tcx>,
435-
conseq: &hir::Expr<'tcx>,
436-
alt: Option<&hir::Expr<'tcx>>,
435+
init: &hir::Expr<'_>,
436+
conseq: &hir::Expr<'_>,
437+
alt: Option<&hir::Expr<'_>>,
437438
err: &mut Diag<'_>,
438439
) {
440+
let source_map = tcx.sess.source_map();
439441
err.span_note(
440-
conseq.span.shrink_to_hi(),
441-
"lifetime for temporaries generated in `if let`s have been shorted in Edition 2024",
442+
source_map.end_point(conseq.span),
443+
"lifetimes for temporaries generated in `if let`s have been shortened in Edition 2024 so that they are dropped here instead",
442444
);
443445
if expr.span.can_be_used_for_suggestions() && conseq.span.can_be_used_for_suggestions() {
446+
let needs_block = if let Some(hir::Node::Expr(expr)) =
447+
alt.and_then(|alt| tcx.hir().parent_iter(alt.hir_id).next()).map(|(_, node)| node)
448+
{
449+
matches!(expr.kind, hir::ExprKind::If(..))
450+
} else {
451+
false
452+
};
444453
let mut sugg = vec![
445-
(expr.span.shrink_to_lo().between(init.span), "match ".into()),
454+
(
455+
expr.span.shrink_to_lo().between(init.span),
456+
if needs_block { "{ match ".into() } else { "match ".into() },
457+
),
446458
(conseq.span.shrink_to_lo(), format!(" {{ {pat} => ")),
447459
];
448460
let expr_end = expr.span.shrink_to_hi();
461+
let mut expr_end_code;
449462
if let Some(alt) = alt {
450-
sugg.push((conseq.span.between(alt.span), format!(" _ => ")));
451-
sugg.push((expr_end, "}".into()));
463+
sugg.push((conseq.span.between(alt.span), " _ => ".into()));
464+
expr_end_code = "}".to_string();
452465
} else {
453-
sugg.push((expr_end, " _ => {} }".into()));
466+
expr_end_code = " _ => {} }".into();
454467
}
468+
expr_end_code.push('}');
469+
sugg.push((expr_end, expr_end_code));
455470
err.multipart_suggestion(
456471
"consider rewriting the `if` into `match` which preserves the extended lifetime",
457472
sugg,
458-
Applicability::MachineApplicable,
473+
Applicability::MaybeIncorrect,
459474
);
460475
}
461476
}

tests/ui/drop/if-let-rescope-borrowck-suggestions.fixed

-26
This file was deleted.

tests/ui/drop/if-let-rescope-borrowck-suggestions.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
//@ edition: 2024
22
//@ compile-flags: -Z validate-mir -Zunstable-options
3-
//@ run-rustfix
43

54
#![feature(if_let_rescope)]
65
#![deny(if_let_rescope)]
@@ -22,4 +21,13 @@ fn do_something<T>(_: &T) {}
2221
fn main() {
2322
do_something(if let Some(value) = Droppy.get_ref() { value } else { &0 });
2423
//~^ ERROR: temporary value dropped while borrowed
24+
do_something(if let Some(value) = Droppy.get_ref() {
25+
//~^ ERROR: temporary value dropped while borrowed
26+
value
27+
} else if let Some(value) = Droppy.get_ref() {
28+
//~^ ERROR: temporary value dropped while borrowed
29+
value
30+
} else {
31+
&0
32+
});
2533
}
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,89 @@
11
error[E0716]: temporary value dropped while borrowed
2-
--> $DIR/if-let-rescope-borrowck-suggestions.rs:23:39
2+
--> $DIR/if-let-rescope-borrowck-suggestions.rs:22:39
33
|
44
LL | do_something(if let Some(value) = Droppy.get_ref() { value } else { &0 });
55
| ^^^^^^ - temporary value is freed at the end of this statement
66
| |
77
| creates a temporary value which is freed while still in use
88
|
9-
note: lifetime for temporaries generated in `if let`s have been shorted in Edition 2024
10-
--> $DIR/if-let-rescope-borrowck-suggestions.rs:23:65
9+
note: lifetimes for temporaries generated in `if let`s have been shortened in Edition 2024 so that they are dropped here instead
10+
--> $DIR/if-let-rescope-borrowck-suggestions.rs:22:64
1111
|
1212
LL | do_something(if let Some(value) = Droppy.get_ref() { value } else { &0 });
13-
| ^
13+
| ^
1414
help: consider using a `let` binding to create a longer lived value
1515
|
1616
LL ~ let binding = Droppy;
1717
LL ~ do_something(if let Some(value) = binding.get_ref() { value } else { &0 });
1818
|
1919
help: consider rewriting the `if` into `match` which preserves the extended lifetime
2020
|
21-
LL | do_something(match Droppy.get_ref() { Some(value) => { value } _ => { &0 }});
22-
| ~~~~~ ++++++++++++++++ ~~~~ +
21+
LL | do_something({ match Droppy.get_ref() { Some(value) => { value } _ => { &0 }}});
22+
| ~~~~~~~ ++++++++++++++++ ~~~~ ++
2323

24-
error: aborting due to 1 previous error
24+
error[E0716]: temporary value dropped while borrowed
25+
--> $DIR/if-let-rescope-borrowck-suggestions.rs:24:39
26+
|
27+
LL | do_something(if let Some(value) = Droppy.get_ref() {
28+
| ^^^^^^ creates a temporary value which is freed while still in use
29+
...
30+
LL | } else if let Some(value) = Droppy.get_ref() {
31+
| - temporary value is freed at the end of this statement
32+
|
33+
note: lifetimes for temporaries generated in `if let`s have been shortened in Edition 2024 so that they are dropped here instead
34+
--> $DIR/if-let-rescope-borrowck-suggestions.rs:27:5
35+
|
36+
LL | } else if let Some(value) = Droppy.get_ref() {
37+
| ^
38+
help: consider using a `let` binding to create a longer lived value
39+
|
40+
LL ~ let binding = Droppy;
41+
LL ~ do_something(if let Some(value) = binding.get_ref() {
42+
|
43+
help: consider rewriting the `if` into `match` which preserves the extended lifetime
44+
|
45+
LL ~ do_something({ match Droppy.get_ref() { Some(value) => {
46+
LL |
47+
LL | value
48+
LL ~ } _ => if let Some(value) = Droppy.get_ref() {
49+
LL |
50+
...
51+
LL | &0
52+
LL ~ }}});
53+
|
54+
55+
error[E0716]: temporary value dropped while borrowed
56+
--> $DIR/if-let-rescope-borrowck-suggestions.rs:27:33
57+
|
58+
LL | } else if let Some(value) = Droppy.get_ref() {
59+
| ^^^^^^ creates a temporary value which is freed while still in use
60+
...
61+
LL | } else {
62+
| - temporary value is freed at the end of this statement
63+
|
64+
note: lifetimes for temporaries generated in `if let`s have been shortened in Edition 2024 so that they are dropped here instead
65+
--> $DIR/if-let-rescope-borrowck-suggestions.rs:30:5
66+
|
67+
LL | } else {
68+
| ^
69+
help: consider using a `let` binding to create a longer lived value
70+
|
71+
LL ~ let binding = Droppy;
72+
LL ~ do_something(if let Some(value) = Droppy.get_ref() {
73+
LL |
74+
LL | value
75+
LL ~ } else if let Some(value) = binding.get_ref() {
76+
|
77+
help: consider rewriting the `if` into `match` which preserves the extended lifetime
78+
|
79+
LL ~ } else { match Droppy.get_ref() { Some(value) => {
80+
LL |
81+
LL | value
82+
LL ~ } _ => {
83+
LL | &0
84+
LL ~ }}});
85+
|
86+
87+
error: aborting due to 3 previous errors
2588

2689
For more information about this error, try `rustc --explain E0716`.

0 commit comments

Comments
 (0)