Skip to content

Commit

Permalink
Auto merge of #126996 - oli-obk:do_not_count_errors, r=nnethercote
Browse files Browse the repository at this point in the history
Automatically taint InferCtxt when errors are emitted

r? `@nnethercote`

Basically `InferCtxt::dcx` now returns a `DiagCtxt` that refers back to the `Cell<Option<ErrorGuaranteed>>` of the `InferCtxt` and thus when invoking `Diag::emit`, and the diagnostic is an error, we taint the `InferCtxt` directly.

That change on its own has no effect at all, because `InferCtxt` already tracks whether errors have been emitted by recording the global error count when it gets opened, and checking at the end whether the count changed. So I removed that error count check, which had a bit of fallout that I immediately fixed by invoking `InferCtxt::dcx` instead of `TyCtxt::dcx` in a bunch of places.

The remaining new errors are because an error was reported in another query, and never bubbled up. I think they are minor enough for this to be ok, and sometimes it actually improves diagnostics, by not silencing useful diagnostics anymore.

fixes #126485 (cc `@olafes)`

There are more improvements we can do (like tainting in hir ty lowering), but I would rather do that in follow up PRs, because it requires some refactorings.
  • Loading branch information
bors committed Jul 1, 2024
2 parents f92a6c4 + bd111f5 commit 7b21c18
Show file tree
Hide file tree
Showing 77 changed files with 886 additions and 816 deletions.
50 changes: 25 additions & 25 deletions compiler/rustc_borrowck/src/borrowck_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use rustc_middle::span_bug;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::Span;

impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
pub fn dcx(&self) -> DiagCtxtHandle<'tcx> {
impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
pub fn dcx(&self) -> DiagCtxtHandle<'infcx> {
self.infcx.dcx()
}

Expand All @@ -18,7 +18,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
place: &str,
borrow_place: &str,
value_place: &str,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
self.dcx().create_err(crate::session_diagnostics::MoveBorrow {
place,
span,
Expand All @@ -34,7 +34,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
desc: &str,
borrow_span: Span,
borrow_desc: &str,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
struct_span_code_err!(
self.dcx(),
span,
Expand All @@ -54,7 +54,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
old_loan_span: Span,
old_opt_via: &str,
old_load_end_span: Option<Span>,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
let via = |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {msg})") };
let mut err = struct_span_code_err!(
self.dcx(),
Expand Down Expand Up @@ -101,7 +101,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
desc: &str,
old_loan_span: Span,
old_load_end_span: Option<Span>,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
let mut err = struct_span_code_err!(
self.dcx(),
new_loan_span,
Expand Down Expand Up @@ -134,7 +134,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
noun_old: &str,
old_opt_via: &str,
previous_end_span: Option<Span>,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
let mut err = struct_span_code_err!(
self.dcx(),
new_loan_span,
Expand Down Expand Up @@ -166,7 +166,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
old_opt_via: &str,
previous_end_span: Option<Span>,
second_borrow_desc: &str,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
let mut err = struct_span_code_err!(
self.dcx(),
new_loan_span,
Expand Down Expand Up @@ -198,7 +198,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
kind_old: &str,
msg_old: &str,
old_load_end_span: Option<Span>,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
let via = |msg: &str| if msg.is_empty() { "".to_string() } else { format!(" (via {msg})") };
let mut err = struct_span_code_err!(
self.dcx(),
Expand Down Expand Up @@ -239,7 +239,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
span: Span,
borrow_span: Span,
desc: &str,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
struct_span_code_err!(
self.dcx(),
span,
Expand All @@ -256,20 +256,20 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
span: Span,
desc: &str,
is_arg: bool,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
let msg = if is_arg { "to immutable argument" } else { "twice to immutable variable" };
struct_span_code_err!(self.dcx(), span, E0384, "cannot assign {} {}", msg, desc)
}

pub(crate) fn cannot_assign(&self, span: Span, desc: &str) -> Diag<'tcx> {
pub(crate) fn cannot_assign(&self, span: Span, desc: &str) -> Diag<'infcx> {
struct_span_code_err!(self.dcx(), span, E0594, "cannot assign to {}", desc)
}

pub(crate) fn cannot_move_out_of(
&self,
move_from_span: Span,
move_from_desc: &str,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
struct_span_code_err!(
self.dcx(),
move_from_span,
Expand All @@ -287,7 +287,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
move_from_span: Span,
ty: Ty<'_>,
is_index: Option<bool>,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
let type_name = match (&ty.kind(), is_index) {
(&ty::Array(_, _), Some(true)) | (&ty::Array(_, _), None) => "array",
(&ty::Slice(_), _) => "slice",
Expand All @@ -308,7 +308,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
&self,
move_from_span: Span,
container_ty: Ty<'_>,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
struct_span_code_err!(
self.dcx(),
move_from_span,
Expand All @@ -325,7 +325,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
verb: &str,
optional_adverb_for_moved: &str,
moved_path: Option<String>,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
let moved_path = moved_path.map(|mp| format!(": `{mp}`")).unwrap_or_default();

struct_span_code_err!(
Expand All @@ -344,7 +344,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
span: Span,
path: &str,
reason: &str,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
struct_span_code_err!(
self.dcx(),
span,
Expand All @@ -362,7 +362,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
immutable_place: &str,
immutable_section: &str,
action: &str,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
struct_span_code_err!(
self.dcx(),
mutate_span,
Expand All @@ -380,7 +380,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
&self,
span: Span,
yield_span: Span,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
let coroutine_kind = self.body.coroutine.as_ref().unwrap().coroutine_kind;
struct_span_code_err!(
self.dcx(),
Expand All @@ -391,7 +391,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
.with_span_label(yield_span, "possible yield occurs here")
}

pub(crate) fn cannot_borrow_across_destructor(&self, borrow_span: Span) -> Diag<'tcx> {
pub(crate) fn cannot_borrow_across_destructor(&self, borrow_span: Span) -> Diag<'infcx> {
struct_span_code_err!(
self.dcx(),
borrow_span,
Expand All @@ -400,7 +400,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
)
}

pub(crate) fn path_does_not_live_long_enough(&self, span: Span, path: &str) -> Diag<'tcx> {
pub(crate) fn path_does_not_live_long_enough(&self, span: Span, path: &str) -> Diag<'infcx> {
struct_span_code_err!(self.dcx(), span, E0597, "{} does not live long enough", path,)
}

Expand All @@ -410,7 +410,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
return_kind: &str,
reference_desc: &str,
path_desc: &str,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
struct_span_code_err!(
self.dcx(),
span,
Expand All @@ -433,7 +433,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
borrowed_path: &str,
capture_span: Span,
scope: &str,
) -> Diag<'tcx> {
) -> Diag<'infcx> {
struct_span_code_err!(
self.dcx(),
closure_span,
Expand All @@ -445,7 +445,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
.with_span_label(closure_span, format!("may outlive borrowed value {borrowed_path}"))
}

pub(crate) fn thread_local_value_does_not_live_long_enough(&self, span: Span) -> Diag<'tcx> {
pub(crate) fn thread_local_value_does_not_live_long_enough(&self, span: Span) -> Diag<'infcx> {
struct_span_code_err!(
self.dcx(),
span,
Expand All @@ -454,7 +454,7 @@ impl<'tcx> crate::MirBorrowckCtxt<'_, '_, '_, 'tcx> {
)
}

pub(crate) fn temporary_value_borrowed_for_too_long(&self, span: Span) -> Diag<'tcx> {
pub(crate) fn temporary_value_borrowed_for_too_long(&self, span: Span) -> Diag<'infcx> {
struct_span_code_err!(self.dcx(), span, E0716, "temporary value dropped while borrowed",)
}
}
Expand Down
40 changes: 20 additions & 20 deletions compiler/rustc_borrowck/src/dataflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,24 @@ use std::fmt;
use crate::{places_conflict, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext};

/// The results of the dataflow analyses used by the borrow checker.
pub struct BorrowckResults<'mir, 'tcx> {
pub(crate) borrows: Results<'tcx, Borrows<'mir, 'tcx>>,
pub(crate) uninits: Results<'tcx, MaybeUninitializedPlaces<'mir, 'tcx>>,
pub(crate) ever_inits: Results<'tcx, EverInitializedPlaces<'mir, 'tcx>>,
pub struct BorrowckResults<'a, 'mir, 'tcx> {
pub(crate) borrows: Results<'tcx, Borrows<'a, 'mir, 'tcx>>,
pub(crate) uninits: Results<'tcx, MaybeUninitializedPlaces<'a, 'mir, 'tcx>>,
pub(crate) ever_inits: Results<'tcx, EverInitializedPlaces<'a, 'mir, 'tcx>>,
}

/// The transient state of the dataflow analyses used by the borrow checker.
#[derive(Debug)]
pub struct BorrowckFlowState<'mir, 'tcx> {
pub(crate) borrows: <Borrows<'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
pub(crate) uninits: <MaybeUninitializedPlaces<'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
pub(crate) ever_inits: <EverInitializedPlaces<'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
pub struct BorrowckFlowState<'a, 'mir, 'tcx> {
pub(crate) borrows: <Borrows<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
pub(crate) uninits: <MaybeUninitializedPlaces<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
pub(crate) ever_inits: <EverInitializedPlaces<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
}

impl<'mir, 'tcx> ResultsVisitable<'tcx> for BorrowckResults<'mir, 'tcx> {
impl<'a, 'mir, 'tcx> ResultsVisitable<'tcx> for BorrowckResults<'a, 'mir, 'tcx> {
// All three analyses are forward, but we have to use just one here.
type Direction = <Borrows<'mir, 'tcx> as AnalysisDomain<'tcx>>::Direction;
type FlowState = BorrowckFlowState<'mir, 'tcx>;
type Direction = <Borrows<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Direction;
type FlowState = BorrowckFlowState<'a, 'mir, 'tcx>;

fn new_flow_state(&self, body: &mir::Body<'tcx>) -> Self::FlowState {
BorrowckFlowState {
Expand Down Expand Up @@ -106,11 +106,11 @@ rustc_index::newtype_index! {
/// `BorrowIndex`, and maps each such index to a `BorrowData`
/// describing the borrow. These indexes are used for representing the
/// borrows in compact bitvectors.
pub struct Borrows<'mir, 'tcx> {
pub struct Borrows<'a, 'mir, 'tcx> {
tcx: TyCtxt<'tcx>,
body: &'mir Body<'tcx>,

borrow_set: &'mir BorrowSet<'tcx>,
borrow_set: &'a BorrowSet<'tcx>,
borrows_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>,
}

Expand Down Expand Up @@ -389,12 +389,12 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
}
}

impl<'mir, 'tcx> Borrows<'mir, 'tcx> {
impl<'a, 'mir, 'tcx> Borrows<'a, 'mir, 'tcx> {
pub fn new(
tcx: TyCtxt<'tcx>,
body: &'mir Body<'tcx>,
regioncx: &'mir RegionInferenceContext<'tcx>,
borrow_set: &'mir BorrowSet<'tcx>,
regioncx: &RegionInferenceContext<'tcx>,
borrow_set: &'a BorrowSet<'tcx>,
) -> Self {
let mut borrows_out_of_scope_at_location =
calculate_borrows_out_of_scope_at_location(body, regioncx, borrow_set);
Expand Down Expand Up @@ -494,7 +494,7 @@ impl<'mir, 'tcx> Borrows<'mir, 'tcx> {
}
}

impl<'tcx> rustc_mir_dataflow::AnalysisDomain<'tcx> for Borrows<'_, 'tcx> {
impl<'tcx> rustc_mir_dataflow::AnalysisDomain<'tcx> for Borrows<'_, '_, 'tcx> {
type Domain = BitSet<BorrowIndex>;

const NAME: &'static str = "borrows";
Expand All @@ -517,7 +517,7 @@ impl<'tcx> rustc_mir_dataflow::AnalysisDomain<'tcx> for Borrows<'_, 'tcx> {
/// region stops containing the CFG points reachable from the issuing location.
/// - we also kill loans of conflicting places when overwriting a shared path: e.g. borrows of
/// `a.b.c` when `a` is overwritten.
impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, '_, 'tcx> {
type Idx = BorrowIndex;

fn domain_size(&self, _: &mir::Body<'tcx>) -> usize {
Expand Down Expand Up @@ -617,8 +617,8 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
}
}

impl DebugWithContext<Borrows<'_, '_>> for BorrowIndex {
fn fmt_with(&self, ctxt: &Borrows<'_, '_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
impl DebugWithContext<Borrows<'_, '_, '_>> for BorrowIndex {
fn fmt_with(&self, ctxt: &Borrows<'_, '_, '_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", ctxt.location(*self))
}
}
Loading

0 comments on commit 7b21c18

Please sign in to comment.