Track ErrorGuaranteed instead of conjuring it from thin air
This commit is contained in:
parent
3042da0248
commit
054e1e3aad
@ -278,7 +278,8 @@ pub struct InferCtxt<'tcx> {
|
|||||||
|
|
||||||
/// The set of predicates on which errors have been reported, to
|
/// The set of predicates on which errors have been reported, to
|
||||||
/// avoid reporting the same error twice.
|
/// 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>)>>,
|
pub reported_signature_mismatch: RefCell<FxHashSet<(Span, Option<Span>)>>,
|
||||||
|
|
||||||
|
@ -107,7 +107,10 @@ fn emit_specialized_closure_kind_error(
|
|||||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||||
) -> Option<ErrorGuaranteed>;
|
) -> 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(
|
fn try_conversion_context(
|
||||||
&self,
|
&self,
|
||||||
@ -142,6 +145,7 @@ struct ErrorDescriptor<'tcx> {
|
|||||||
(
|
(
|
||||||
span,
|
span,
|
||||||
predicates
|
predicates
|
||||||
|
.0
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&predicate| ErrorDescriptor { predicate, index: None })
|
.map(|&predicate| ErrorDescriptor { predicate, index: None })
|
||||||
.collect(),
|
.collect(),
|
||||||
@ -213,7 +217,8 @@ struct ErrorDescriptor<'tcx> {
|
|||||||
for from_expansion in [false, true] {
|
for from_expansion in [false, true] {
|
||||||
for (error, suppressed) in iter::zip(&errors, &is_suppressed) {
|
for (error, suppressed) in iter::zip(&errors, &is_suppressed) {
|
||||||
if !suppressed && error.obligation.cause.span.from_expansion() == from_expansion {
|
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
|
// We want to ignore desugarings here: spans are equivalent even
|
||||||
// if one is the result of a desugaring and the other is not.
|
// if one is the result of a desugaring and the other is not.
|
||||||
let mut span = error.obligation.cause.span;
|
let mut span = error.obligation.cause.span;
|
||||||
@ -224,7 +229,8 @@ struct ErrorDescriptor<'tcx> {
|
|||||||
self.reported_trait_errors
|
self.reported_trait_errors
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.entry(span)
|
.entry(span)
|
||||||
.or_default()
|
.or_insert_with(|| (vec![], guar))
|
||||||
|
.0
|
||||||
.push(error.obligation.predicate);
|
.push(error.obligation.predicate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -447,10 +453,10 @@ fn report_selection_error(
|
|||||||
{
|
{
|
||||||
return guar;
|
return guar;
|
||||||
}
|
}
|
||||||
if self.fn_arg_obligation(&obligation) {
|
// Silence redundant errors on binding acccess that are already
|
||||||
// Silence redundant errors on binding acccess that are already
|
// reported on the binding definition (#56607).
|
||||||
// reported on the binding definition (#56607).
|
if let Err(guar) = self.fn_arg_obligation(&obligation) {
|
||||||
return self.dcx().span_delayed_bug(obligation.cause.span, "error already reported");
|
return guar;
|
||||||
}
|
}
|
||||||
let mut file = None;
|
let mut file = None;
|
||||||
let (post_message, pre_message, type_def) = self
|
let (post_message, pre_message, type_def) = self
|
||||||
@ -981,7 +987,10 @@ fn emit_specialized_closure_kind_error(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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, .. } =
|
if let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } =
|
||||||
obligation.cause.code()
|
obligation.cause.code()
|
||||||
&& let Some(Node::Expr(arg)) = self.tcx.opt_hir_node(*arg_hir_id)
|
&& let Some(Node::Expr(arg)) = self.tcx.opt_hir_node(*arg_hir_id)
|
||||||
@ -991,12 +1000,12 @@ fn fn_arg_obligation(&self, obligation: &PredicateObligation<'tcx>) -> bool {
|
|||||||
hir::Path { res: hir::def::Res::Local(hir_id), .. },
|
hir::Path { res: hir::def::Res::Local(hir_id), .. },
|
||||||
)) = arg.kind
|
)) = arg.kind
|
||||||
&& let Some(Node::Pat(pat)) = self.tcx.opt_hir_node(*hir_id)
|
&& 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)
|
&& 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()?`,
|
/// When the `E` of the resulting `Result<T, E>` in an expression `foo().bar().baz()?`,
|
||||||
|
Loading…
Reference in New Issue
Block a user