diff --git a/src/librustc/hir/map/blocks.rs b/src/librustc/hir/map/blocks.rs index 91e88e2c73ff892947f387eff7f606cbbfc1a94f..ff2f1dc1ba28a85f83f67d795c56ed2f50cfeaa5 100644 --- a/src/librustc/hir/map/blocks.rs +++ b/src/librustc/hir/map/blocks.rs @@ -38,7 +38,7 @@ /// - The default implementation for a trait method. /// /// To construct one, use the `Code::from_node` function. -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] pub struct FnLikeNode<'a> { node: map::Node<'a> } /// MaybeFnLike wraps a method that indicates if an object diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 955bec00433129db7e703f92395134f402604957..dca85d7727a77d8add7bf612fc4877be2591ccf2 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -194,6 +194,63 @@ pub struct cmt_<'tcx> { pub type cmt<'tcx> = Rc>; +impl<'tcx> cmt_<'tcx> { + pub fn get_field(&self, name: ast::Name) -> Option { + match self.cat { + Categorization::Deref(ref cmt, ..) | + Categorization::Interior(ref cmt, _) | + Categorization::Downcast(ref cmt, _) => { + if let Categorization::Local(_) = cmt.cat { + if let ty::TyAdt(def, _) = self.ty.sty { + return def.struct_variant().find_field_named(name).map(|x| x.did); + } + None + } else { + cmt.get_field(name) + } + } + _ => None + } + } + + pub fn get_field_name(&self) -> Option { + match self.cat { + Categorization::Interior(_, ref ik) => { + if let InteriorKind::InteriorField(FieldName::NamedField(name)) = *ik { + Some(name) + } else { + None + } + } + Categorization::Deref(ref cmt, ..) | + Categorization::Downcast(ref cmt, _) => { + cmt.get_field_name() + } + _ => None, + } + } + + pub fn get_arg_if_immutable(&self, map: &hir_map::Map) -> Option { + match self.cat { + Categorization::Deref(ref cmt, ..) | + Categorization::Interior(ref cmt, _) | + Categorization::Downcast(ref cmt, _) => { + if let Categorization::Local(nid) = cmt.cat { + if let ty::TyAdt(_, _) = self.ty.sty { + if let ty::TyRef(_, ty::TypeAndMut{mutbl: MutImmutable, ..}) = cmt.ty.sty { + return Some(nid); + } + } + None + } else { + cmt.get_arg_if_immutable(map) + } + } + _ => None + } + } +} + pub trait ast_node { fn id(&self) -> ast::NodeId; fn span(&self) -> Span; diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 5681e8c7766231c2201c591a13cc694fb73aba38..36fc5149b40d8de66d41539e33013093c21eb45d 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1325,6 +1325,7 @@ pub fn for_item(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: NodeId) } } +#[derive(Debug)] pub struct VariantDef { /// The variant's DefId. If this is a tuple-like struct, /// this is the DefId of the struct's ctor. @@ -1335,6 +1336,7 @@ pub struct VariantDef { pub ctor_kind: CtorKind, } +#[derive(Debug)] pub struct FieldDef { pub did: DefId, pub name: Name, diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index b02bb7c6e4dd803f17d796604d63d3193d9a5105..d6164e69ffd3a9656fea55571ac0e4209f011d12 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -134,7 +134,7 @@ pub enum TypeVariants<'tcx> { TyRawPtr(TypeAndMut<'tcx>), /// A reference; a pointer with an associated lifetime. Written as - /// `&a mut T` or `&'a T`. + /// `&'a mut T` or `&'a T`. TyRef(&'tcx Region, TypeAndMut<'tcx>), /// The anonymous type of a function declaration/definition. Each diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index 7f7f73d9a9678e45ab6e39c44087428b5836c78c..1783ca74a25923fdf4fcad56f6b5a29c75e93788 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -195,7 +195,8 @@ fn check_aliasability<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, bccx.report_aliasability_violation( borrow_span, loan_cause, - mc::AliasableReason::UnaliasableImmutable); + mc::AliasableReason::UnaliasableImmutable, + cmt); Err(()) } (mc::Aliasability::FreelyAliasable(alias_cause), ty::UniqueImmBorrow) | @@ -203,7 +204,8 @@ fn check_aliasability<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, bccx.report_aliasability_violation( borrow_span, loan_cause, - alias_cause); + alias_cause, + cmt); Err(()) } (..) => { diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 4a92578fed512672a8ce20579bd3e4aad17b8f93..4ce6c9527571e3f505b9fd512cd06254f7c3032b 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -540,7 +540,7 @@ pub fn opt_loan_path<'tcx>(cmt: &mc::cmt<'tcx>) -> Option>> { // Errors // Errors that can occur -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub enum bckerr_code<'tcx> { err_mutbl, /// superscope, subscope, loan cause @@ -550,7 +550,7 @@ pub enum bckerr_code<'tcx> { // Combination of an error code and the categorization of the expression // that caused it -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub struct BckError<'tcx> { span: Span, cause: AliasableViolationKind, @@ -601,12 +601,8 @@ pub fn report(&self, err: BckError<'tcx>) { _ => { } } - // General fallback. - let span = err.span.clone(); - let mut db = self.struct_span_err( - err.span, - &self.bckerr_to_string(&err)); - self.note_and_explain_bckerr(&mut db, err, span); + let mut db = self.bckerr_to_diag(&err); + self.note_and_explain_bckerr(&mut db, err); db.emit(); } @@ -771,8 +767,11 @@ pub fn span_err_with_code>(&self, s: S, msg: &str, code: &str self.tcx.sess.span_err_with_code(s, msg, code); } - pub fn bckerr_to_string(&self, err: &BckError<'tcx>) -> String { - match err.code { + pub fn bckerr_to_diag(&self, err: &BckError<'tcx>) -> DiagnosticBuilder<'a> { + let span = err.span.clone(); + let mut immutable_field = None; + + let msg = &match err.code { err_mutbl => { let descr = match err.cmt.note { mc::NoteClosureEnv(_) | mc::NoteUpvarRef(_) => { @@ -783,6 +782,7 @@ pub fn bckerr_to_string(&self, err: &BckError<'tcx>) -> String { format!("{} {}", err.cmt.mutbl.to_user_str(), self.cmt_to_string(&err.cmt)) + } Some(lp) => { format!("{} {} `{}`", @@ -807,6 +807,19 @@ pub fn bckerr_to_string(&self, err: &BckError<'tcx>) -> String { BorrowViolation(euv::AutoUnsafe) | BorrowViolation(euv::ForLoop) | BorrowViolation(euv::MatchDiscriminant) => { + // Check for this field's definition to see if it is an immutable reference + // and suggest making it mutable if that is the case. + immutable_field = err.cmt.get_field_name() + .and_then(|name| err.cmt.get_field(name)) + .and_then(|did| self.tcx.hir.as_local_node_id(did)) + .and_then(|nid| { + if let hir_map::Node::NodeField(ref field) = self.tcx.hir.get(nid) { + return self.suggest_mut_for_immutable(&field.ty) + .map(|msg| (self.tcx.hir.span(nid), msg)); + } + None + }); + format!("cannot borrow {} as mutable", descr) } BorrowViolation(euv::ClosureInvocation) => { @@ -830,13 +843,20 @@ pub fn bckerr_to_string(&self, err: &BckError<'tcx>) -> String { its contents can be safely reborrowed", descr) } + }; + + let mut db = self.struct_span_err(span, msg); + if let Some((span, msg)) = immutable_field { + db.span_label(span, &msg); } + db } pub fn report_aliasability_violation(&self, span: Span, kind: AliasableViolationKind, - cause: mc::AliasableReason) { + cause: mc::AliasableReason, + cmt: mc::cmt<'tcx>) { let mut is_closure = false; let prefix = match kind { MutabilityViolation => { @@ -903,6 +923,9 @@ pub fn report_aliasability_violation(&self, self.tcx.sess, span, E0389, "{} in a `&` reference", prefix); e.span_label(span, &"assignment into an immutable reference"); + if let Some(nid) = cmt.get_arg_if_immutable(&self.tcx.hir) { + self.immutable_argument_should_be_mut(nid, &mut e); + } e } }; @@ -913,6 +936,55 @@ pub fn report_aliasability_violation(&self, err.emit(); } + /// Given a type, if it is an immutable reference, return a suggestion to make it mutable + fn suggest_mut_for_immutable(&self, pty: &hir::Ty) -> Option { + // Check wether the argument is an immutable reference + if let hir::TyRptr(opt_lifetime, hir::MutTy { + mutbl: hir::Mutability::MutImmutable, + ref ty + }) = pty.node { + // Account for existing lifetimes when generating the message + if let Some(lifetime) = opt_lifetime { + if let Ok(snippet) = self.tcx.sess.codemap().span_to_snippet(ty.span) { + if let Ok(lifetime_snippet) = self.tcx.sess.codemap() + .span_to_snippet(lifetime.span) { + return Some(format!("use `&{} mut {}` here to make mutable", + lifetime_snippet, + snippet)); + } + } + } else if let Ok(snippet) = self.tcx.sess.codemap().span_to_snippet(pty.span) { + if snippet.starts_with("&") { + return Some(format!("use `{}` here to make mutable", + snippet.replace("&", "&mut "))); + } + } else { + bug!("couldn't find a snippet for span: {:?}", pty.span); + } + } + None + } + + fn immutable_argument_should_be_mut(&self, nid: ast::NodeId, db: &mut DiagnosticBuilder) { + let parent = self.tcx.hir.get_parent_node(nid); + let parent_node = self.tcx.hir.get(parent); + + // The parent node is like a fn + if let Some(fn_like) = FnLikeNode::from_node(parent_node) { + // `nid`'s parent's `Body` + let fn_body = self.tcx.hir.body(fn_like.body()); + // Get the position of `nid` in the arguments list + let arg_pos = fn_body.arguments.iter().position(|arg| arg.pat.id == nid); + if let Some(i) = arg_pos { + // The argument's `Ty` + let arg_ty = &fn_like.decl().inputs[i]; + if let Some(msg) = self.suggest_mut_for_immutable(&arg_ty) { + db.span_label(arg_ty.span, &msg); + } + } + } + } + fn report_out_of_scope_escaping_closure_capture(&self, err: &BckError<'tcx>, capture_span: Span) @@ -961,8 +1033,8 @@ fn region_end_span(&self, region: &'tcx ty::Region) -> Option { } } - pub fn note_and_explain_bckerr(&self, db: &mut DiagnosticBuilder, err: BckError<'tcx>, - error_span: Span) { + pub fn note_and_explain_bckerr(&self, db: &mut DiagnosticBuilder, err: BckError<'tcx>) { + let error_span = err.span.clone(); match err.code { err_mutbl => self.note_and_explain_mutbl_error(db, &err, &error_span), err_out_of_scope(super_scope, sub_scope, cause) => { @@ -1114,41 +1186,13 @@ fn note_and_explain_mutbl_error(&self, db: &mut DiagnosticBuilder, err: &BckErro } } _ => { - if let Categorization::Deref(ref inner_cmt, ..) = err.cmt.cat { - if let Categorization::Local(local_id) = inner_cmt.cat { - let parent = self.tcx.hir.get_parent_node(local_id); - - if let Some(fn_like) = FnLikeNode::from_node(self.tcx.hir.get(parent)) { - if let Some(i) = self.tcx.hir.body(fn_like.body()).arguments.iter() - .position(|arg| arg.pat.id == local_id) { - let arg_ty = &fn_like.decl().inputs[i]; - if let hir::TyRptr( - opt_lifetime, - hir::MutTy{mutbl: hir::Mutability::MutImmutable, ref ty}) = - arg_ty.node { - if let Some(lifetime) = opt_lifetime { - if let Ok(snippet) = self.tcx.sess.codemap() - .span_to_snippet(ty.span) { - if let Ok(lifetime_snippet) = self.tcx.sess.codemap() - .span_to_snippet(lifetime.span) { - db.span_label(arg_ty.span, - &format!("use `&{} mut {}` \ - here to make mutable", - lifetime_snippet, - snippet)); - } - } - } - else if let Ok(snippet) = self.tcx.sess.codemap() - .span_to_snippet(arg_ty.span) { - if snippet.starts_with("&") { - db.span_label(arg_ty.span, - &format!("use `{}` here to make mutable", - snippet.replace("&", "&mut "))); - } - } - } - } + if let Categorization::Deref(..) = err.cmt.cat { + db.span_label(*error_span, &"cannot borrow as mutable"); + if let Some(local_id) = err.cmt.get_arg_if_immutable(&self.tcx.hir) { + self.immutable_argument_should_be_mut(local_id, db); + } else if let Categorization::Deref(ref inner_cmt, ..) = err.cmt.cat { + if let Categorization::Local(local_id) = inner_cmt.cat { + self.immutable_argument_should_be_mut(local_id, db); } } } else if let Categorization::Local(local_id) = err.cmt.cat { diff --git a/src/test/ui/did_you_mean/issue-38147-1.rs b/src/test/ui/did_you_mean/issue-38147-1.rs new file mode 100644 index 0000000000000000000000000000000000000000..136921dd0a5694838942d8db7f255bc3b92cbabe --- /dev/null +++ b/src/test/ui/did_you_mean/issue-38147-1.rs @@ -0,0 +1,31 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct Pass<'a> { + s: &'a mut String +} + +impl<'a> Pass<'a> { + fn f(&mut self) { + self.s.push('x'); + } +} + +struct Foo<'a> { + s: &'a mut String +} + +impl<'a> Foo<'a> { + fn f(&self) { + self.s.push('x'); + } +} + +fn main() {} diff --git a/src/test/ui/did_you_mean/issue-38147-1.stderr b/src/test/ui/did_you_mean/issue-38147-1.stderr new file mode 100644 index 0000000000000000000000000000000000000000..e9f2b1dad806d52429b48060b5a1136315856584 --- /dev/null +++ b/src/test/ui/did_you_mean/issue-38147-1.stderr @@ -0,0 +1,10 @@ +error[E0389]: cannot borrow data mutably in a `&` reference + --> $DIR/issue-38147-1.rs:27:9 + | +26 | fn f(&self) { + | ----- use `&mut self` here to make mutable +27 | self.s.push('x'); + | ^^^^^^ assignment into an immutable reference + +error: aborting due to previous error + diff --git a/src/test/ui/did_you_mean/issue-38147-2.rs b/src/test/ui/did_you_mean/issue-38147-2.rs new file mode 100644 index 0000000000000000000000000000000000000000..a5d533edf75ecdc61ca80bfadf27eeaf9dedd57f --- /dev/null +++ b/src/test/ui/did_you_mean/issue-38147-2.rs @@ -0,0 +1,21 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct Bar<'a> { + s: &'a String +} + +impl<'a> Bar<'a> { + fn f(&mut self) { + self.s.push('x'); + } +} + +fn main() {} diff --git a/src/test/ui/did_you_mean/issue-38147-2.stderr b/src/test/ui/did_you_mean/issue-38147-2.stderr new file mode 100644 index 0000000000000000000000000000000000000000..fdaf0cd44d9d4626900657bba701823726b49b76 --- /dev/null +++ b/src/test/ui/did_you_mean/issue-38147-2.stderr @@ -0,0 +1,11 @@ +error: cannot borrow immutable borrowed content `*self.s` as mutable + --> $DIR/issue-38147-2.rs:17:9 + | +12 | s: &'a String + | ------------- use `&'a mut String` here to make mutable +... +17 | self.s.push('x'); + | ^^^^^^ cannot borrow as mutable + +error: aborting due to previous error + diff --git a/src/test/ui/did_you_mean/issue-38147-3.rs b/src/test/ui/did_you_mean/issue-38147-3.rs new file mode 100644 index 0000000000000000000000000000000000000000..5e8f2d3eaefaab67f3e7e65da458141a083d1b5a --- /dev/null +++ b/src/test/ui/did_you_mean/issue-38147-3.rs @@ -0,0 +1,21 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct Qux<'a> { + s: &'a String +} + +impl<'a> Qux<'a> { + fn f(&self) { + self.s.push('x'); + } +} + +fn main() {} diff --git a/src/test/ui/did_you_mean/issue-38147-3.stderr b/src/test/ui/did_you_mean/issue-38147-3.stderr new file mode 100644 index 0000000000000000000000000000000000000000..d2280fa561bdeb12cf049731f2c2f7c83104692d --- /dev/null +++ b/src/test/ui/did_you_mean/issue-38147-3.stderr @@ -0,0 +1,13 @@ +error: cannot borrow immutable borrowed content `*self.s` as mutable + --> $DIR/issue-38147-3.rs:17:9 + | +12 | s: &'a String + | ------------- use `&'a mut String` here to make mutable +... +16 | fn f(&self) { + | ----- use `&mut self` here to make mutable +17 | self.s.push('x'); + | ^^^^^^ cannot borrow as mutable + +error: aborting due to previous error + diff --git a/src/test/ui/did_you_mean/issue-38147-4.rs b/src/test/ui/did_you_mean/issue-38147-4.rs new file mode 100644 index 0000000000000000000000000000000000000000..4eb20ceeed48e50a1b32f8204dafe21e97279bc8 --- /dev/null +++ b/src/test/ui/did_you_mean/issue-38147-4.rs @@ -0,0 +1,19 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct Foo<'a> { + s: &'a mut String +} + +fn f(x: usize, f: &Foo) { + f.s.push('x'); +} + +fn main() {} diff --git a/src/test/ui/did_you_mean/issue-38147-4.stderr b/src/test/ui/did_you_mean/issue-38147-4.stderr new file mode 100644 index 0000000000000000000000000000000000000000..9a8853f4fbbdb15dfe2bfa8330db4c5b4d4e8344 --- /dev/null +++ b/src/test/ui/did_you_mean/issue-38147-4.stderr @@ -0,0 +1,10 @@ +error[E0389]: cannot borrow data mutably in a `&` reference + --> $DIR/issue-38147-4.rs:16:5 + | +15 | fn f(x: usize, f: &Foo) { + | ---- use `&mut Foo` here to make mutable +16 | f.s.push('x'); + | ^^^ assignment into an immutable reference + +error: aborting due to previous error + diff --git a/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr b/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr index 1109351bff8394e2393388777f27304478173e67..b83a6aaebf3232026db99be66a7af5d9ebccf1e6 100644 --- a/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr +++ b/src/test/ui/span/borrowck-borrow-overloaded-auto-deref-mut.stderr @@ -12,7 +12,7 @@ error: cannot borrow immutable borrowed content `*x` as mutable 74 | fn deref_extend_mut_field1(x: &Own) -> &mut isize { | ----------- use `&mut Own` here to make mutable 75 | &mut x.y //~ ERROR cannot borrow - | ^ + | ^ cannot borrow as mutable error[E0499]: cannot borrow `*x` as mutable more than once at a time --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:88:19 @@ -38,7 +38,7 @@ error: cannot borrow immutable borrowed content `*x` as mutable 101 | fn assign_field2<'a>(x: &'a Own) { | -------------- use `&'a mut Own` here to make mutable 102 | x.y = 3; //~ ERROR cannot borrow - | ^ + | ^ cannot borrow as mutable error[E0499]: cannot borrow `*x` as mutable more than once at a time --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:111:5 @@ -64,7 +64,7 @@ error: cannot borrow immutable borrowed content `*x` as mutable 130 | fn deref_extend_mut_method1(x: &Own) -> &mut isize { | ----------- use `&mut Own` here to make mutable 131 | x.y_mut() //~ ERROR cannot borrow - | ^ + | ^ cannot borrow as mutable error: cannot borrow immutable argument `x` as mutable --> $DIR/borrowck-borrow-overloaded-auto-deref-mut.rs:139:6 @@ -80,7 +80,7 @@ error: cannot borrow immutable borrowed content `*x` as mutable 142 | fn assign_method2<'a>(x: &'a Own) { | -------------- use `&'a mut Own` here to make mutable 143 | *x.y_mut() = 3; //~ ERROR cannot borrow - | ^ + | ^ cannot borrow as mutable error: aborting due to 10 previous errors diff --git a/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr b/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr index a5b70459161415f7d5b01061e6a8fb99f0e3a947..af954a4d7924f1bada77d8e0be10738ad34af0dc 100644 --- a/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr +++ b/src/test/ui/span/borrowck-borrow-overloaded-deref-mut.stderr @@ -12,7 +12,7 @@ error: cannot borrow immutable borrowed content `*x` as mutable 50 | fn deref_extend_mut1<'a>(x: &'a Own) -> &'a mut isize { | -------------- use `&'a mut Own` here to make mutable 51 | &mut **x //~ ERROR cannot borrow - | ^^ + | ^^ cannot borrow as mutable error: cannot borrow immutable argument `x` as mutable --> $DIR/borrowck-borrow-overloaded-deref-mut.rs:59:6 @@ -28,7 +28,7 @@ error: cannot borrow immutable borrowed content `*x` as mutable 62 | fn assign2<'a>(x: &'a Own) { | -------------- use `&'a mut Own` here to make mutable 63 | **x = 3; //~ ERROR cannot borrow - | ^^ + | ^^ cannot borrow as mutable error: aborting due to 4 previous errors diff --git a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr index 16bb60013674fded9dff9fa8c615eeaec9f2b1e7..f2f0e027f0161927da53cdb4f77f8dfe8e445a53 100644 --- a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr +++ b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.stderr @@ -17,13 +17,15 @@ error: cannot borrow immutable borrowed content `*f` as mutable 35 | fn test2(f: &F) where F: FnMut() { | -- use `&mut F` here to make mutable 36 | (*f)(); //~ ERROR: cannot borrow immutable borrowed content `*f` as mutable - | ^^^^ + | ^^^^ cannot borrow as mutable error: cannot borrow immutable `Box` content `*f.f` as mutable --> $DIR/borrowck-call-is-borrow-issue-12224.rs:44:5 | +43 | fn test4(f: &Test) { + | ----- use `&mut Test` here to make mutable 44 | f.f.call_mut(()) //~ ERROR: cannot borrow immutable `Box` content `*f.f` as mutable - | ^^^ + | ^^^ cannot borrow as mutable error[E0504]: cannot move `f` into closure because it is borrowed --> $DIR/borrowck-call-is-borrow-issue-12224.rs:63:13 diff --git a/src/test/ui/span/borrowck-call-method-from-mut-aliasable.stderr b/src/test/ui/span/borrowck-call-method-from-mut-aliasable.stderr index a1af1ca7408a280a8545fabc3a931e366f44ae81..2349bfaf75e6f4fe37c3fde7703a554142b6ad4a 100644 --- a/src/test/ui/span/borrowck-call-method-from-mut-aliasable.stderr +++ b/src/test/ui/span/borrowck-call-method-from-mut-aliasable.stderr @@ -5,7 +5,7 @@ error: cannot borrow immutable borrowed content `*x` as mutable | ---- use `&mut Foo` here to make mutable 26 | x.f(); 27 | x.h(); //~ ERROR cannot borrow - | ^ + | ^ cannot borrow as mutable error: aborting due to previous error diff --git a/src/test/ui/span/borrowck-fn-in-const-b.stderr b/src/test/ui/span/borrowck-fn-in-const-b.stderr index 41f549c708a29577fb5f6455adff14ebad554d49..251a9e4aa57555730d0a988b08fd59cf839cd035 100644 --- a/src/test/ui/span/borrowck-fn-in-const-b.stderr +++ b/src/test/ui/span/borrowck-fn-in-const-b.stderr @@ -4,7 +4,7 @@ error: cannot borrow immutable borrowed content `*x` as mutable 16 | fn broken(x: &Vec) { | ------------ use `&mut Vec` here to make mutable 17 | x.push(format!("this is broken")); - | ^ + | ^ cannot borrow as mutable error: aborting due to previous error diff --git a/src/test/ui/span/borrowck-object-mutability.stderr b/src/test/ui/span/borrowck-object-mutability.stderr index 32e4da18056ff58f2a7b8c0cb54791da9f5a5dbe..4ef1cb9c239e4ba3fe0ee5ce5a944714c8689ed4 100644 --- a/src/test/ui/span/borrowck-object-mutability.stderr +++ b/src/test/ui/span/borrowck-object-mutability.stderr @@ -5,13 +5,13 @@ error: cannot borrow immutable borrowed content `*x` as mutable | ---- use `&mut Foo` here to make mutable 18 | x.borrowed(); 19 | x.borrowed_mut(); //~ ERROR cannot borrow - | ^ + | ^ cannot borrow as mutable error: cannot borrow immutable `Box` content `*x` as mutable --> $DIR/borrowck-object-mutability.rs:29:5 | 29 | x.borrowed_mut(); //~ ERROR cannot borrow - | ^ + | ^ cannot borrow as mutable error: aborting due to 2 previous errors diff --git a/src/test/ui/span/mut-arg-hint.stderr b/src/test/ui/span/mut-arg-hint.stderr index 58f66c1358437132e9236fb7a0c6b3e677bcd297..e4ed062214715a823bc4ca1613bd4fab2a04a0cf 100644 --- a/src/test/ui/span/mut-arg-hint.stderr +++ b/src/test/ui/span/mut-arg-hint.stderr @@ -4,7 +4,7 @@ error: cannot borrow immutable borrowed content `*a` as mutable 17 | pub fn foo<'a>(mut a: &'a String) { | ---------- use `&'a mut String` here to make mutable 18 | a.push_str("foo"); - | ^ + | ^ cannot borrow as mutable error: cannot borrow immutable borrowed content `*a` as mutable --> $DIR/mut-arg-hint.rs:13:9 @@ -12,7 +12,7 @@ error: cannot borrow immutable borrowed content `*a` as mutable 12 | fn foo(mut a: &String) { | ------- use `&mut String` here to make mutable 13 | a.push_str("bar"); - | ^ + | ^ cannot borrow as mutable error: cannot borrow immutable borrowed content `*a` as mutable --> $DIR/mut-arg-hint.rs:25:9 @@ -20,7 +20,7 @@ error: cannot borrow immutable borrowed content `*a` as mutable 24 | pub fn foo(mut a: &String) { | ------- use `&mut String` here to make mutable 25 | a.push_str("foo"); - | ^ + | ^ cannot borrow as mutable error: aborting due to 3 previous errors