Skip to content

Commit

Permalink
Track ErrorGuaranteed instead of conjuring it from thin air
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Jan 25, 2024
1 parent 3042da0 commit 054e1e3
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 12 deletions.
3 changes: 2 additions & 1 deletion compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,8 @@ pub struct InferCtxt<'tcx> {

/// The set of predicates on which errors have been reported, to
/// avoid reporting the same error twice.
pub reported_trait_errors: RefCell<FxIndexMap<Span, Vec<ty::Predicate<'tcx>>>>,
pub reported_trait_errors:
RefCell<FxIndexMap<Span, (Vec<ty::Predicate<'tcx>>, ErrorGuaranteed)>>,

pub reported_signature_mismatch: RefCell<FxHashSet<(Span, Option<Span>)>>,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,10 @@ pub trait TypeErrCtxtExt<'tcx> {
trait_ref: ty::PolyTraitRef<'tcx>,
) -> Option<ErrorGuaranteed>;

fn fn_arg_obligation(&self, obligation: &PredicateObligation<'tcx>) -> bool;
fn fn_arg_obligation(
&self,
obligation: &PredicateObligation<'tcx>,
) -> Result<(), ErrorGuaranteed>;

fn try_conversion_context(
&self,
Expand Down Expand Up @@ -142,6 +145,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
(
span,
predicates
.0
.iter()
.map(|&predicate| ErrorDescriptor { predicate, index: None })
.collect(),
Expand Down Expand Up @@ -213,7 +217,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
for from_expansion in [false, true] {
for (error, suppressed) in iter::zip(&errors, &is_suppressed) {
if !suppressed && error.obligation.cause.span.from_expansion() == from_expansion {
reported = Some(self.report_fulfillment_error(error));
let guar = self.report_fulfillment_error(error);
reported = Some(guar);
// We want to ignore desugarings here: spans are equivalent even
// if one is the result of a desugaring and the other is not.
let mut span = error.obligation.cause.span;
Expand All @@ -224,7 +229,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
self.reported_trait_errors
.borrow_mut()
.entry(span)
.or_default()
.or_insert_with(|| (vec![], guar))
.0
.push(error.obligation.predicate);
}
}
Expand Down Expand Up @@ -447,10 +453,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
{
return guar;
}
if self.fn_arg_obligation(&obligation) {
// Silence redundant errors on binding acccess that are already
// reported on the binding definition (#56607).
return self.dcx().span_delayed_bug(obligation.cause.span, "error already reported");
// Silence redundant errors on binding acccess that are already
// reported on the binding definition (#56607).
if let Err(guar) = self.fn_arg_obligation(&obligation) {
return guar;
}
let mut file = None;
let (post_message, pre_message, type_def) = self
Expand Down Expand Up @@ -981,7 +987,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
}

fn fn_arg_obligation(&self, obligation: &PredicateObligation<'tcx>) -> bool {
fn fn_arg_obligation(
&self,
obligation: &PredicateObligation<'tcx>,
) -> Result<(), ErrorGuaranteed> {
if let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } =
obligation.cause.code()
&& let Some(Node::Expr(arg)) = self.tcx.opt_hir_node(*arg_hir_id)
Expand All @@ -991,12 +1000,12 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
hir::Path { res: hir::def::Res::Local(hir_id), .. },
)) = arg.kind
&& let Some(Node::Pat(pat)) = self.tcx.opt_hir_node(*hir_id)
&& let Some(preds) = self.reported_trait_errors.borrow().get(&pat.span)
&& let Some((preds, guar)) = self.reported_trait_errors.borrow().get(&pat.span)
&& preds.contains(&obligation.predicate)
{
return true;
return Err(*guar);
}
false
Ok(())
}

/// When the `E` of the resulting `Result<T, E>` in an expression `foo().bar().baz()?`,
Expand Down

0 comments on commit 054e1e3

Please sign in to comment.