mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 08:44:35 +00:00
Point to immutable arg/fields when trying to use as &mut
Point to immutable borrow arguments and fields when trying to use them as mutable borrows. Add label to primary span on "cannot borrow as mutable" errors. Present the following output when trying to access an immutable borrow's field as mutable: ``` 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 | f.s.push('x'); | ^^^ assignment into an immutable reference ``` And the following when trying to access an immutable struct field as mutable: ``` 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 ```
This commit is contained in:
parent
491b978822
commit
e1280d81af
@ -38,7 +38,7 @@ use syntax_pos::Span;
|
||||
/// - 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
|
||||
|
@ -193,6 +193,63 @@ pub struct cmt_<'tcx> {
|
||||
|
||||
pub type cmt<'tcx> = Rc<cmt_<'tcx>>;
|
||||
|
||||
impl<'tcx> cmt_<'tcx> {
|
||||
pub fn get_field(&self, name: ast::Name) -> Option<DefId> {
|
||||
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<ast::Name> {
|
||||
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<ast::NodeId> {
|
||||
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;
|
||||
|
@ -1325,6 +1325,7 @@ bitflags! {
|
||||
}
|
||||
}
|
||||
|
||||
#[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,
|
||||
|
@ -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
|
||||
|
@ -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(())
|
||||
}
|
||||
(..) => {
|
||||
|
@ -540,7 +540,7 @@ pub fn opt_loan_path<'tcx>(cmt: &mc::cmt<'tcx>) -> Option<Rc<LoanPath<'tcx>>> {
|
||||
// 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 @@ impl<'a, 'tcx> BorrowckCtxt<'a, '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 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
||||
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 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
||||
format!("{} {}",
|
||||
err.cmt.mutbl.to_user_str(),
|
||||
self.cmt_to_string(&err.cmt))
|
||||
|
||||
}
|
||||
Some(lp) => {
|
||||
format!("{} {} `{}`",
|
||||
@ -807,6 +807,19 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
||||
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 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
||||
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 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
||||
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 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
||||
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<String> {
|
||||
// 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 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
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) => {
|
||||
@ -1103,41 +1175,13 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
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 {
|
||||
|
31
src/test/ui/did_you_mean/issue-38147-1.rs
Normal file
31
src/test/ui/did_you_mean/issue-38147-1.rs
Normal file
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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() {}
|
10
src/test/ui/did_you_mean/issue-38147-1.stderr
Normal file
10
src/test/ui/did_you_mean/issue-38147-1.stderr
Normal file
@ -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
|
||||
|
21
src/test/ui/did_you_mean/issue-38147-2.rs
Normal file
21
src/test/ui/did_you_mean/issue-38147-2.rs
Normal file
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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() {}
|
11
src/test/ui/did_you_mean/issue-38147-2.stderr
Normal file
11
src/test/ui/did_you_mean/issue-38147-2.stderr
Normal file
@ -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
|
||||
|
21
src/test/ui/did_you_mean/issue-38147-3.rs
Normal file
21
src/test/ui/did_you_mean/issue-38147-3.rs
Normal file
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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() {}
|
13
src/test/ui/did_you_mean/issue-38147-3.stderr
Normal file
13
src/test/ui/did_you_mean/issue-38147-3.stderr
Normal file
@ -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
|
||||
|
19
src/test/ui/did_you_mean/issue-38147-4.rs
Normal file
19
src/test/ui/did_you_mean/issue-38147-4.rs
Normal file
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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() {}
|
10
src/test/ui/did_you_mean/issue-38147-4.stderr
Normal file
10
src/test/ui/did_you_mean/issue-38147-4.stderr
Normal file
@ -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
|
||||
|
@ -12,7 +12,7 @@ error: cannot borrow immutable borrowed content `*x` as mutable
|
||||
74 | fn deref_extend_mut_field1(x: &Own<Point>) -> &mut isize {
|
||||
| ----------- use `&mut Own<Point>` 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<Point>) {
|
||||
| -------------- use `&'a mut Own<Point>` 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<Point>) -> &mut isize {
|
||||
| ----------- use `&mut Own<Point>` 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<Point>) {
|
||||
| -------------- use `&'a mut Own<Point>` here to make mutable
|
||||
143 | *x.y_mut() = 3; //~ ERROR cannot borrow
|
||||
| ^
|
||||
| ^ cannot borrow as mutable
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
|
||||
|
@ -12,7 +12,7 @@ error: cannot borrow immutable borrowed content `*x` as mutable
|
||||
50 | fn deref_extend_mut1<'a>(x: &'a Own<isize>) -> &'a mut isize {
|
||||
| -------------- use `&'a mut Own<isize>` 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<isize>) {
|
||||
| -------------- use `&'a mut Own<isize>` here to make mutable
|
||||
63 | **x = 3; //~ ERROR cannot borrow
|
||||
| ^^
|
||||
| ^^ cannot borrow as mutable
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
@ -17,13 +17,15 @@ error: cannot borrow immutable borrowed content `*f` as mutable
|
||||
35 | fn test2<F>(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
|
||||
|
@ -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
|
||||
|
||||
|
@ -4,7 +4,7 @@ error: cannot borrow immutable borrowed content `*x` as mutable
|
||||
16 | fn broken(x: &Vec<String>) {
|
||||
| ------------ use `&mut Vec<String>` here to make mutable
|
||||
17 | x.push(format!("this is broken"));
|
||||
| ^
|
||||
| ^ cannot borrow as mutable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user