diff --git a/src/librustc_borrowck/borrowck/unused.rs b/src/librustc_borrowck/borrowck/unused.rs index 7bcd8a185453b..57f6084446126 100644 --- a/src/librustc_borrowck/borrowck/unused.rs +++ b/src/librustc_borrowck/borrowck/unused.rs @@ -62,7 +62,8 @@ impl<'a, 'tcx> UnusedMutCx<'a, 'tcx> { None => span_bug!(span, "missing binding mode"), }; match bm { - ty::BindByValue(hir::MutMutable) => {} + // allow `fn(mut self: &mut self)` so we can desugar `fn(&mut self)` to that + ty::BindByValue(hir::MutMutable) if name.as_str() != "self" => {} _ => return, } diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 1866122454c70..6438e932babad 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -82,6 +82,9 @@ impl<'a> AstValidator<'a> { match arg.pat.node { PatKind::Ident(BindingMode::ByValue(Mutability::Immutable), _, None) | PatKind::Wild => {} + // allow `fn(mut self: &mut self)` so we can desugar `fn(&mut self)` to that + PatKind::Ident(BindingMode::ByValue(Mutability::Mutable), ref ident, None) + if ident.name.as_str() == "self" => {} PatKind::Ident(BindingMode::ByValue(Mutability::Mutable), _, None) => report_err(arg.pat.span, true), _ => report_err(arg.pat.span, false), diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 91c9a1524e144..8f2678890331e 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1597,7 +1597,7 @@ pub enum TyKind { Infer, /// Inferred type of a `self` or `&self` argument in a method. ImplicitSelf, - // A macro in the type position. + /// A macro in the type position. Mac(Mac), /// Placeholder for a kind that has failed to be defined. Err, @@ -1677,7 +1677,9 @@ impl Arg { if ident.name == keywords::SelfValue.name() { return match self.ty.node { TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))), - TyKind::Rptr(lt, MutTy{ref ty, mutbl}) if ty.node == TyKind::ImplicitSelf => { + TyKind::Rptr(lt, MutTy { ref ty, mutbl }) + if ty.node == TyKind::ImplicitSelf => + { Some(respan(self.pat.span, SelfKind::Region(lt, mutbl))) } _ => Some(respan(self.pat.span.to(self.ty.span), @@ -1715,7 +1717,7 @@ impl Arg { match eself.node { SelfKind::Explicit(ty, mutbl) => arg(mutbl, ty), SelfKind::Value(mutbl) => arg(mutbl, infer_ty), - SelfKind::Region(lt, mutbl) => arg(Mutability::Immutable, P(Ty { + SelfKind::Region(lt, mutbl) => arg(mutbl, P(Ty { id: DUMMY_NODE_ID, node: TyKind::Rptr(lt, MutTy { ty: infer_ty, mutbl: mutbl }), span, diff --git a/src/test/ui/did_you_mean/issue-31424.rs b/src/test/ui/did_you_mean/issue-31424.rs index 1b31e064337e2..7ef5fbf8c2b4e 100644 --- a/src/test/ui/did_you_mean/issue-31424.rs +++ b/src/test/ui/did_you_mean/issue-31424.rs @@ -14,7 +14,7 @@ struct Struct; impl Struct { fn foo(&mut self) { - (&mut self).bar(); //~ ERROR cannot borrow + (&mut self).bar(); } // In this case we could keep the suggestion, but to distinguish the diff --git a/src/test/ui/did_you_mean/issue-31424.stderr b/src/test/ui/did_you_mean/issue-31424.stderr index a80593e05f105..32571ec418f58 100644 --- a/src/test/ui/did_you_mean/issue-31424.stderr +++ b/src/test/ui/did_you_mean/issue-31424.stderr @@ -1,12 +1,3 @@ -error[E0596]: cannot borrow immutable argument `self` as mutable - --> $DIR/issue-31424.rs:17:15 - | -LL | (&mut self).bar(); //~ ERROR cannot borrow - | ^^^^ - | | - | cannot reborrow mutably - | try removing `&mut` here - error[E0596]: cannot borrow immutable argument `self` as mutable --> $DIR/issue-31424.rs:23:15 | @@ -15,6 +6,6 @@ LL | fn bar(self: &mut Self) { LL | (&mut self).bar(); //~ ERROR cannot borrow | ^^^^ cannot borrow mutably -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0596`. diff --git a/src/test/ui/did_you_mean/issue-34126.rs b/src/test/ui/did_you_mean/issue-34126.rs index 9dfb38abd049f..67d296b98641e 100644 --- a/src/test/ui/did_you_mean/issue-34126.rs +++ b/src/test/ui/did_you_mean/issue-34126.rs @@ -11,7 +11,7 @@ struct Z { } impl Z { - fn run(&self, z: &mut Z) { } + fn run(&self, _z: &mut Z) { } fn start(&mut self) { self.run(&mut self); //~ ERROR cannot borrow } diff --git a/src/test/ui/did_you_mean/issue-34126.stderr b/src/test/ui/did_you_mean/issue-34126.stderr index 08ece78b78885..3f8dd369a9cd6 100644 --- a/src/test/ui/did_you_mean/issue-34126.stderr +++ b/src/test/ui/did_you_mean/issue-34126.stderr @@ -1,12 +1,12 @@ -error[E0596]: cannot borrow immutable argument `self` as mutable +error[E0502]: cannot borrow `self` as mutable because `*self` is also borrowed as immutable --> $DIR/issue-34126.rs:16:23 | LL | self.run(&mut self); //~ ERROR cannot borrow - | ^^^^ - | | - | cannot reborrow mutably - | try removing `&mut` here + | ---- ^^^^- immutable borrow ends here + | | | + | | mutable borrow occurs here + | immutable borrow occurs here error: aborting due to previous error -For more information about this error, try `rustc --explain E0596`. +For more information about this error, try `rustc --explain E0502`.