From 23c3a307300827dbd53637742905293b9240506a Mon Sep 17 00:00:00 2001 From: clubby789 Date: Tue, 3 Jan 2023 17:02:25 +0000 Subject: [PATCH] Explain error with `&mut self` for unsized trait impls --- .../src/diagnostics/mutability_errors.rs | 27 +++++++++++-------- src/test/ui/borrowck/issue-93078.rs | 15 +++++++++++ src/test/ui/borrowck/issue-93078.stderr | 12 +++++++++ 3 files changed, 43 insertions(+), 11 deletions(-) create mode 100644 src/test/ui/borrowck/issue-93078.rs create mode 100644 src/test/ui/borrowck/issue-93078.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 6f6d1b01bd429..bf830e276999c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -344,20 +344,25 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } else { err.span_help(source_info.span, "try removing `&mut` here"); } - } else if decl.mutability == Mutability::Not - && !matches!( + } else if decl.mutability == Mutability::Not { + if matches!( decl.local_info, Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::ImplicitSelf( hir::ImplicitSelfKind::MutRef - )))) - ) - { - err.span_suggestion_verbose( - decl.source_info.span.shrink_to_lo(), - "consider making the binding mutable", - "mut ", - Applicability::MachineApplicable, - ); + ),))) + ) { + err.note( + "as `Self` may be unsized, this call attempts to take `&mut &mut self`", + ); + err.note("however, `&mut self` expands to `self: &mut Self`, therefore `self` cannot be borrowed mutably"); + } else { + err.span_suggestion_verbose( + decl.source_info.span.shrink_to_lo(), + "consider making the binding mutable", + "mut ", + Applicability::MachineApplicable, + ); + }; } } diff --git a/src/test/ui/borrowck/issue-93078.rs b/src/test/ui/borrowck/issue-93078.rs new file mode 100644 index 0000000000000..2e608c5db3e1d --- /dev/null +++ b/src/test/ui/borrowck/issue-93078.rs @@ -0,0 +1,15 @@ +trait Modify { + fn modify(&mut self) ; +} + +impl Modify for T { + fn modify(&mut self) {} +} + +trait Foo { + fn mute(&mut self) { + self.modify(); //~ ERROR cannot borrow `self` as mutable + } +} + +fn main() {} diff --git a/src/test/ui/borrowck/issue-93078.stderr b/src/test/ui/borrowck/issue-93078.stderr new file mode 100644 index 0000000000000..771a652a1739c --- /dev/null +++ b/src/test/ui/borrowck/issue-93078.stderr @@ -0,0 +1,12 @@ +error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable + --> $DIR/issue-93078.rs:11:9 + | +LL | self.modify(); + | ^^^^^^^^^^^^^ cannot borrow as mutable + | + = note: as `Self` may be unsized, this call attempts to take `&mut &mut self` + = note: however, `&mut self` expands to `self: &mut Self`, therefore `self` cannot be borrowed mutably + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0596`.