Skip to content

Commit

Permalink
Use verbose suggestions for mutability errors
Browse files Browse the repository at this point in the history
  • Loading branch information
estebank committed Dec 29, 2022
1 parent 92c1937 commit b9439eb
Show file tree
Hide file tree
Showing 34 changed files with 338 additions and 181 deletions.
33 changes: 12 additions & 21 deletions compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let local_decl = &self.body.local_decls[local];
assert_eq!(local_decl.mutability, Mutability::Not);

err.span_label(span, format!("cannot {ACT}", ACT = act));
err.span_label(span, format!("cannot {act}"));
err.span_suggestion(
local_decl.source_info.span,
"consider changing this to be mutable",
Expand All @@ -357,7 +357,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {

let captured_place = &self.upvars[upvar_index.index()].place;

err.span_label(span, format!("cannot {ACT}", ACT = act));
err.span_label(span, format!("cannot {act}"));

let upvar_hir_id = captured_place.get_root_variable();

Expand Down Expand Up @@ -397,7 +397,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
.span_to_snippet(span)
.map_or(false, |snippet| snippet.starts_with("&mut ")) =>
{
err.span_label(span, format!("cannot {ACT}", ACT = act));
err.span_label(span, format!("cannot {act}"));
err.span_suggestion(
span,
"try removing `&mut` here",
Expand All @@ -409,7 +409,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
PlaceRef { local, projection: [ProjectionElem::Deref] }
if self.body.local_decls[local].is_ref_for_guard() =>
{
err.span_label(span, format!("cannot {ACT}", ACT = act));
err.span_label(span, format!("cannot {act}"));
err.note(
"variables bound in patterns are immutable until the end of the pattern guard",
);
Expand Down Expand Up @@ -537,7 +537,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
Some((true, err_help_span, suggested_code)) => {
let (is_trait_sig, local_trait) = self.is_error_in_trait(local);
if !is_trait_sig {
err.span_suggestion(
err.span_suggestion_verbose(
err_help_span,
&format!(
"consider changing this to be a mutable {pointer_desc}"
Expand All @@ -546,7 +546,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
Applicability::MachineApplicable,
);
} else if let Some(x) = local_trait {
err.span_suggestion(
err.span_suggestion_verbose(
x,
&format!(
"consider changing that to be a mutable {pointer_desc}"
Expand All @@ -569,24 +569,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
err.span_label(
span,
format!(
"`{NAME}` is a `{SIGIL}` {DESC}, \
so the data it refers to cannot be {ACTED_ON}",
NAME = name,
SIGIL = pointer_sigil,
DESC = pointer_desc,
ACTED_ON = acted_on
"`{name}` is a `{pointer_sigil}` {pointer_desc}, \
so the data it refers to cannot be {acted_on}",
),
);
}
_ => {
err.span_label(
span,
format!(
"cannot {ACT} through `{SIGIL}` {DESC}",
ACT = act,
SIGIL = pointer_sigil,
DESC = pointer_desc
),
format!("cannot {act} through `{pointer_sigil}` {pointer_desc}"),
);
}
}
Expand All @@ -605,13 +596,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
Some(BorrowedContentSource::OverloadedDeref(ty)) => {
err.help(&format!(
"trait `DerefMut` is required to modify through a dereference, \
but it is not implemented for `{ty}`",
but it is not implemented for `{ty}`",
));
}
Some(BorrowedContentSource::OverloadedIndex(ty)) => {
err.help(&format!(
"trait `IndexMut` is required to modify indexed content, \
but it is not implemented for `{ty}`",
but it is not implemented for `{ty}`",
));
self.suggest_map_index_mut_alternatives(ty, &mut err, span);
}
Expand All @@ -620,7 +611,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
}

_ => {
err.span_label(span, format!("cannot {ACT}", ACT = act));
err.span_label(span, format!("cannot {act}"));
}
}

Expand Down
8 changes: 5 additions & 3 deletions src/test/ui/array-slice-vec/slice-mut-2.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
--> $DIR/slice-mut-2.rs:7:18
|
LL | let x: &[isize] = &[1, 2, 3, 4, 5];
| ---------------- help: consider changing this to be a mutable reference: `&mut [1, 2, 3, 4, 5]`
...
LL | let _ = &mut x[2..4];
| ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
help: consider changing this to be a mutable reference
|
LL | let x: &[isize] = &mut [1, 2, 3, 4, 5];
| ~~~~~~~~~~~~~~~~~~~~

error: aborting due to previous error

Expand Down
16 changes: 10 additions & 6 deletions src/test/ui/borrowck/borrow-raw-address-of-deref-mutability.stderr
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
--> $DIR/borrow-raw-address-of-deref-mutability.rs:8:13
|
LL | let x = &0;
| -- help: consider changing this to be a mutable reference: `&mut 0`
LL |
LL | let q = &raw mut *x;
| ^^^^^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
help: consider changing this to be a mutable reference
|
LL | let x = &mut 0;
| ~~~~~~

error[E0596]: cannot borrow `*x` as mutable, as it is behind a `*const` pointer
--> $DIR/borrow-raw-address-of-deref-mutability.rs:14:13
|
LL | let x = &0 as *const i32;
| -- help: consider changing this to be a mutable pointer: `&mut 0`
LL |
LL | let q = &raw mut *x;
| ^^^^^^^^^^^ `x` is a `*const` pointer, so the data it refers to cannot be borrowed as mutable
|
help: consider changing this to be a mutable pointer
|
LL | let x = &mut 0 as *const i32;
| ~~~~~~

error: aborting due to 2 previous errors

Expand Down
23 changes: 15 additions & 8 deletions src/test/ui/borrowck/borrowck-access-permissions.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -25,28 +25,35 @@ LL | let _y1 = &mut *box_x;
error[E0596]: cannot borrow `*ref_x` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-access-permissions.rs:30:19
|
LL | let ref_x = &x;
| -- help: consider changing this to be a mutable reference: `&mut x`
...
LL | let _y1 = &mut *ref_x;
| ^^^^^^^^^^^ `ref_x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
help: consider changing this to be a mutable reference
|
LL | let ref_x = &mut x;
| ~~~~~~

error[E0596]: cannot borrow `*ptr_x` as mutable, as it is behind a `*const` pointer
--> $DIR/borrowck-access-permissions.rs:39:23
|
LL | let ptr_x : *const _ = &x;
| -- help: consider changing this to be a mutable pointer: `&mut x`
...
LL | let _y1 = &mut *ptr_x;
| ^^^^^^^^^^^ `ptr_x` is a `*const` pointer, so the data it refers to cannot be borrowed as mutable
|
help: consider changing this to be a mutable pointer
|
LL | let ptr_x : *const _ = &mut x;
| ~~~~~~

error[E0596]: cannot borrow `*foo_ref.f` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-access-permissions.rs:48:18
|
LL | let foo_ref = &foo;
| ---- help: consider changing this to be a mutable reference: `&mut foo`
LL | let _y = &mut *foo_ref.f;
| ^^^^^^^^^^^^^^^ `foo_ref` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
help: consider changing this to be a mutable reference
|
LL | let foo_ref = &mut foo;
| ~~~~~~~~

error: aborting due to 6 previous errors

Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
error[E0594]: cannot assign to `*s.pointer`, which is behind a `&` reference
--> $DIR/borrowck-assign-to-andmut-in-aliasable-loc.rs:9:5
|
LL | fn a(s: &S) {
| -- help: consider changing this to be a mutable reference: `&mut S<'_>`
LL | *s.pointer += 1;
| ^^^^^^^^^^^^^^^ `s` is a `&` reference, so the data it refers to cannot be written
|
help: consider changing this to be a mutable reference
|
LL | fn a(s: &mut S<'_>) {
| ~~~~~~~~~~

error[E0594]: cannot assign to `*s.pointer`, which is behind a `&` reference
--> $DIR/borrowck-assign-to-andmut-in-aliasable-loc.rs:17:5
|
LL | fn c(s: & &mut S) {
| -------- help: consider changing this to be a mutable reference: `&mut &mut S<'_>`
LL | *s.pointer += 1;
| ^^^^^^^^^^^^^^^ `s` is a `&` reference, so the data it refers to cannot be written
|
help: consider changing this to be a mutable reference
|
LL | fn c(s: &mut &mut S<'_>) {
| ~~~~~~~~~~~~~~~

error: aborting due to 2 previous errors

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@ LL | **t1 = 22;
error[E0596]: cannot borrow `**t0` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs:19:26
|
LL | fn foo4(t0: & &mut isize) {
| ------------ help: consider changing this to be a mutable reference: `&mut &mut isize`
LL | let x: &mut isize = &mut **t0;
| ^^^^^^^^^ `t0` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
help: consider changing this to be a mutable reference
|
LL | fn foo4(t0: &mut &mut isize) {
| ~~~~~~~~~~~~~~~

error: aborting due to 3 previous errors

Expand Down
7 changes: 5 additions & 2 deletions src/test/ui/borrowck/borrowck-issue-14498.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
error[E0594]: cannot assign to `***p`, which is behind a `&` reference
--> $DIR/borrowck-issue-14498.rs:16:5
|
LL | let p = &y;
| -- help: consider changing this to be a mutable reference: `&mut y`
LL | ***p = 2;
| ^^^^^^^^ `p` is a `&` reference, so the data it refers to cannot be written
|
help: consider changing this to be a mutable reference
|
LL | let p = &mut y;
| ~~~~~~

error[E0506]: cannot assign to `**y` because it is borrowed
--> $DIR/borrowck-issue-14498.rs:25:5
Expand Down
7 changes: 5 additions & 2 deletions src/test/ui/borrowck/borrowck-reborrow-from-mut.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,13 @@ LL | use_imm(_bar1);
error[E0596]: cannot borrow `foo.bar1` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-reborrow-from-mut.rs:88:17
|
LL | fn borrow_mut_from_imm(foo: &Foo) {
| ---- help: consider changing this to be a mutable reference: `&mut Foo`
LL | let _bar1 = &mut foo.bar1;
| ^^^^^^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
help: consider changing this to be a mutable reference
|
LL | fn borrow_mut_from_imm(foo: &mut Foo) {
| ~~~~~~~~

error: aborting due to 11 previous errors

Expand Down
8 changes: 5 additions & 3 deletions src/test/ui/borrowck/issue-85765.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ LL | rofl.push(Vec::new());
error[E0594]: cannot assign to `*r`, which is behind a `&` reference
--> $DIR/issue-85765.rs:12:5
|
LL | let r = &mutvar;
| ------- help: consider changing this to be a mutable reference: `&mut mutvar`
LL |
LL | *r = 0;
| ^^^^^^ `r` is a `&` reference, so the data it refers to cannot be written
|
help: consider changing this to be a mutable reference
|
LL | let r = &mut mutvar;
| ~~~~~~~~~~~

error[E0594]: cannot assign to `*x`, which is behind a `&` reference
--> $DIR/issue-85765.rs:19:5
Expand Down
8 changes: 5 additions & 3 deletions src/test/ui/borrowck/issue-93093.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
error[E0594]: cannot assign to `self.foo`, which is behind a `&` reference
--> $DIR/issue-93093.rs:8:9
|
LL | async fn bar(&self) {
| ----- help: consider changing this to be a mutable reference: `&mut self`
LL |
LL | self.foo += 1;
| ^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be written
|
help: consider changing this to be a mutable reference
|
LL | async fn bar(&mut self) {
| ~~~~~~~~~

error: aborting due to previous error

Expand Down
Loading

0 comments on commit b9439eb

Please sign in to comment.