diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 7c5cbc58e25c5..946c1c093fd71 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -1207,6 +1207,17 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> { "access_place: suppressing error place_span=`{:?}` kind=`{:?}`", place_span, kind ); + + // If the place is being mutated, then mark it as such anyway in order to suppress the + // `unused_mut` lint, which is likely incorrect once the access place error has been + // resolved. + if rw == ReadOrWrite::Write(WriteKind::Mutate) + && let Ok(root_place) = + self.is_mutable(place_span.0.as_ref(), is_local_mutation_allowed) + { + self.add_used_mut(root_place, state); + } + return; } diff --git a/tests/ui/lint/unused/mut-used-despite-borrowck-error.rs b/tests/ui/lint/unused/mut-used-despite-borrowck-error.rs new file mode 100644 index 0000000000000..7f1a51bc85105 --- /dev/null +++ b/tests/ui/lint/unused/mut-used-despite-borrowck-error.rs @@ -0,0 +1,19 @@ +//! Do not fire unused_mut lint when mutation of the bound variable fails due to a borrow-checking +//! error. +//! +//! Regression test for https://github.com/rust-lang/rust/issues/152024 +//@ compile-flags: -W unused_mut + +struct Thing; +impl Drop for Thing { + fn drop(&mut self) {} +} + +fn main() { + let mut t; + let mut b = None; + loop { + t = Thing; //~ ERROR cannot assign to `t` because it is borrowed + b.insert(&t); + } +} diff --git a/tests/ui/lint/unused/mut-used-despite-borrowck-error.stderr b/tests/ui/lint/unused/mut-used-despite-borrowck-error.stderr new file mode 100644 index 0000000000000..c03cf3f7c6093 --- /dev/null +++ b/tests/ui/lint/unused/mut-used-despite-borrowck-error.stderr @@ -0,0 +1,13 @@ +error[E0506]: cannot assign to `t` because it is borrowed + --> $DIR/mut-used-despite-borrowck-error.rs:16:9 + | +LL | t = Thing; + | ^ `t` is assigned to here but it was already borrowed +LL | b.insert(&t); + | - -- `t` is borrowed here + | | + | borrow later used here + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0506`.