Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 31 additions & 6 deletions compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
AccessKind::Mutate => {
err = self.cannot_assign(span, &(item_msg + &reason));
act = "assign";
acted_on = "written";
acted_on = "written to";
span
}
AccessKind::MutableBorrow => {
Expand Down Expand Up @@ -518,8 +518,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
err.span_label(
span,
format!(
"`{name}` is a `{pointer_sigil}` {pointer_desc}, \
so the data it refers to cannot be {acted_on}",
"`{name}` is a `{pointer_sigil}` {pointer_desc}, so it cannot be \
{acted_on}",
),
);

Expand All @@ -542,7 +542,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
self.expected_fn_found_fn_mut_call(&mut err, span, act);
}

PlaceRef { local: _, projection: [.., ProjectionElem::Deref] } => {
PlaceRef { local, projection: [.., ProjectionElem::Deref] } => {
err.span_label(span, format!("cannot {act}"));

match opt_source {
Expand All @@ -559,11 +559,36 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
));
self.suggest_map_index_mut_alternatives(ty, &mut err, span);
}
_ => (),
_ => {
let local = &self.body.local_decls[local];
match local.local_info() {
LocalInfo::StaticRef { def_id, .. } => {
let span = self.infcx.tcx.def_span(def_id);
err.span_label(span, format!("this `static` cannot be {acted_on}"));
}
LocalInfo::ConstRef { def_id } => {
let span = self.infcx.tcx.def_span(def_id);
err.span_label(span, format!("this `const` cannot be {acted_on}"));
}
LocalInfo::BlockTailTemp(_) | LocalInfo::Boring
if !local.source_info.span.overlaps(span) =>
{
err.span_label(
local.source_info.span,
format!("this cannot be {acted_on}"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not seem to have a testcase.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's covered by a few for Boring like in tests/ui/nll/dont-print-desugared.stderr, and tests/ui/pattern/mut-pattern-of-immutable-borrow.rs covers the BlockTailTemp case.

Copy link
Member

@hkBst hkBst Nov 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked for the output "this cannot be written to" and did not find it. Since you added the "to", the output should be in the diff, but I did not find it...

);
}
_ => {}
}
}
}
}

_ => {
PlaceRef { local, .. } => {
let local = &self.body.local_decls[local];
if !local.source_info.span.overlaps(span) {
err.span_label(local.source_info.span, format!("this cannot be {acted_on}"));
}
err.span_label(span, format!("cannot {act}"));
}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/array-slice-vec/slice-mut-2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
--> $DIR/slice-mut-2.rs:7:18
|
LL | let _ = &mut x[2..4];
| ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
| ^ `x` is a `&` reference, so it cannot be borrowed as mutable
|
help: consider changing this binding's type
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `sm.x` as mutable, as it is behind a `&` reference
--> $DIR/accidentally-cloning-ref-borrow-error.rs:32:9
|
LL | foo(&mut sm.x);
| ^^^^^^^^^ `sm` is a `&` reference, so the data it refers to cannot be borrowed as mutable
| ^^^^^^^^^ `sm` is a `&` reference, so it cannot be borrowed as mutable
|
help: `Str` doesn't implement `Clone`, so this call clones the reference `&Str`
--> $DIR/accidentally-cloning-ref-borrow-error.rs:31:21
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/borrowck/argument_number_mismatch_ice.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ error[E0594]: cannot assign to `*input`, which is behind a `&` reference
--> $DIR/argument_number_mismatch_ice.rs:10:9
|
LL | *input = self.0;
| ^^^^^^^^^^^^^^^ `input` is a `&` reference, so the data it refers to cannot be written
| ^^^^^^^^^^^^^^^ `input` is a `&` reference, so it cannot be written to
|
help: consider changing this to be a mutable reference in the `impl` method and the `trait` definition
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
--> $DIR/borrow-raw-address-of-deref-mutability.rs:6:13
|
LL | let q = &raw mut *x;
| ^^^^^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
| ^^^^^^^^^^^ `x` is a `&` reference, so it cannot be borrowed as mutable
|
help: consider changing this to be a mutable reference
|
Expand All @@ -13,7 +13,7 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `*const` pointer
--> $DIR/borrow-raw-address-of-deref-mutability.rs:12:13
|
LL | let q = &raw mut *x;
| ^^^^^^^^^^^ `x` is a `*const` pointer, so the data it refers to cannot be borrowed as mutable
| ^^^^^^^^^^^ `x` is a `*const` pointer, so it cannot be borrowed as mutable
|
help: consider specifying this binding's type
|
Expand Down
9 changes: 6 additions & 3 deletions tests/ui/borrowck/borrowck-access-permissions.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ LL | let mut x = 1;
error[E0596]: cannot borrow immutable static item `static_x` as mutable
--> $DIR/borrowck-access-permissions.rs:16:19
|
LL | static static_x: i32 = 1;
| -------------------- this `static` cannot be borrowed as mutable
...
LL | let _y1 = &mut static_x;
| ^^^^^^^^^^^^^ cannot borrow as mutable

Expand All @@ -30,7 +33,7 @@ error[E0596]: cannot borrow `*ref_x` as mutable, as it is behind a `&` reference
--> $DIR/borrowck-access-permissions.rs:36:19
|
LL | let _y1 = &mut *ref_x;
| ^^^^^^^^^^^ `ref_x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
| ^^^^^^^^^^^ `ref_x` is a `&` reference, so it cannot be borrowed as mutable
|
help: consider changing this to be a mutable reference
|
Expand All @@ -41,7 +44,7 @@ error[E0596]: cannot borrow `*ptr_x` as mutable, as it is behind a `*const` poin
--> $DIR/borrowck-access-permissions.rs:46:23
|
LL | let _y1 = &mut *ptr_x;
| ^^^^^^^^^^^ `ptr_x` is a `*const` pointer, so the data it refers to cannot be borrowed as mutable
| ^^^^^^^^^^^ `ptr_x` is a `*const` pointer, so it cannot be borrowed as mutable
|
help: consider changing this binding's type
|
Expand All @@ -53,7 +56,7 @@ error[E0596]: cannot borrow `*foo_ref.f` as mutable, as it is behind a `&` refer
--> $DIR/borrowck-access-permissions.rs:59:18
|
LL | let _y = &mut *foo_ref.f;
| ^^^^^^^^^^^^^^^ `foo_ref` is a `&` reference, so the data it refers to cannot be borrowed as mutable
| ^^^^^^^^^^^^^^^ `foo_ref` is a `&` reference, so it cannot be borrowed as mutable
|
help: consider changing this to be a mutable reference
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0594]: cannot assign to `*s.pointer`, which is behind a `&` reference
--> $DIR/borrowck-assign-to-andmut-in-aliasable-loc.rs:9:5
|
LL | *s.pointer += 1;
| ^^^^^^^^^^^^^^^ `s` is a `&` reference, so the data it refers to cannot be written
| ^^^^^^^^^^^^^^^ `s` is a `&` reference, so it cannot be written to
|
help: consider changing this to be a mutable reference
|
Expand All @@ -13,7 +13,7 @@ error[E0594]: cannot assign to `*s.pointer`, which is behind a `&` reference
--> $DIR/borrowck-assign-to-andmut-in-aliasable-loc.rs:17:5
|
LL | *s.pointer += 1;
| ^^^^^^^^^^^^^^^ `s` is a `&` reference, so the data it refers to cannot be written
| ^^^^^^^^^^^^^^^ `s` is a `&` reference, so it cannot be written to
|
help: consider changing this to be a mutable reference
|
Expand Down
3 changes: 3 additions & 0 deletions tests/ui/borrowck/borrowck-assign-to-constants.stderr
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
error[E0594]: cannot assign to immutable static item `foo`
--> $DIR/borrowck-assign-to-constants.rs:5:5
|
LL | static foo: isize = 5;
| ----------------- this `static` cannot be written to
...
LL | foo = 6;
| ^^^^^^^ cannot assign

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0594]: cannot assign to `**t1`, which is behind a `&` reference
--> $DIR/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs:9:5
|
LL | **t1 = 22;
| ^^^^^^^^^ `t1` is a `&` reference, so the data it refers to cannot be written
| ^^^^^^^^^ `t1` is a `&` reference, so it cannot be written to
|
help: consider specifying this binding's type
|
Expand All @@ -23,7 +23,7 @@ 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 | let x: &mut isize = &mut **t0;
| ^^^^^^^^^ `t0` is a `&` reference, so the data it refers to cannot be borrowed as mutable
| ^^^^^^^^^ `t0` is a `&` reference, so it cannot be borrowed as mutable
|
help: consider changing this to be a mutable reference
|
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/borrowck/borrowck-issue-14498.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0594]: cannot assign to `***p`, which is behind a `&` reference
--> $DIR/borrowck-issue-14498.rs:16:5
|
LL | ***p = 2;
| ^^^^^^^^ `p` is a `&` reference, so the data it refers to cannot be written
| ^^^^^^^^ `p` is a `&` reference, so it cannot be written to
|
help: consider changing this to be a mutable reference
|
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/borrowck/borrowck-reborrow-from-mut.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ error[E0596]: cannot borrow `foo.bar1` as mutable, as it is behind a `&` referen
--> $DIR/borrowck-reborrow-from-mut.rs:88:17
|
LL | let _bar1 = &mut foo.bar1;
| ^^^^^^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be borrowed as mutable
| ^^^^^^^^^^^^^ `foo` is a `&` reference, so it cannot be borrowed as mutable
|
help: consider changing this to be a mutable reference
|
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/borrowck/issue-115259-suggest-iter-mut.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `**layer` as mutable, as it is behind a `&` referenc
--> $DIR/issue-115259-suggest-iter-mut.rs:15:65
|
LL | self.layers.iter().fold(0, |result, mut layer| result + layer.process())
| --------- ^^^^^ `layer` is a `&` reference, so the data it refers to cannot be borrowed as mutable
| --------- ^^^^^ `layer` is a `&` reference, so it cannot be borrowed as mutable
| |
| consider changing this binding's type to be: `&mut Box<dyn Layer>`
|
Expand Down
3 changes: 3 additions & 0 deletions tests/ui/borrowck/issue-42344.stderr
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
error[E0596]: cannot borrow `*TAB[_]` as mutable, as `TAB` is an immutable static item
--> $DIR/issue-42344.rs:4:5
|
LL | static TAB: [&mut [u8]; 0] = [];
| -------------------------- this `static` cannot be borrowed as mutable
...
LL | TAB[0].iter_mut();
| ^^^^^^ cannot borrow as mutable

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/borrowck/issue-62387-suggest-iter-mut-2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `*container` as mutable, as it is behind a `&` refer
--> $DIR/issue-62387-suggest-iter-mut-2.rs:30:45
|
LL | vec.iter().flat_map(|container| container.things()).cloned().collect::<Vec<PathBuf>>();
| --------- ^^^^^^^^^ `container` is a `&` reference, so the data it refers to cannot be borrowed as mutable
| --------- ^^^^^^^^^ `container` is a `&` reference, so it cannot be borrowed as mutable
| |
| consider changing this binding's type to be: `&mut Container`
|
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/borrowck/issue-62387-suggest-iter-mut.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference
--> $DIR/issue-62387-suggest-iter-mut.rs:18:27
|
LL | v.iter().for_each(|a| a.double());
| - ^ `a` is a `&` reference, so the data it refers to cannot be borrowed as mutable
| - ^ `a` is a `&` reference, so it cannot be borrowed as mutable
| |
| consider changing this binding's type to be: `&mut A`
|
Expand All @@ -15,7 +15,7 @@ error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference
--> $DIR/issue-62387-suggest-iter-mut.rs:25:39
|
LL | v.iter().rev().rev().for_each(|a| a.double());
| - ^ `a` is a `&` reference, so the data it refers to cannot be borrowed as mutable
| - ^ `a` is a `&` reference, so it cannot be borrowed as mutable
| |
| consider changing this binding's type to be: `&mut A`
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ LL | for item in &mut std::iter::empty::<&'static ()>() {
| -------------------------------------- this iterator yields `&` references
LL |
LL | *item = ();
| ^^^^^^^^^^ `item` is a `&` reference, so the data it refers to cannot be written
| ^^^^^^^^^^ `item` is a `&` reference, so it cannot be written to

error: aborting due to 1 previous error

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/borrowck/issue-82032.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ LL | for v in self.0.values() {
| | help: use mutable method: `values_mut()`
| this iterator yields `&` references
LL | v.flush();
| ^ `v` is a `&` reference, so the data it refers to cannot be borrowed as mutable
| ^ `v` is a `&` reference, so it cannot be borrowed as mutable

error: aborting due to 1 previous error

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/borrowck/issue-83309-ice-immut-in-for-loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ fn main() {
//~^ NOTE this iterator yields `&` references
*v -= 1;
//~^ ERROR cannot assign to `*v`, which is behind a `&` reference
//~| NOTE `v` is a `&` reference, so the data it refers to cannot be written
//~| NOTE `v` is a `&` reference, so it cannot be written to
}
}

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/borrowck/issue-83309-ice-immut-in-for-loop.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ LL | for v in Query.iter_mut() {
| ---------------- this iterator yields `&` references
LL |
LL | *v -= 1;
| ^^^^^^^ `v` is a `&` reference, so the data it refers to cannot be written
| ^^^^^^^ `v` is a `&` reference, so it cannot be written to

error: aborting due to 1 previous error

Expand Down
8 changes: 4 additions & 4 deletions tests/ui/borrowck/issue-85765-closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,27 @@ fn main() {
//~^ HELP consider changing this binding's type
rofl.push(Vec::new());
//~^ ERROR cannot borrow `*rofl` as mutable, as it is behind a `&` reference
//~| NOTE `rofl` is a `&` reference, so the data it refers to cannot be borrowed as mutable
//~| NOTE `rofl` is a `&` reference, so it cannot be borrowed as mutable

let mut mutvar = 42;
let r = &mutvar;
//~^ HELP consider changing this to be a mutable reference
*r = 0;
//~^ ERROR cannot assign to `*r`, which is behind a `&` reference
//~| NOTE `r` is a `&` reference, so the data it refers to cannot be written
//~| NOTE `r` is a `&` reference, so it cannot be written to

#[rustfmt::skip]
let x: &usize = &mut{0};
//~^ HELP consider changing this binding's type
*x = 1;
//~^ ERROR cannot assign to `*x`, which is behind a `&` reference
//~| NOTE `x` is a `&` reference, so the data it refers to cannot be written
//~| NOTE `x` is a `&` reference, so it cannot be written to

#[rustfmt::skip]
let y: &usize = &mut(0);
//~^ HELP consider changing this binding's type
*y = 1;
//~^ ERROR cannot assign to `*y`, which is behind a `&` reference
//~| NOTE `y` is a `&` reference, so the data it refers to cannot be written
//~| NOTE `y` is a `&` reference, so it cannot be written to
};
}
8 changes: 4 additions & 4 deletions tests/ui/borrowck/issue-85765-closure.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0596]: cannot borrow `*rofl` as mutable, as it is behind a `&` reference
--> $DIR/issue-85765-closure.rs:6:9
|
LL | rofl.push(Vec::new());
| ^^^^ `rofl` is a `&` reference, so the data it refers to cannot be borrowed as mutable
| ^^^^ `rofl` is a `&` reference, so it cannot be borrowed as mutable
|
help: consider changing this binding's type
|
Expand All @@ -13,7 +13,7 @@ error[E0594]: cannot assign to `*r`, which is behind a `&` reference
--> $DIR/issue-85765-closure.rs:13:9
|
LL | *r = 0;
| ^^^^^^ `r` is a `&` reference, so the data it refers to cannot be written
| ^^^^^^ `r` is a `&` reference, so it cannot be written to
|
help: consider changing this to be a mutable reference
|
Expand All @@ -24,7 +24,7 @@ error[E0594]: cannot assign to `*x`, which is behind a `&` reference
--> $DIR/issue-85765-closure.rs:20:9
|
LL | *x = 1;
| ^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written
| ^^^^^^ `x` is a `&` reference, so it cannot be written to
|
help: consider changing this binding's type
|
Expand All @@ -35,7 +35,7 @@ error[E0594]: cannot assign to `*y`, which is behind a `&` reference
--> $DIR/issue-85765-closure.rs:27:9
|
LL | *y = 1;
| ^^^^^^ `y` is a `&` reference, so the data it refers to cannot be written
| ^^^^^^ `y` is a `&` reference, so it cannot be written to
|
help: consider changing this binding's type
|
Expand Down
8 changes: 4 additions & 4 deletions tests/ui/borrowck/issue-85765.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,26 @@ fn main() {
//~^ HELP consider changing this binding's type
rofl.push(Vec::new());
//~^ ERROR cannot borrow `*rofl` as mutable, as it is behind a `&` reference
//~| NOTE `rofl` is a `&` reference, so the data it refers to cannot be borrowed as mutable
//~| NOTE `rofl` is a `&` reference, so it cannot be borrowed as mutable

let mut mutvar = 42;
let r = &mutvar;
//~^ HELP consider changing this to be a mutable reference
*r = 0;
//~^ ERROR cannot assign to `*r`, which is behind a `&` reference
//~| NOTE `r` is a `&` reference, so the data it refers to cannot be written
//~| NOTE `r` is a `&` reference, so it cannot be written to

#[rustfmt::skip]
let x: &usize = &mut{0};
//~^ HELP consider changing this binding's type
*x = 1;
//~^ ERROR cannot assign to `*x`, which is behind a `&` reference
//~| NOTE `x` is a `&` reference, so the data it refers to cannot be written
//~| NOTE `x` is a `&` reference, so it cannot be written to

#[rustfmt::skip]
let y: &usize = &mut(0);
//~^ HELP consider changing this binding's type
*y = 1;
//~^ ERROR cannot assign to `*y`, which is behind a `&` reference
//~| NOTE `y` is a `&` reference, so the data it refers to cannot be written
//~| NOTE `y` is a `&` reference, so it cannot be written to
}
Loading
Loading