diff --git a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs index 21f00af5c0cef..74e872e200dab 100644 --- a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs +++ b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs @@ -256,6 +256,6 @@ impl OutlivesSuggestionBuilder { diag.sort_span = mir_span.shrink_to_hi(); // Buffer the diagnostic - mbcx.buffer_error(diag); + mbcx.buffer_non_error_diag(diag); } } diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 459b03b0fad65..04d914cdc718b 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -398,7 +398,7 @@ fn do_mir_borrowck<'a, 'tcx>( diag.message = initial_diag.styled_message().clone(); diag.span = initial_diag.span.clone(); - mbcx.buffer_error(diag); + mbcx.buffer_non_error_diag(diag); }, ); initial_diag.cancel(); @@ -2317,6 +2317,11 @@ mod error { t.buffer(&mut self.buffered); } + // For diagnostics we must not set `tainted_by_errors`. + pub fn buffer_non_error_diag(&mut self, t: DiagnosticBuilder<'_>) { + t.buffer(&mut self.buffered); + } + pub fn set_tainted_by_errors(&mut self) { self.tainted_by_errors = Some(ErrorReported {}); } @@ -2327,6 +2332,10 @@ mod error { self.errors.buffer_error(t); } + pub fn buffer_non_error_diag(&mut self, t: DiagnosticBuilder<'_>) { + self.errors.buffer_non_error_diag(t); + } + pub fn buffer_move_error( &mut self, move_out_indices: Vec, diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index a16bdf286738c..a2736fd115664 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -417,7 +417,7 @@ pub(super) fn dump_annotation<'a, 'tcx>( err.note(&format!("Inferred opaque type values:\n{:#?}", opaque_type_values)); } - errors.buffer_error(err); + errors.buffer_non_error_diag(err); } fn for_each_region_constraint( diff --git a/src/test/ui/nll/lint-no-err.rs b/src/test/ui/nll/lint-no-err.rs new file mode 100644 index 0000000000000..4b4169faadf55 --- /dev/null +++ b/src/test/ui/nll/lint-no-err.rs @@ -0,0 +1,28 @@ +// check-pass + +// mir borrowck previously incorrectly set `tainted_by_errors` +// when buffering lints, which resulted in ICE later on, +// see #94502. + +// Errors with `nll` which is already tested in enough other tests, +// so we ignore it here. +// +// ignore-compare-mode-nll + +struct Repro; +impl Repro { + fn get(&self) -> &i32 { + &3 + } + + fn insert(&mut self, _: i32) {} +} + +fn main() { + let x = &0; + let mut conflict = Repro; + let prev = conflict.get(); + conflict.insert(*prev + *x); + //~^ WARN cannot borrow `conflict` as mutable because it is also borrowed as immutable + //~| WARN this borrowing pattern was not meant to be accepted +} diff --git a/src/test/ui/nll/lint-no-err.stderr b/src/test/ui/nll/lint-no-err.stderr new file mode 100644 index 0000000000000..1e7aecfaa643d --- /dev/null +++ b/src/test/ui/nll/lint-no-err.stderr @@ -0,0 +1,17 @@ +warning: cannot borrow `conflict` as mutable because it is also borrowed as immutable + --> $DIR/lint-no-err.rs:25:5 + | +LL | let prev = conflict.get(); + | -------------- immutable borrow occurs here +LL | conflict.insert(*prev + *x); + | ^^^^^^^^^^^^^^^^-----^^^^^^ + | | | + | | immutable borrow later used here + | mutable borrow occurs here + | + = note: `#[warn(mutable_borrow_reservation_conflict)]` on by default + = warning: this borrowing pattern was not meant to be accepted, and may become a hard error in the future + = note: for more information, see issue #59159 + +warning: 1 warning emitted +