Skip to content

Commit e97789d

Browse files
committed
tweak "make mut" spans when assigning to locals
1 parent c781584 commit e97789d

File tree

12 files changed

+46
-41
lines changed

12 files changed

+46
-41
lines changed

compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,36 +1202,42 @@ fn suggest_ampmut<'tcx>(
12021202
opt_assignment_rhs_span: Option<Span>,
12031203
opt_ty_info: Option<Span>,
12041204
) -> (bool, Span, String) {
1205+
// if there is a RHS and it starts with a `&` from it, then check if it is
1206+
// mutable, and if not, put suggest putting `mut ` to make it mutable.
1207+
// we don't have to worry about lifetime annotations here because they are
1208+
// not valid when taking a reference. For example, the following is not valid Rust:
1209+
//
1210+
// let x: &i32 = &'a 5;
1211+
// ^^ lifetime annotation not allowed
1212+
//
12051213
if let Some(assignment_rhs_span) = opt_assignment_rhs_span
12061214
&& let Ok(src) = tcx.sess.source_map().span_to_snippet(assignment_rhs_span)
1215+
&& let Some(stripped) = src.strip_prefix('&')
12071216
{
1208-
let is_mutbl = |ty: &str| -> bool {
1209-
if let Some(rest) = ty.strip_prefix("mut") {
1210-
match rest.chars().next() {
1211-
// e.g. `&mut x`
1212-
Some(c) if c.is_whitespace() => true,
1213-
// e.g. `&mut(x)`
1214-
Some('(') => true,
1215-
// e.g. `&mut{x}`
1216-
Some('{') => true,
1217-
// e.g. `&mutablevar`
1218-
_ => false,
1219-
}
1220-
} else {
1221-
false
1217+
let is_mut = if let Some(rest) = stripped.trim_start().strip_prefix("mut") {
1218+
match rest.chars().next() {
1219+
// e.g. `&mut x`
1220+
Some(c) if c.is_whitespace() => true,
1221+
// e.g. `&mut(x)`
1222+
Some('(') => true,
1223+
// e.g. `&mut{x}`
1224+
Some('{') => true,
1225+
// e.g. `&mutablevar`
1226+
_ => false,
12221227
}
1228+
} else {
1229+
false
12231230
};
1224-
if let (true, Some(ws_pos)) = (src.starts_with("&'"), src.find(char::is_whitespace)) {
1225-
let lt_name = &src[1..ws_pos];
1226-
let ty = src[ws_pos..].trim_start();
1227-
if !is_mutbl(ty) {
1228-
return (true, assignment_rhs_span, format!("&{lt_name} mut {ty}"));
1229-
}
1230-
} else if let Some(stripped) = src.strip_prefix('&') {
1231-
let stripped = stripped.trim_start();
1232-
if !is_mutbl(stripped) {
1233-
return (true, assignment_rhs_span, format!("&mut {stripped}"));
1234-
}
1231+
// if the reference is already mutable then there is nothing we can do
1232+
// here.
1233+
if !is_mut {
1234+
let span = assignment_rhs_span;
1235+
// shrink the span to just after the `&` in `&variable`
1236+
let span = span.with_lo(span.lo() + BytePos(1)).shrink_to_lo();
1237+
1238+
// FIXME(Ezrashaw): returning is bad because we still might want to
1239+
// update the annotated type, see #106857.
1240+
return (true, span, "mut ".to_owned());
12351241
}
12361242
}
12371243

tests/ui/array-slice-vec/slice-mut-2.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | let _ = &mut x[2..4];
77
help: consider changing this to be a mutable reference
88
|
99
LL | let x: &[isize] = &mut [1, 2, 3, 4, 5];
10-
| ~~~~~~~~~~~~~~~~~~~~
10+
| +++
1111

1212
error: aborting due to previous error
1313

tests/ui/borrowck/borrow-raw-address-of-deref-mutability.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | let q = &raw mut *x;
77
help: consider changing this to be a mutable reference
88
|
99
LL | let x = &mut 0;
10-
| ~~~~~~
10+
| +++
1111

1212
error[E0596]: cannot borrow `*x` as mutable, as it is behind a `*const` pointer
1313
--> $DIR/borrow-raw-address-of-deref-mutability.rs:14:13
@@ -18,7 +18,7 @@ LL | let q = &raw mut *x;
1818
help: consider changing this to be a mutable pointer
1919
|
2020
LL | let x = &mut 0 as *const i32;
21-
| ~~~~~~
21+
| +++
2222

2323
error: aborting due to 2 previous errors
2424

tests/ui/borrowck/borrowck-access-permissions.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ LL | let _y1 = &mut *ref_x;
3535
help: consider changing this to be a mutable reference
3636
|
3737
LL | let ref_x = &mut x;
38-
| ~~~~~~
38+
| +++
3939

4040
error[E0596]: cannot borrow `*ptr_x` as mutable, as it is behind a `*const` pointer
4141
--> $DIR/borrowck-access-permissions.rs:39:23
@@ -46,7 +46,7 @@ LL | let _y1 = &mut *ptr_x;
4646
help: consider changing this to be a mutable pointer
4747
|
4848
LL | let ptr_x : *const _ = &mut x;
49-
| ~~~~~~
49+
| +++
5050

5151
error[E0596]: cannot borrow `*foo_ref.f` as mutable, as it is behind a `&` reference
5252
--> $DIR/borrowck-access-permissions.rs:48:18
@@ -57,7 +57,7 @@ LL | let _y = &mut *foo_ref.f;
5757
help: consider changing this to be a mutable reference
5858
|
5959
LL | let foo_ref = &mut foo;
60-
| ~~~~~~~~
60+
| +++
6161

6262
error: aborting due to 6 previous errors
6363

tests/ui/borrowck/borrowck-issue-14498.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | ***p = 2;
77
help: consider changing this to be a mutable reference
88
|
99
LL | let p = &mut y;
10-
| ~~~~~~
10+
| +++
1111

1212
error[E0506]: cannot assign to `**y` because it is borrowed
1313
--> $DIR/borrowck-issue-14498.rs:25:5

tests/ui/borrowck/issue-85765.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ LL | *r = 0;
1818
help: consider changing this to be a mutable reference
1919
|
2020
LL | let r = &mut mutvar;
21-
| ~~~~~~~~~~~
21+
| +++
2222

2323
error[E0594]: cannot assign to `*x`, which is behind a `&` reference
2424
--> $DIR/issue-85765.rs:19:5

tests/ui/closures/2229_closure_analysis/diagnostics/mut_ref.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ LL | **ref_mref_x = y;
1010
help: consider changing this to be a mutable reference
1111
|
1212
LL | let ref_mref_x = &mut mref_x;
13-
| ~~~~~~~~~~~
13+
| +++
1414

1515
error[E0596]: cannot borrow `**mref_ref_x` as mutable, as it is behind a `&` reference
1616
--> $DIR/mut_ref.rs:26:13

tests/ui/did_you_mean/issue-40823.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | buf.iter_mut();
77
help: consider changing this to be a mutable reference
88
|
99
LL | let mut buf = &mut [1, 2, 3, 4];
10-
| ~~~~~~~~~~~~~~~~~
10+
| +++
1111

1212
error: aborting due to previous error
1313

tests/ui/error-codes/E0389.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | fancy_ref.num = 6;
77
help: consider changing this to be a mutable reference
88
|
99
LL | let fancy_ref = &mut (&mut fancy);
10-
| ~~~~~~~~~~~~~~~~~
10+
| +++
1111

1212
error: aborting due to previous error
1313

tests/ui/issues/issue-51515.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
fn main() {
22
let foo = &16;
33
//~^ HELP consider changing this to be a mutable reference
4-
//~| SUGGESTION &mut 16
54
*foo = 32;
65
//~^ ERROR cannot assign to `*foo`, which is behind a `&` reference
76
let bar = foo;

tests/ui/issues/issue-51515.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
error[E0594]: cannot assign to `*foo`, which is behind a `&` reference
2-
--> $DIR/issue-51515.rs:5:5
2+
--> $DIR/issue-51515.rs:4:5
33
|
44
LL | *foo = 32;
55
| ^^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be written
66
|
77
help: consider changing this to be a mutable reference
88
|
99
LL | let foo = &mut 16;
10-
| ~~~~~~~
10+
| +++
1111

1212
error[E0594]: cannot assign to `*bar`, which is behind a `&` reference
13-
--> $DIR/issue-51515.rs:9:5
13+
--> $DIR/issue-51515.rs:8:5
1414
|
1515
LL | *bar = 64;
1616
| ^^^^^^^^^ `bar` is a `&` reference, so the data it refers to cannot be written

tests/ui/nll/issue-47388.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | fancy_ref.num = 6;
77
help: consider changing this to be a mutable reference
88
|
99
LL | let fancy_ref = &mut (&mut fancy);
10-
| ~~~~~~~~~~~~~~~~~
10+
| +++
1111

1212
error: aborting due to previous error
1313

0 commit comments

Comments
 (0)