Include lifetime in mutability suggestion in NLL messages
This commit is contained in:
parent
70cac59031
commit
c883edfbc6
@ -307,7 +307,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||||||
let local_decl = &self.mir.local_decls[*local];
|
let local_decl = &self.mir.local_decls[*local];
|
||||||
let suggestion = match local_decl.is_user_variable.as_ref().unwrap() {
|
let suggestion = match local_decl.is_user_variable.as_ref().unwrap() {
|
||||||
ClearCrossCrate::Set(mir::BindingForm::ImplicitSelf) => {
|
ClearCrossCrate::Set(mir::BindingForm::ImplicitSelf) => {
|
||||||
Some(suggest_ampmut_self(local_decl))
|
Some(suggest_ampmut_self(self.tcx, local_decl))
|
||||||
}
|
}
|
||||||
|
|
||||||
ClearCrossCrate::Set(mir::BindingForm::Var(mir::VarBindingForm {
|
ClearCrossCrate::Set(mir::BindingForm::Var(mir::VarBindingForm {
|
||||||
@ -418,8 +418,22 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn suggest_ampmut_self<'cx, 'gcx, 'tcx>(local_decl: &mir::LocalDecl<'tcx>) -> (Span, String) {
|
fn suggest_ampmut_self<'cx, 'gcx, 'tcx>(
|
||||||
(local_decl.source_info.span, "&mut self".to_string())
|
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
|
||||||
|
local_decl: &mir::LocalDecl<'tcx>,
|
||||||
|
) -> (Span, String) {
|
||||||
|
let sp = local_decl.source_info.span;
|
||||||
|
(sp, match tcx.sess.codemap().span_to_snippet(sp) {
|
||||||
|
Ok(snippet) => {
|
||||||
|
let lt_pos = snippet.find('\'');
|
||||||
|
if let Some(lt_pos) = lt_pos {
|
||||||
|
format!("&{}mut self", &snippet[lt_pos..snippet.len() - 4])
|
||||||
|
} else {
|
||||||
|
"&mut self".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => "&mut self".to_string()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// When we want to suggest a user change a local variable to be a `&mut`, there
|
// When we want to suggest a user change a local variable to be a `&mut`, there
|
||||||
@ -447,9 +461,15 @@ fn suggest_ampmut<'cx, 'gcx, 'tcx>(
|
|||||||
let locations = mir.find_assignments(local);
|
let locations = mir.find_assignments(local);
|
||||||
if locations.len() > 0 {
|
if locations.len() > 0 {
|
||||||
let assignment_rhs_span = mir.source_info(locations[0]).span;
|
let assignment_rhs_span = mir.source_info(locations[0]).span;
|
||||||
let snippet = tcx.sess.codemap().span_to_snippet(assignment_rhs_span);
|
if let Ok(src) = tcx.sess.codemap().span_to_snippet(assignment_rhs_span) {
|
||||||
if let Ok(src) = snippet {
|
if let (true, Some(ws_pos)) = (
|
||||||
if src.starts_with('&') {
|
src.starts_with("&'"),
|
||||||
|
src.find(|c: char| -> bool { c.is_whitespace() }),
|
||||||
|
) {
|
||||||
|
let lt_name = &src[1..ws_pos];
|
||||||
|
let ty = &src[ws_pos..];
|
||||||
|
return (assignment_rhs_span, format!("&{} mut {}", lt_name, ty));
|
||||||
|
} else if src.starts_with('&') {
|
||||||
let borrowed_expr = src[1..].to_string();
|
let borrowed_expr = src[1..].to_string();
|
||||||
return (assignment_rhs_span, format!("&mut {}", borrowed_expr));
|
return (assignment_rhs_span, format!("&mut {}", borrowed_expr));
|
||||||
}
|
}
|
||||||
@ -466,13 +486,25 @@ fn suggest_ampmut<'cx, 'gcx, 'tcx>(
|
|||||||
None => local_decl.source_info.span,
|
None => local_decl.source_info.span,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if let Ok(src) = tcx.sess.codemap().span_to_snippet(highlight_span) {
|
||||||
|
if let (true, Some(ws_pos)) = (
|
||||||
|
src.starts_with("&'"),
|
||||||
|
src.find(|c: char| -> bool { c.is_whitespace() }),
|
||||||
|
) {
|
||||||
|
let lt_name = &src[1..ws_pos];
|
||||||
|
let ty = &src[ws_pos..];
|
||||||
|
return (highlight_span, format!("&{} mut{}", lt_name, ty));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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::MutImmutable);
|
assert_eq!(ty_mut.mutbl, hir::MutImmutable);
|
||||||
if local_decl.ty.is_region_ptr() {
|
(highlight_span,
|
||||||
(highlight_span, format!("&mut {}", ty_mut.ty))
|
if local_decl.ty.is_region_ptr() {
|
||||||
} else {
|
format!("&mut {}", ty_mut.ty)
|
||||||
(highlight_span, format!("*mut {}", ty_mut.ty))
|
} else {
|
||||||
}
|
format!("*mut {}", ty_mut.ty)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_closure_or_generator(ty: ty::Ty) -> bool {
|
fn is_closure_or_generator(ty: ty::Ty) -> bool {
|
||||||
|
@ -10,7 +10,7 @@ error[E0596]: cannot borrow `self.x` as mutable, as it is behind a `&` reference
|
|||||||
--> $DIR/issue-39544.rs:26:17
|
--> $DIR/issue-39544.rs:26:17
|
||||||
|
|
|
|
||||||
LL | fn foo<'z>(&'z self) {
|
LL | fn foo<'z>(&'z self) {
|
||||||
| -------- help: consider changing this to be a mutable reference: `&mut self`
|
| -------- help: consider changing this to be a mutable reference: `&'z mut self`
|
||||||
LL | let _ = &mut self.x; //~ ERROR cannot borrow
|
LL | let _ = &mut self.x; //~ ERROR cannot borrow
|
||||||
| ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
| ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ error[E0596]: cannot borrow `self.x` as mutable, as it is behind a `&` reference
|
|||||||
--> $DIR/issue-39544.rs:35:17
|
--> $DIR/issue-39544.rs:35:17
|
||||||
|
|
|
|
||||||
LL | fn foo2<'a>(&'a self, other: &Z) {
|
LL | fn foo2<'a>(&'a self, other: &Z) {
|
||||||
| -------- help: consider changing this to be a mutable reference: `&mut self`
|
| -------- help: consider changing this to be a mutable reference: `&'a mut self`
|
||||||
LL | let _ = &mut self.x; //~ ERROR cannot borrow
|
LL | let _ = &mut self.x; //~ ERROR cannot borrow
|
||||||
| ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
| ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ error[E0596]: cannot borrow `self.x` as mutable, as it is behind a `&` reference
|
|||||||
--> $DIR/issue-39544.rs:40:17
|
--> $DIR/issue-39544.rs:40:17
|
||||||
|
|
|
|
||||||
LL | fn foo3<'a>(self: &'a Self, other: &Z) {
|
LL | fn foo3<'a>(self: &'a Self, other: &Z) {
|
||||||
| -------- help: consider changing this to be a mutable reference: `&mut Z`
|
| -------- help: consider changing this to be a mutable reference: `&'a mut Self`
|
||||||
LL | let _ = &mut self.x; //~ ERROR cannot borrow
|
LL | let _ = &mut self.x; //~ ERROR cannot borrow
|
||||||
| ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
| ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
|
|||||||
--> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:102:5
|
--> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:102:5
|
||||||
|
|
|
|
||||||
LL | fn assign_field2<'a>(x: &'a Own<Point>) {
|
LL | fn assign_field2<'a>(x: &'a Own<Point>) {
|
||||||
| -------------- help: consider changing this to be a mutable reference: `&mut Own<Point>`
|
| -------------- help: consider changing this to be a mutable reference: `&'a mut Own<Point>`
|
||||||
LL | x.y = 3; //~ ERROR cannot borrow
|
LL | x.y = 3; //~ ERROR cannot borrow
|
||||||
| ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
| ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
|
|||||||
--> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:143:6
|
--> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:143:6
|
||||||
|
|
|
|
||||||
LL | fn assign_method2<'a>(x: &'a Own<Point>) {
|
LL | fn assign_method2<'a>(x: &'a Own<Point>) {
|
||||||
| -------------- help: consider changing this to be a mutable reference: `&mut Own<Point>`
|
| -------------- help: consider changing this to be a mutable reference: `&'a mut Own<Point>`
|
||||||
LL | *x.y_mut() = 3; //~ ERROR cannot borrow
|
LL | *x.y_mut() = 3; //~ ERROR cannot borrow
|
||||||
| ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
| ^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
|
|||||||
--> $DIR/borrowck-borrow-overloaded-deref-mut.rs:51:11
|
--> $DIR/borrowck-borrow-overloaded-deref-mut.rs:51:11
|
||||||
|
|
|
|
||||||
LL | fn deref_extend_mut1<'a>(x: &'a Own<isize>) -> &'a mut isize {
|
LL | fn deref_extend_mut1<'a>(x: &'a Own<isize>) -> &'a mut isize {
|
||||||
| -------------- help: consider changing this to be a mutable reference: `&mut Own<isize>`
|
| -------------- help: consider changing this to be a mutable reference: `&'a mut Own<isize>`
|
||||||
LL | &mut **x //~ ERROR cannot borrow
|
LL | &mut **x //~ ERROR cannot borrow
|
||||||
| ^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
| ^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ error[E0596]: cannot borrow `*x` as mutable, as it is behind a `&` reference
|
|||||||
--> $DIR/borrowck-borrow-overloaded-deref-mut.rs:63:6
|
--> $DIR/borrowck-borrow-overloaded-deref-mut.rs:63:6
|
||||||
|
|
|
|
||||||
LL | fn assign2<'a>(x: &'a Own<isize>) {
|
LL | fn assign2<'a>(x: &'a Own<isize>) {
|
||||||
| -------------- help: consider changing this to be a mutable reference: `&mut Own<isize>`
|
| -------------- help: consider changing this to be a mutable reference: `&'a mut Own<isize>`
|
||||||
LL | **x = 3; //~ ERROR cannot borrow
|
LL | **x = 3; //~ ERROR cannot borrow
|
||||||
| ^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
| ^^ `x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ error[E0596]: cannot borrow `*a` as mutable, as it is behind a `&` reference
|
|||||||
--> $DIR/mut-arg-hint.rs:18:5
|
--> $DIR/mut-arg-hint.rs:18:5
|
||||||
|
|
|
|
||||||
LL | pub fn foo<'a>(mut a: &'a String) {
|
LL | pub fn foo<'a>(mut a: &'a String) {
|
||||||
| ---------- help: consider changing this to be a mutable reference: `&mut std::string::String`
|
| ---------- help: consider changing this to be a mutable reference: `&'a mut String`
|
||||||
LL | a.push_str("foo"); //~ ERROR cannot borrow immutable borrowed content
|
LL | a.push_str("foo"); //~ ERROR cannot borrow immutable borrowed content
|
||||||
| ^ `a` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
| ^ `a` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ error[E0596]: cannot borrow `**t` as mutable, as it is behind a `&` reference
|
|||||||
--> $DIR/trivial-bounds-inconsistent-copy-reborrow.rs:16:5
|
--> $DIR/trivial-bounds-inconsistent-copy-reborrow.rs:16:5
|
||||||
|
|
|
|
||||||
LL | fn reborrow_mut<'a>(t: &'a &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy {
|
LL | fn reborrow_mut<'a>(t: &'a &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy {
|
||||||
| --------------- help: consider changing this to be a mutable reference: `&mut &mut i32`
|
| --------------- help: consider changing this to be a mutable reference: `&'a mut &'a mut i32`
|
||||||
LL | *t //~ ERROR
|
LL | *t //~ ERROR
|
||||||
| ^^ `t` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
| ^^ `t` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
||||||
|
|
||||||
@ -10,7 +10,7 @@ error[E0596]: cannot borrow `**t` as mutable, as it is behind a `&` reference
|
|||||||
--> $DIR/trivial-bounds-inconsistent-copy-reborrow.rs:20:6
|
--> $DIR/trivial-bounds-inconsistent-copy-reborrow.rs:20:6
|
||||||
|
|
|
|
||||||
LL | fn copy_reborrow_mut<'a>(t: &'a &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy {
|
LL | fn copy_reborrow_mut<'a>(t: &'a &'a mut i32) -> &'a mut i32 where &'a mut i32: Copy {
|
||||||
| --------------- help: consider changing this to be a mutable reference: `&mut &mut i32`
|
| --------------- help: consider changing this to be a mutable reference: `&'a mut &'a mut i32`
|
||||||
LL | {*t} //~ ERROR
|
LL | {*t} //~ ERROR
|
||||||
| ^^ `t` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
| ^^ `t` is a `&` reference, so the data it refers to cannot be borrowed as mutable
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user