tweak "make mut" spans when assigning to locals
This commit is contained in:
parent
3320f2fab6
commit
fd8aa5ec7d
@ -1202,36 +1202,42 @@ fn suggest_ampmut<'tcx>(
|
||||
opt_assignment_rhs_span: Option<Span>,
|
||||
opt_ty_info: Option<Span>,
|
||||
) -> (bool, Span, String) {
|
||||
// if there is a RHS and it starts with a `&` from it, then check if it is
|
||||
// mutable, and if not, put suggest putting `mut ` to make it mutable.
|
||||
// we don't have to worry about lifetime annotations here because they are
|
||||
// not valid when taking a reference. For example, the following is not valid Rust:
|
||||
//
|
||||
// let x: &i32 = &'a 5;
|
||||
// ^^ lifetime annotation not allowed
|
||||
//
|
||||
if let Some(assignment_rhs_span) = opt_assignment_rhs_span
|
||||
&& let Ok(src) = tcx.sess.source_map().span_to_snippet(assignment_rhs_span)
|
||||
&& let Some(stripped) = src.strip_prefix('&')
|
||||
{
|
||||
let is_mutbl = |ty: &str| -> bool {
|
||||
if let Some(rest) = ty.strip_prefix("mut") {
|
||||
match rest.chars().next() {
|
||||
// e.g. `&mut x`
|
||||
Some(c) if c.is_whitespace() => true,
|
||||
// e.g. `&mut(x)`
|
||||
Some('(') => true,
|
||||
// e.g. `&mut{x}`
|
||||
Some('{') => true,
|
||||
// e.g. `&mutablevar`
|
||||
_ => false,
|
||||
}
|
||||
} else {
|
||||
false
|
||||
let is_mut = if let Some(rest) = stripped.trim_start().strip_prefix("mut") {
|
||||
match rest.chars().next() {
|
||||
// e.g. `&mut x`
|
||||
Some(c) if c.is_whitespace() => true,
|
||||
// e.g. `&mut(x)`
|
||||
Some('(') => true,
|
||||
// e.g. `&mut{x}`
|
||||
Some('{') => true,
|
||||
// e.g. `&mutablevar`
|
||||
_ => false,
|
||||
}
|
||||
} else {
|
||||
false
|
||||
};
|
||||
if let (true, Some(ws_pos)) = (src.starts_with("&'"), src.find(char::is_whitespace)) {
|
||||
let lt_name = &src[1..ws_pos];
|
||||
let ty = src[ws_pos..].trim_start();
|
||||
if !is_mutbl(ty) {
|
||||
return (true, assignment_rhs_span, format!("&{lt_name} mut {ty}"));
|
||||
}
|
||||
} else if let Some(stripped) = src.strip_prefix('&') {
|
||||
let stripped = stripped.trim_start();
|
||||
if !is_mutbl(stripped) {
|
||||
return (true, assignment_rhs_span, format!("&mut {stripped}"));
|
||||
}
|
||||
// if the reference is already mutable then there is nothing we can do
|
||||
// here.
|
||||
if !is_mut {
|
||||
let span = assignment_rhs_span;
|
||||
// shrink the span to just after the `&` in `&variable`
|
||||
let span = span.with_lo(span.lo() + BytePos(1)).shrink_to_lo();
|
||||
|
||||
// FIXME(Ezrashaw): returning is bad because we still might want to
|
||||
// update the annotated type, see #106857.
|
||||
return (true, span, "mut ".to_owned());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ LL | let _ = &mut x[2..4];
|
||||
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
|
||||
|
||||
|
@ -7,7 +7,7 @@ LL | let q = &raw mut *x;
|
||||
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
|
||||
@ -18,7 +18,7 @@ LL | let q = &raw mut *x;
|
||||
help: consider changing this to be a mutable pointer
|
||||
|
|
||||
LL | let x = &mut 0 as *const i32;
|
||||
| ~~~~~~
|
||||
| +++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -35,7 +35,7 @@ LL | let _y1 = &mut *ref_x;
|
||||
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
|
||||
@ -46,7 +46,7 @@ LL | let _y1 = &mut *ptr_x;
|
||||
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
|
||||
@ -57,7 +57,7 @@ LL | let _y = &mut *foo_ref.f;
|
||||
help: consider changing this to be a mutable reference
|
||||
|
|
||||
LL | let foo_ref = &mut foo;
|
||||
| ~~~~~~~~
|
||||
| +++
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
|
@ -7,7 +7,7 @@ LL | ***p = 2;
|
||||
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
|
||||
|
@ -18,7 +18,7 @@ LL | *r = 0;
|
||||
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
|
||||
|
@ -10,7 +10,7 @@ LL | **ref_mref_x = y;
|
||||
help: consider changing this to be a mutable reference
|
||||
|
|
||||
LL | let ref_mref_x = &mut mref_x;
|
||||
| ~~~~~~~~~~~
|
||||
| +++
|
||||
|
||||
error[E0596]: cannot borrow `**mref_ref_x` as mutable, as it is behind a `&` reference
|
||||
--> $DIR/mut_ref.rs:26:13
|
||||
|
@ -7,7 +7,7 @@ LL | buf.iter_mut();
|
||||
help: consider changing this to be a mutable reference
|
||||
|
|
||||
LL | let mut buf = &mut [1, 2, 3, 4];
|
||||
| ~~~~~~~~~~~~~~~~~
|
||||
| +++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -7,7 +7,7 @@ LL | fancy_ref.num = 6;
|
||||
help: consider changing this to be a mutable reference
|
||||
|
|
||||
LL | let fancy_ref = &mut (&mut fancy);
|
||||
| ~~~~~~~~~~~~~~~~~
|
||||
| +++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
fn main() {
|
||||
let foo = &16;
|
||||
//~^ HELP consider changing this to be a mutable reference
|
||||
//~| SUGGESTION &mut 16
|
||||
*foo = 32;
|
||||
//~^ ERROR cannot assign to `*foo`, which is behind a `&` reference
|
||||
let bar = foo;
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0594]: cannot assign to `*foo`, which is behind a `&` reference
|
||||
--> $DIR/issue-51515.rs:5:5
|
||||
--> $DIR/issue-51515.rs:4:5
|
||||
|
|
||||
LL | *foo = 32;
|
||||
| ^^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be written
|
||||
@ -7,10 +7,10 @@ LL | *foo = 32;
|
||||
help: consider changing this to be a mutable reference
|
||||
|
|
||||
LL | let foo = &mut 16;
|
||||
| ~~~~~~~
|
||||
| +++
|
||||
|
||||
error[E0594]: cannot assign to `*bar`, which is behind a `&` reference
|
||||
--> $DIR/issue-51515.rs:9:5
|
||||
--> $DIR/issue-51515.rs:8:5
|
||||
|
|
||||
LL | *bar = 64;
|
||||
| ^^^^^^^^^ `bar` is a `&` reference, so the data it refers to cannot be written
|
||||
|
@ -7,7 +7,7 @@ LL | fancy_ref.num = 6;
|
||||
help: consider changing this to be a mutable reference
|
||||
|
|
||||
LL | let fancy_ref = &mut (&mut fancy);
|
||||
| ~~~~~~~~~~~~~~~~~
|
||||
| +++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user