Skip to content

Commit 3f6925d

Browse files
committed
Suggest mut when possbile for temporary value dropped while borrowed
1 parent 7e19eef commit 3f6925d

File tree

4 files changed

+52
-6
lines changed

4 files changed

+52
-6
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3201,12 +3201,16 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
32013201
let expr_ty: Option<Ty<'_>> =
32023202
visitor.prop_expr.map(|expr| typeck_results.expr_ty(expr).peel_refs());
32033203

3204-
let is_format_arguments_item = if let Some(expr_ty) = expr_ty
3204+
let (is_format_arguments_item, is_pin_struct) = if let Some(expr_ty) =
3205+
expr_ty
32053206
&& let ty::Adt(adt, _) = expr_ty.kind()
32063207
{
3207-
self.infcx.tcx.is_lang_item(adt.did(), LangItem::FormatArguments)
3208+
(
3209+
self.infcx.tcx.is_lang_item(adt.did(), LangItem::FormatArguments),
3210+
(self.infcx.tcx.is_lang_item(adt.did(), LangItem::Pin)),
3211+
)
32083212
} else {
3209-
false
3213+
(false, false)
32103214
};
32113215

32123216
if visitor.found == 0
@@ -3229,8 +3233,22 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
32293233
Applicability::MaybeIncorrect,
32303234
);
32313235
}
3236+
3237+
let mutability = if matches!(borrow.kind(), BorrowKind::Mut { .. })
3238+
&& !is_pin_struct
3239+
{
3240+
"mut "
3241+
} else {
3242+
""
3243+
};
3244+
32323245
if !is_format_arguments_item {
3233-
let addition = format!("let binding = {};\n{}", s, " ".repeat(p));
3246+
let addition = format!(
3247+
"let {}binding = {};\n{}",
3248+
mutability,
3249+
s,
3250+
" ".repeat(p)
3251+
);
32343252
err.multipart_suggestion_verbose(
32353253
msg,
32363254
vec![

tests/ui/coroutine/auto-trait-regions.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ LL | assert_foo(a);
1111
|
1212
help: consider using a `let` binding to create a longer lived value
1313
|
14-
LL ~ let binding = true;
14+
LL ~ let mut binding = true;
1515
LL ~ let a = A(&mut binding, &mut true, No);
1616
|
1717

@@ -28,7 +28,7 @@ LL | assert_foo(a);
2828
|
2929
help: consider using a `let` binding to create a longer lived value
3030
|
31-
LL ~ let binding = true;
31+
LL ~ let mut binding = true;
3232
LL ~ let a = A(&mut true, &mut binding, No);
3333
|
3434

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
fn main() {
2+
let mut s = String::from("hello");
3+
let mut ref_s = &mut s;
4+
5+
ref_s = &mut String::from("world"); //~ ERROR temporary value dropped while borrowed [E0716]
6+
7+
print!("r1 = {}", ref_s);
8+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0716]: temporary value dropped while borrowed
2+
--> $DIR/sugg-mut-for-binding-issue-137486.rs:5:18
3+
|
4+
LL | ref_s = &mut String::from("world");
5+
| ^^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement
6+
| |
7+
| creates a temporary value which is freed while still in use
8+
LL |
9+
LL | print!("r1 = {}", ref_s);
10+
| ----- borrow later used here
11+
|
12+
help: consider using a `let` binding to create a longer lived value
13+
|
14+
LL ~ let mut binding = String::from("world");
15+
LL ~ ref_s = &mut binding;
16+
|
17+
18+
error: aborting due to 1 previous error
19+
20+
For more information about this error, try `rustc --explain E0716`.

0 commit comments

Comments
 (0)