Skip to content

Commit

Permalink
Unrolled build for rust-lang#136032
Browse files Browse the repository at this point in the history
Rollup merge of rust-lang#136032 - estebank:issue-136028, r=SparrowLii

Account for mutable borrow in argument suggestion

```
error: value assigned to `object` is never read
  --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:21:5
   |
LL |     object = &mut object2;
   |     ^^^^^^
   |
help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding
   |
LL ~ fn change_object3(object: &mut Object) {
LL |
LL |     let object2 = Object;
LL ~     *object = object2;
   |
```
instead of
```
error: value assigned to `object` is never read
  --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:21:5
   |
LL |     object = &mut object2;
   |     ^^^^^^
   |
help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding
   |
LL ~ fn change_object3(object: &mut mut Object) {
LL |
LL |     let object2 = Object;
LL ~     *object = object2;
   |
```

Fix rust-lang#136028.
  • Loading branch information
rust-timer authored Jan 26, 2025
2 parents 2f0ad2a + 1dfc437 commit ad1fd25
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 57 deletions.
38 changes: 19 additions & 19 deletions compiler/rustc_hir_typeck/src/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -851,32 +851,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&& let hir::PatKind::Binding(hir::BindingMode::MUT, _hir_id, ident, _) = pat.kind

// Look for the type corresponding to the argument pattern we have in the argument list.
&& let Some(ty_sugg) = fn_decl
&& let Some(ty_ref) = fn_decl
.inputs
.iter()
.filter_map(|ty| {
if ty.span == *ty_span
&& let hir::TyKind::Ref(lt, x) = ty.kind
{
// `&'name Ty` -> `&'name mut Ty` or `&Ty` -> `&mut Ty`
Some((
x.ty.span.shrink_to_lo(),
format!(
"{}mut ",
if lt.ident.span.lo() == lt.ident.span.hi() { "" } else { " " }
),
))
} else {
None
}
.filter_map(|ty| match ty.kind {
hir::TyKind::Ref(lt, mut_ty) if ty.span == *ty_span => Some((lt, mut_ty)),
_ => None,
})
.next()
{
let sugg = vec![
ty_sugg,
let mut sugg = if ty_ref.1.mutbl.is_mut() {
// Leave `&'name mut Ty` and `&mut Ty` as they are (#136028).
vec![]
} else {
// `&'name Ty` -> `&'name mut Ty` or `&Ty` -> `&mut Ty`
vec![(
ty_ref.1.ty.span.shrink_to_lo(),
format!(
"{}mut ",
if ty_ref.0.ident.span.lo() == ty_ref.0.ident.span.hi() { "" } else { " " },
),
)]
};
sugg.extend([
(pat.span.until(ident.span), String::new()),
(lhs.span.shrink_to_lo(), "*".to_string()),
];
]);
// We suggest changing the argument from `mut ident: &Ty` to `ident: &'_ mut Ty` and the
// assignment from `ident = val;` to `*ident = val;`.
err.multipart_suggestion_verbose(
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1791,7 +1791,7 @@ pub(crate) struct UnusedAssign {
pub(crate) struct UnusedAssignSuggestion {
pub pre: &'static str,
#[suggestion_part(code = "{pre}mut ")]
pub ty_span: Span,
pub ty_span: Option<Span>,
#[suggestion_part(code = "")]
pub ty_ref_span: Span,
#[suggestion_part(code = "*")]
Expand Down
16 changes: 10 additions & 6 deletions compiler/rustc_passes/src/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1620,24 +1620,28 @@ impl<'tcx> Liveness<'_, 'tcx> {
&& let item = self.ir.tcx.hir_owner_node(item_id)
&& let Some(fn_decl) = item.fn_decl()
&& let hir::PatKind::Binding(hir::BindingMode::MUT, _hir_id, ident, _) = pat.kind
&& let Some((ty_span, pre)) = fn_decl
&& let Some((lt, mut_ty)) = fn_decl
.inputs
.iter()
.filter_map(|ty| {
if ty.span == *ty_span
&& let hir::TyKind::Ref(lt, mut_ty) = ty.kind
{
// `&'name Ty` -> `&'name mut Ty` or `&Ty` -> `&mut Ty`
Some((
mut_ty.ty.span.shrink_to_lo(),
if lt.ident.span.lo() == lt.ident.span.hi() { "" } else { " " },
))
Some((lt, mut_ty))
} else {
None
}
})
.next()
{
let ty_span = if mut_ty.mutbl.is_mut() {
// Leave `&'name mut Ty` and `&mut Ty` as they are (#136028).
None
} else {
// `&'name Ty` -> `&'name mut Ty` or `&Ty` -> `&mut Ty`
Some(mut_ty.ty.span.shrink_to_lo())
};
let pre = if lt.ident.span.lo() == lt.ident.span.hi() { "" } else { " " };
Some(errors::UnusedAssignSuggestion {
ty_span,
pre,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,32 @@
//@ run-rustfix
#![deny(unused_assignments, unused_variables)]
#![allow(unused_mut)]
struct Object;

fn change_object(object: &mut Object) { //~ HELP you might have meant to mutate
let object2 = Object;
*object = object2; //~ ERROR mismatched types
let object2 = Object;
*object = object2; //~ ERROR mismatched types
}

fn change_object2(object: &mut Object) { //~ ERROR variable `object` is assigned to, but never used
//~^ HELP you might have meant to mutate
let object2 = Object;
*object = object2;
//~^ ERROR `object2` does not live long enough
//~| ERROR value assigned to `object` is never read
}

fn change_object3(object: &mut Object) { //~ ERROR variable `object` is assigned to, but never used
//~^ HELP you might have meant to mutate
let object2 = Object;
let mut object2 = Object; //~ HELP consider changing this to be mutable
*object = object2;
//~^ ERROR `object2` does not live long enough
//~^ ERROR cannot borrow `object2` as mutable
//~| ERROR value assigned to `object` is never read
}

fn main() {
let mut object = Object;
change_object(&mut object);
change_object2(&mut object);
change_object3(&mut object);
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,32 @@
//@ run-rustfix
#![deny(unused_assignments, unused_variables)]
#![allow(unused_mut)]
struct Object;

fn change_object(mut object: &Object) { //~ HELP you might have meant to mutate
let object2 = Object;
object = object2; //~ ERROR mismatched types
let object2 = Object;
object = object2; //~ ERROR mismatched types
}

fn change_object2(mut object: &Object) { //~ ERROR variable `object` is assigned to, but never used
//~^ HELP you might have meant to mutate
let object2 = Object;
object = &object2;
//~^ ERROR `object2` does not live long enough
//~| ERROR value assigned to `object` is never read
}

fn change_object3(mut object: &mut Object) { //~ ERROR variable `object` is assigned to, but never used
//~^ HELP you might have meant to mutate
let object2 = Object;
object = &object2;
//~^ ERROR `object2` does not live long enough
let object2 = Object; //~ HELP consider changing this to be mutable
object = &mut object2;
//~^ ERROR cannot borrow `object2` as mutable
//~| ERROR value assigned to `object` is never read
}

fn main() {
let mut object = Object;
change_object(&mut object);
change_object2(&mut object);
change_object3(&mut object);
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
error[E0308]: mismatched types
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:7:14
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:8:13
|
LL | fn change_object(mut object: &Object) {
| ------- expected due to this parameter type
LL | let object2 = Object;
LL | object = object2;
| ^^^^^^^ expected `&Object`, found `Object`
LL | let object2 = Object;
LL | object = object2;
| ^^^^^^^ expected `&Object`, found `Object`
|
help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding
|
LL ~ fn change_object(object: &mut Object) {
LL | let object2 = Object;
LL ~ *object = object2;
LL | let object2 = Object;
LL ~ *object = object2;
|

error: value assigned to `object` is never read
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:13:5
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:14:4
|
LL | object = &object2;
| ^^^^^^
LL | object = &object2;
| ^^^^^^
|
note: the lint level is defined here
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:2:9
Expand All @@ -29,12 +29,12 @@ help: you might have meant to mutate the pointed at value being passed in, inste
|
LL ~ fn change_object2(object: &mut Object) {
LL |
LL | let object2 = Object;
LL ~ *object = object2;
LL | let object2 = Object;
LL ~ *object = object2;
|

error: variable `object` is assigned to, but never used
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:10:23
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:11:23
|
LL | fn change_object2(mut object: &Object) {
| ^^^^^^
Expand All @@ -47,23 +47,56 @@ LL | #![deny(unused_assignments, unused_variables)]
| ^^^^^^^^^^^^^^^^

error[E0597]: `object2` does not live long enough
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:13:14
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:14:13
|
LL | fn change_object2(mut object: &Object) {
| - let's call the lifetime of this reference `'1`
LL |
LL | let object2 = Object;
| ------- binding `object2` declared here
LL | object = &object2;
| ---------^^^^^^^^
| | |
| | borrowed value does not live long enough
| assignment requires that `object2` is borrowed for `'1`
LL | let object2 = Object;
| ------- binding `object2` declared here
LL | object = &object2;
| ---------^^^^^^^^
| | |
| | borrowed value does not live long enough
| assignment requires that `object2` is borrowed for `'1`
...
LL | }
| - `object2` dropped here while still borrowed

error: aborting due to 4 previous errors
error: value assigned to `object` is never read
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:22:5
|
LL | object = &mut object2;
| ^^^^^^
|
help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding
|
LL ~ fn change_object3(object: &mut Object) {
LL |
LL | let object2 = Object;
LL ~ *object = object2;
|

error: variable `object` is assigned to, but never used
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:19:23
|
LL | fn change_object3(mut object: &mut Object) {
| ^^^^^^
|
= note: consider using `_object` instead

error[E0596]: cannot borrow `object2` as mutable, as it is not declared as mutable
--> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:22:14
|
LL | object = &mut object2;
| ^^^^^^^^^^^^ cannot borrow as mutable
|
help: consider changing this to be mutable
|
LL | let mut object2 = Object;
| +++

error: aborting due to 7 previous errors

Some errors have detailed explanations: E0308, E0597.
Some errors have detailed explanations: E0308, E0596, E0597.
For more information about an error, try `rustc --explain E0308`.

0 comments on commit ad1fd25

Please sign in to comment.