Skip to content

Commit b6616b6

Browse files
committed
tweak "make mut" spans (No. 2)
1 parent e97789d commit b6616b6

File tree

7 files changed

+36
-30
lines changed

7 files changed

+36
-30
lines changed

compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,35 +1241,41 @@ fn suggest_ampmut<'tcx>(
12411241
}
12421242
}
12431243

1244-
let (suggestibility, highlight_span) = match opt_ty_info {
1244+
let (binding_exists, span) = match opt_ty_info {
12451245
// if this is a variable binding with an explicit type,
1246-
// try to highlight that for the suggestion.
1246+
// then we will suggest changing it to be mutable.
1247+
// this is `Applicability::MachineApplicable`.
12471248
Some(ty_span) => (true, ty_span),
12481249

1249-
// otherwise, just highlight the span associated with
1250-
// the (MIR) LocalDecl.
1250+
// otherwise, we'll suggest *adding* an annotated type, we'll suggest
1251+
// the RHS's type for that.
1252+
// this is `Applicability::HasPlaceholders`.
12511253
None => (false, local_decl.source_info.span),
12521254
};
12531255

1254-
if let Ok(src) = tcx.sess.source_map().span_to_snippet(highlight_span)
1255-
&& let (true, Some(ws_pos)) = (src.starts_with("&'"), src.find(char::is_whitespace))
1256+
// if the binding already exists and is a reference with a explicit
1257+
// lifetime, then we can suggest adding ` mut`. this is special-cased from
1258+
// the path without a explicit lifetime.
1259+
if let Ok(src) = tcx.sess.source_map().span_to_snippet(span)
1260+
&& src.starts_with("&'")
1261+
// note that `& 'a T` is invalid so this is correct.
1262+
&& let Some(ws_pos) = src.find(char::is_whitespace)
12561263
{
1257-
let lt_name = &src[1..ws_pos];
1258-
let ty = &src[ws_pos..];
1259-
return (true, highlight_span, format!("&{lt_name} mut{ty}"));
1264+
let span = span.with_lo(span.lo() + BytePos(ws_pos as u32)).shrink_to_lo();
1265+
(true, span, " mut".to_owned())
1266+
} else {
1267+
let ty_mut = local_decl.ty.builtin_deref(true).unwrap();
1268+
assert_eq!(ty_mut.mutbl, hir::Mutability::Not);
1269+
(
1270+
binding_exists,
1271+
span,
1272+
if local_decl.ty.is_ref() {
1273+
format!("&mut {}", ty_mut.ty)
1274+
} else {
1275+
format!("*mut {}", ty_mut.ty)
1276+
},
1277+
)
12601278
}
1261-
1262-
let ty_mut = local_decl.ty.builtin_deref(true).unwrap();
1263-
assert_eq!(ty_mut.mutbl, hir::Mutability::Not);
1264-
(
1265-
suggestibility,
1266-
highlight_span,
1267-
if local_decl.ty.is_ref() {
1268-
format!("&mut {}", ty_mut.ty)
1269-
} else {
1270-
format!("*mut {}", ty_mut.ty)
1271-
},
1272-
)
12731279
}
12741280

12751281
fn is_closure_or_generator(ty: Ty<'_>) -> bool {

tests/ui/did_you_mean/issue-39544.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ LL | let _ = &mut self.x;
7373
help: consider changing this to be a mutable reference
7474
|
7575
LL | fn foo3<'a>(self: &'a mut Self, other: &Z) {
76-
| ~~~~~~~~~~~~
76+
| +++
7777

7878
error[E0596]: cannot borrow `other.x` as mutable, as it is behind a `&` reference
7979
--> $DIR/issue-39544.rs:31:17

tests/ui/issues/issue-61623.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | f2(|| x.0, f1(x.1))
77
help: consider changing this to be a mutable reference
88
|
99
LL | fn f3<'a>(x: &'a mut ((), &'a mut ())) {
10-
| ~~~~~~~~~~~~~~~~~~~~~~~~
10+
| +++
1111

1212
error: aborting due to previous error
1313

tests/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ LL | x.y = 3;
5050
help: consider changing this to be a mutable reference
5151
|
5252
LL | fn assign_field2<'a>(x: &'a mut Own<Point>) {
53-
| ~~~~~~~~~~~~~~~~~~
53+
| +++
5454

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

109109
error: aborting due to 10 previous errors
110110

tests/ui/span/borrowck-borrow-overloaded-deref-mut.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ LL | &mut **x
1818
help: consider changing this to be a mutable reference
1919
|
2020
LL | fn deref_extend_mut1<'a>(x: &'a mut Own<isize>) -> &'a mut isize {
21-
| ~~~~~~~~~~~~~~~~~~
21+
| +++
2222

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

4545
error: aborting due to 4 previous errors
4646

tests/ui/span/mut-arg-hint.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ LL | a.push_str("foo");
1818
help: consider changing this to be a mutable reference
1919
|
2020
LL | pub fn foo<'a>(mut a: &'a mut String) {
21-
| ~~~~~~~~~~~~~~
21+
| +++
2222

2323
error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference
2424
--> $DIR/mut-arg-hint.rs:15:9

tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy-reborrow.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | *t
77
help: consider changing this to be a mutable reference
88
|
99
LL | fn reborrow_mut<'a>(t: &'a mut &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy {
10-
| ~~~~~~~~~~~~~~~~~~~
10+
| +++
1111

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

2323
error: aborting due to 2 previous errors
2424

0 commit comments

Comments
 (0)