1
Fork 0

tweak "make mut" spans (No. 2)

This commit is contained in:
Ezra Shaw 2023-04-19 19:29:28 +12:00 committed by Ezra Shaw
parent fd8aa5ec7d
commit 9624d2b08e
No known key found for this signature in database
GPG key ID: 5156CF5845150B0D
7 changed files with 36 additions and 30 deletions

View file

@ -1241,35 +1241,41 @@ fn suggest_ampmut<'tcx>(
} }
} }
let (suggestibility, highlight_span) = match opt_ty_info { let (binding_exists, span) = match opt_ty_info {
// if this is a variable binding with an explicit type, // if this is a variable binding with an explicit type,
// try to highlight that for the suggestion. // then we will suggest changing it to be mutable.
// this is `Applicability::MachineApplicable`.
Some(ty_span) => (true, ty_span), Some(ty_span) => (true, ty_span),
// otherwise, just highlight the span associated with // otherwise, we'll suggest *adding* an annotated type, we'll suggest
// the (MIR) LocalDecl. // the RHS's type for that.
// this is `Applicability::HasPlaceholders`.
None => (false, local_decl.source_info.span), None => (false, local_decl.source_info.span),
}; };
if let Ok(src) = tcx.sess.source_map().span_to_snippet(highlight_span) // if the binding already exists and is a reference with a explicit
&& let (true, Some(ws_pos)) = (src.starts_with("&'"), src.find(char::is_whitespace)) // lifetime, then we can suggest adding ` mut`. this is special-cased from
// the path without a explicit lifetime.
if let Ok(src) = tcx.sess.source_map().span_to_snippet(span)
&& src.starts_with("&'")
// note that `& 'a T` is invalid so this is correct.
&& let Some(ws_pos) = src.find(char::is_whitespace)
{ {
let lt_name = &src[1..ws_pos]; let span = span.with_lo(span.lo() + BytePos(ws_pos as u32)).shrink_to_lo();
let ty = &src[ws_pos..]; (true, span, " mut".to_owned())
return (true, highlight_span, format!("&{lt_name} mut{ty}")); } else {
}
let ty_mut = local_decl.ty.builtin_deref(true).unwrap(); let ty_mut = local_decl.ty.builtin_deref(true).unwrap();
assert_eq!(ty_mut.mutbl, hir::Mutability::Not); assert_eq!(ty_mut.mutbl, hir::Mutability::Not);
( (
suggestibility, binding_exists,
highlight_span, span,
if local_decl.ty.is_ref() { if local_decl.ty.is_ref() {
format!("&mut {}", ty_mut.ty) format!("&mut {}", ty_mut.ty)
} else { } else {
format!("*mut {}", ty_mut.ty) format!("*mut {}", ty_mut.ty)
}, },
) )
}
} }
fn is_closure_or_generator(ty: Ty<'_>) -> bool { fn is_closure_or_generator(ty: Ty<'_>) -> bool {

View file

@ -73,7 +73,7 @@ LL | let _ = &mut self.x;
help: consider changing this to be a mutable reference help: consider changing this to be a mutable reference
| |
LL | fn foo3<'a>(self: &'a mut Self, other: &Z) { LL | fn foo3<'a>(self: &'a mut Self, other: &Z) {
| ~~~~~~~~~~~~ | +++
error[E0596]: cannot borrow `other.x` as mutable, as it is behind a `&` reference error[E0596]: cannot borrow `other.x` as mutable, as it is behind a `&` reference
--> $DIR/issue-39544.rs:31:17 --> $DIR/issue-39544.rs:31:17

View file

@ -7,7 +7,7 @@ LL | f2(|| x.0, f1(x.1))
help: consider changing this to be a mutable reference help: consider changing this to be a mutable reference
| |
LL | fn f3<'a>(x: &'a mut ((), &'a mut ())) { LL | fn f3<'a>(x: &'a mut ((), &'a mut ())) {
| ~~~~~~~~~~~~~~~~~~~~~~~~ | +++
error: aborting due to previous error error: aborting due to previous error

View file

@ -50,7 +50,7 @@ LL | x.y = 3;
help: consider changing this to be a mutable reference help: consider changing this to be a mutable reference
| |
LL | fn assign_field2<'a>(x: &'a mut Own<Point>) { LL | fn assign_field2<'a>(x: &'a mut Own<Point>) {
| ~~~~~~~~~~~~~~~~~~ | +++
error[E0499]: cannot borrow `*x` as mutable more than once at a time error[E0499]: cannot borrow `*x` as mutable more than once at a time
--> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:101:5 --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:101:5
@ -104,7 +104,7 @@ LL | *x.y_mut() = 3;
help: consider changing this to be a mutable reference help: consider changing this to be a mutable reference
| |
LL | fn assign_method2<'a>(x: &'a mut Own<Point>) { LL | fn assign_method2<'a>(x: &'a mut Own<Point>) {
| ~~~~~~~~~~~~~~~~~~ | +++
error: aborting due to 10 previous errors error: aborting due to 10 previous errors

View file

@ -18,7 +18,7 @@ LL | &mut **x
help: consider changing this to be a mutable reference help: consider changing this to be a mutable reference
| |
LL | fn deref_extend_mut1<'a>(x: &'a mut Own<isize>) -> &'a mut isize { LL | fn deref_extend_mut1<'a>(x: &'a mut Own<isize>) -> &'a mut isize {
| ~~~~~~~~~~~~~~~~~~ | +++
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/borrowck-borrow-overloaded-deref-mut.rs:49:6 --> $DIR/borrowck-borrow-overloaded-deref-mut.rs:49:6
@ -40,7 +40,7 @@ LL | **x = 3;
help: consider changing this to be a mutable reference help: consider changing this to be a mutable reference
| |
LL | fn assign2<'a>(x: &'a mut Own<isize>) { LL | fn assign2<'a>(x: &'a mut Own<isize>) {
| ~~~~~~~~~~~~~~~~~~ | +++
error: aborting due to 4 previous errors error: aborting due to 4 previous errors

View file

@ -18,7 +18,7 @@ LL | a.push_str("foo");
help: consider changing this to be a mutable reference help: consider changing this to be a mutable reference
| |
LL | pub fn foo<'a>(mut a: &'a mut String) { LL | pub fn foo<'a>(mut a: &'a mut String) {
| ~~~~~~~~~~~~~~ | +++
error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference
--> $DIR/mut-arg-hint.rs:15:9 --> $DIR/mut-arg-hint.rs:15:9

View file

@ -7,7 +7,7 @@ LL | *t
help: consider changing this to be a mutable reference help: consider changing this to be a mutable reference
| |
LL | fn reborrow_mut<'a>(t: &'a mut &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy { LL | fn reborrow_mut<'a>(t: &'a mut &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy {
| ~~~~~~~~~~~~~~~~~~~ | +++
error[E0596]: cannot borrow `**t` as mutable, as it is behind a `&` reference error[E0596]: cannot borrow `**t` as mutable, as it is behind a `&` reference
--> $DIR/trivial-bounds-inconsistent-copy-reborrow.rs:10:6 --> $DIR/trivial-bounds-inconsistent-copy-reborrow.rs:10:6
@ -18,7 +18,7 @@ LL | {*t}
help: consider changing this to be a mutable reference help: consider changing this to be a mutable reference
| |
LL | fn copy_reborrow_mut<'a>(t: &'a mut &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy { LL | fn copy_reborrow_mut<'a>(t: &'a mut &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy {
| ~~~~~~~~~~~~~~~~~~~ | +++
error: aborting due to 2 previous errors error: aborting due to 2 previous errors