diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 3b7d31b1b13bd..ca6638dd34913 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -3201,12 +3201,16 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let expr_ty: Option> = visitor.prop_expr.map(|expr| typeck_results.expr_ty(expr).peel_refs()); - let is_format_arguments_item = if let Some(expr_ty) = expr_ty + let (is_format_arguments_item, is_pin_struct) = if let Some(expr_ty) = + expr_ty && let ty::Adt(adt, _) = expr_ty.kind() { - self.infcx.tcx.is_lang_item(adt.did(), LangItem::FormatArguments) + ( + self.infcx.tcx.is_lang_item(adt.did(), LangItem::FormatArguments), + (self.infcx.tcx.is_lang_item(adt.did(), LangItem::Pin)), + ) } else { - false + (false, false) }; if visitor.found == 0 @@ -3229,8 +3233,22 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { Applicability::MaybeIncorrect, ); } + + let mutability = if matches!(borrow.kind(), BorrowKind::Mut { .. }) + && !is_pin_struct + { + "mut " + } else { + "" + }; + if !is_format_arguments_item { - let addition = format!("let binding = {};\n{}", s, " ".repeat(p)); + let addition = format!( + "let {}binding = {};\n{}", + mutability, + s, + " ".repeat(p) + ); err.multipart_suggestion_verbose( msg, vec![ diff --git a/tests/ui/coroutine/auto-trait-regions.stderr b/tests/ui/coroutine/auto-trait-regions.stderr index a9a0bde2ba019..a3b5a5f006e61 100644 --- a/tests/ui/coroutine/auto-trait-regions.stderr +++ b/tests/ui/coroutine/auto-trait-regions.stderr @@ -11,7 +11,7 @@ LL | assert_foo(a); | help: consider using a `let` binding to create a longer lived value | -LL ~ let binding = true; +LL ~ let mut binding = true; LL ~ let a = A(&mut binding, &mut true, No); | @@ -28,7 +28,7 @@ LL | assert_foo(a); | help: consider using a `let` binding to create a longer lived value | -LL ~ let binding = true; +LL ~ let mut binding = true; LL ~ let a = A(&mut true, &mut binding, No); | diff --git a/tests/ui/nll/sugg-mut-for-binding-issue-137486.rs b/tests/ui/nll/sugg-mut-for-binding-issue-137486.rs new file mode 100644 index 0000000000000..300907c6a0aef --- /dev/null +++ b/tests/ui/nll/sugg-mut-for-binding-issue-137486.rs @@ -0,0 +1,8 @@ +fn main() { + let mut s = String::from("hello"); + let mut ref_s = &mut s; + + ref_s = &mut String::from("world"); //~ ERROR temporary value dropped while borrowed [E0716] + + print!("r1 = {}", ref_s); +} diff --git a/tests/ui/nll/sugg-mut-for-binding-issue-137486.stderr b/tests/ui/nll/sugg-mut-for-binding-issue-137486.stderr new file mode 100644 index 0000000000000..6e7191abb53b7 --- /dev/null +++ b/tests/ui/nll/sugg-mut-for-binding-issue-137486.stderr @@ -0,0 +1,20 @@ +error[E0716]: temporary value dropped while borrowed + --> $DIR/sugg-mut-for-binding-issue-137486.rs:5:18 + | +LL | ref_s = &mut String::from("world"); + | ^^^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement + | | + | creates a temporary value which is freed while still in use +LL | +LL | print!("r1 = {}", ref_s); + | ----- borrow later used here + | +help: consider using a `let` binding to create a longer lived value + | +LL ~ let mut binding = String::from("world"); +LL ~ ref_s = &mut binding; + | + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0716`.