Auto merge of #96892 - oli-obk:🐌_obligation_cause_code_🐌, r=estebank
Clean up derived obligation creation r? `@estebank` working on fixing the perf regression from https://github.com/rust-lang/rust/pull/91030#issuecomment-1083360210
This commit is contained in:
commit
c1d65eaa45
11 changed files with 176 additions and 219 deletions
|
@ -2,11 +2,10 @@ pub mod on_unimplemented;
|
|||
pub mod suggestions;
|
||||
|
||||
use super::{
|
||||
DerivedObligationCause, EvaluationResult, FulfillmentContext, FulfillmentError,
|
||||
FulfillmentErrorCode, ImplDerivedObligationCause, MismatchedProjectionTypes, Obligation,
|
||||
ObligationCause, ObligationCauseCode, OnUnimplementedDirective, OnUnimplementedNote,
|
||||
OutputTypeParameterMismatch, Overflow, PredicateObligation, SelectionContext, SelectionError,
|
||||
TraitNotObjectSafe,
|
||||
EvaluationResult, FulfillmentContext, FulfillmentError, FulfillmentErrorCode,
|
||||
MismatchedProjectionTypes, Obligation, ObligationCause, ObligationCauseCode,
|
||||
OnUnimplementedDirective, OnUnimplementedNote, OutputTypeParameterMismatch, Overflow,
|
||||
PredicateObligation, SelectionContext, SelectionError, TraitNotObjectSafe,
|
||||
};
|
||||
|
||||
use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
|
||||
|
@ -684,42 +683,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
let mut code = obligation.cause.code();
|
||||
let mut trait_pred = trait_predicate;
|
||||
let mut peeled = false;
|
||||
loop {
|
||||
match &*code {
|
||||
ObligationCauseCode::FunctionArgumentObligation {
|
||||
parent_code,
|
||||
..
|
||||
} => {
|
||||
code = &parent_code;
|
||||
}
|
||||
ObligationCauseCode::ImplDerivedObligation(
|
||||
box ImplDerivedObligationCause {
|
||||
derived:
|
||||
DerivedObligationCause {
|
||||
parent_code,
|
||||
parent_trait_pred,
|
||||
},
|
||||
..
|
||||
},
|
||||
)
|
||||
| ObligationCauseCode::BuiltinDerivedObligation(
|
||||
DerivedObligationCause {
|
||||
parent_code,
|
||||
parent_trait_pred,
|
||||
},
|
||||
)
|
||||
| ObligationCauseCode::DerivedObligation(
|
||||
DerivedObligationCause {
|
||||
parent_code,
|
||||
parent_trait_pred,
|
||||
},
|
||||
) => {
|
||||
peeled = true;
|
||||
code = &parent_code;
|
||||
trait_pred = *parent_trait_pred;
|
||||
}
|
||||
_ => break,
|
||||
};
|
||||
while let Some((parent_code, parent_trait_pred)) = code.parent() {
|
||||
code = parent_code;
|
||||
if let Some(parent_trait_pred) = parent_trait_pred {
|
||||
trait_pred = parent_trait_pred;
|
||||
peeled = true;
|
||||
}
|
||||
}
|
||||
let def_id = trait_pred.def_id();
|
||||
// Mention *all* the `impl`s for the *top most* obligation, the
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use super::{
|
||||
DerivedObligationCause, EvaluationResult, ImplDerivedObligationCause, Obligation,
|
||||
ObligationCause, ObligationCauseCode, PredicateObligation, SelectionContext,
|
||||
EvaluationResult, Obligation, ObligationCause, ObligationCauseCode, PredicateObligation,
|
||||
SelectionContext,
|
||||
};
|
||||
|
||||
use crate::autoderef::Autoderef;
|
||||
|
@ -623,28 +623,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
let span = obligation.cause.span;
|
||||
let mut real_trait_pred = trait_pred;
|
||||
let mut code = obligation.cause.code();
|
||||
loop {
|
||||
match &code {
|
||||
ObligationCauseCode::FunctionArgumentObligation { parent_code, .. } => {
|
||||
code = &parent_code;
|
||||
}
|
||||
ObligationCauseCode::ImplDerivedObligation(box ImplDerivedObligationCause {
|
||||
derived: DerivedObligationCause { parent_code, parent_trait_pred },
|
||||
..
|
||||
})
|
||||
| ObligationCauseCode::BuiltinDerivedObligation(DerivedObligationCause {
|
||||
parent_code,
|
||||
parent_trait_pred,
|
||||
})
|
||||
| ObligationCauseCode::DerivedObligation(DerivedObligationCause {
|
||||
parent_code,
|
||||
parent_trait_pred,
|
||||
}) => {
|
||||
code = &parent_code;
|
||||
real_trait_pred = *parent_trait_pred;
|
||||
}
|
||||
_ => break,
|
||||
};
|
||||
while let Some((parent_code, parent_trait_pred)) = code.parent() {
|
||||
code = parent_code;
|
||||
if let Some(parent_trait_pred) = parent_trait_pred {
|
||||
real_trait_pred = parent_trait_pred;
|
||||
}
|
||||
let Some(real_ty) = real_trait_pred.self_ty().no_bound_vars() else {
|
||||
continue;
|
||||
};
|
||||
|
@ -1669,7 +1652,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
debug!("maybe_note_obligation_cause_for_async_await: code={:?}", code);
|
||||
match code {
|
||||
ObligationCauseCode::FunctionArgumentObligation { parent_code, .. } => {
|
||||
next_code = Some(parent_code.as_ref());
|
||||
next_code = Some(parent_code);
|
||||
}
|
||||
ObligationCauseCode::ImplDerivedObligation(cause) => {
|
||||
let ty = cause.derived.parent_trait_pred.skip_binder().self_ty();
|
||||
|
@ -1700,7 +1683,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
_ => {}
|
||||
}
|
||||
|
||||
next_code = Some(cause.derived.parent_code.as_ref());
|
||||
next_code = Some(&cause.derived.parent_code);
|
||||
}
|
||||
ObligationCauseCode::DerivedObligation(derived_obligation)
|
||||
| ObligationCauseCode::BuiltinDerivedObligation(derived_obligation) => {
|
||||
|
@ -1732,7 +1715,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
_ => {}
|
||||
}
|
||||
|
||||
next_code = Some(derived_obligation.parent_code.as_ref());
|
||||
next_code = Some(&derived_obligation.parent_code);
|
||||
}
|
||||
_ => break,
|
||||
}
|
||||
|
@ -2382,8 +2365,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
let is_upvar_tys_infer_tuple = if !matches!(ty.kind(), ty::Tuple(..)) {
|
||||
false
|
||||
} else {
|
||||
if let ObligationCauseCode::BuiltinDerivedObligation(ref data) =
|
||||
*data.parent_code
|
||||
if let ObligationCauseCode::BuiltinDerivedObligation(data) = &*data.parent_code
|
||||
{
|
||||
let parent_trait_ref =
|
||||
self.resolve_vars_if_possible(data.parent_trait_pred);
|
||||
|
@ -2428,7 +2410,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
err,
|
||||
&parent_predicate,
|
||||
param_env,
|
||||
&cause_code.peel_derives(),
|
||||
cause_code.peel_derives(),
|
||||
obligated_types,
|
||||
seen_requirements,
|
||||
)
|
||||
|
|
|
@ -17,17 +17,15 @@ use rustc_middle::ty::{ToPolyTraitRef, ToPredicate};
|
|||
use rustc_span::def_id::DefId;
|
||||
|
||||
use crate::traits::project::{normalize_with_depth, normalize_with_depth_to};
|
||||
use crate::traits::select::TraitObligationExt;
|
||||
use crate::traits::util::{self, closure_trait_ref_and_return_type, predicate_for_trait_def};
|
||||
use crate::traits::{
|
||||
BuiltinDerivedObligation, DerivedObligationCause, ImplDerivedObligation,
|
||||
ImplDerivedObligationCause, ImplSource, ImplSourceAutoImplData, ImplSourceBuiltinData,
|
||||
ImplSourceClosureData, ImplSourceConstDestructData, ImplSourceDiscriminantKindData,
|
||||
ImplSourceFnPointerData, ImplSourceGeneratorData, ImplSourceObjectData, ImplSourcePointeeData,
|
||||
ImplSourceTraitAliasData, ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized,
|
||||
ObjectCastObligation, Obligation, ObligationCause, OutputTypeParameterMismatch,
|
||||
PredicateObligation, Selection, SelectionError, TraitNotObjectSafe, TraitObligation,
|
||||
Unimplemented, VtblSegment,
|
||||
BuiltinDerivedObligation, ImplDerivedObligation, ImplDerivedObligationCause, ImplSource,
|
||||
ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData,
|
||||
ImplSourceConstDestructData, ImplSourceDiscriminantKindData, ImplSourceFnPointerData,
|
||||
ImplSourceGeneratorData, ImplSourceObjectData, ImplSourcePointeeData, ImplSourceTraitAliasData,
|
||||
ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, ObjectCastObligation,
|
||||
Obligation, ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection,
|
||||
SelectionError, TraitNotObjectSafe, TraitObligation, Unimplemented, VtblSegment,
|
||||
};
|
||||
|
||||
use super::BuiltinImplConditions;
|
||||
|
@ -1128,21 +1126,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
let substs = self.rematch_impl(impl_def_id, &new_obligation);
|
||||
debug!(?substs, "impl substs");
|
||||
|
||||
let derived = DerivedObligationCause {
|
||||
parent_trait_pred: obligation.predicate,
|
||||
parent_code: obligation.cause.clone_code(),
|
||||
};
|
||||
let derived_code = ImplDerivedObligation(Box::new(ImplDerivedObligationCause {
|
||||
derived,
|
||||
impl_def_id,
|
||||
span: obligation.cause.span,
|
||||
}));
|
||||
|
||||
let cause = ObligationCause::new(
|
||||
obligation.cause.span,
|
||||
obligation.cause.body_id,
|
||||
derived_code,
|
||||
);
|
||||
let cause = obligation.derived_cause(|derived| {
|
||||
ImplDerivedObligation(Box::new(ImplDerivedObligationCause {
|
||||
derived,
|
||||
impl_def_id,
|
||||
span: obligation.cause.span,
|
||||
}))
|
||||
});
|
||||
ensure_sufficient_stack(|| {
|
||||
self.vtable_impl(
|
||||
impl_def_id,
|
||||
|
|
|
@ -14,9 +14,9 @@ use super::util;
|
|||
use super::util::{closure_trait_ref_and_return_type, predicate_for_trait_def};
|
||||
use super::wf;
|
||||
use super::{
|
||||
DerivedObligationCause, ErrorReporting, ImplDerivedObligation, ImplDerivedObligationCause,
|
||||
Normalized, Obligation, ObligationCause, ObligationCauseCode, Overflow, PredicateObligation,
|
||||
Selection, SelectionError, SelectionResult, TraitObligation, TraitQueryMode,
|
||||
ErrorReporting, ImplDerivedObligation, ImplDerivedObligationCause, Normalized, Obligation,
|
||||
ObligationCause, ObligationCauseCode, Overflow, PredicateObligation, Selection, SelectionError,
|
||||
SelectionResult, TraitObligation, TraitQueryMode,
|
||||
};
|
||||
|
||||
use crate::infer::{InferCtxt, InferOk, TypeFreshener};
|
||||
|
@ -2314,17 +2314,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
debug!(?predicates);
|
||||
assert_eq!(predicates.parent, None);
|
||||
let mut obligations = Vec::with_capacity(predicates.predicates.len());
|
||||
let parent_code = cause.clone_code();
|
||||
for (predicate, span) in predicates.predicates {
|
||||
let span = *span;
|
||||
let derived =
|
||||
DerivedObligationCause { parent_trait_pred, parent_code: parent_code.clone() };
|
||||
let code = ImplDerivedObligation(Box::new(ImplDerivedObligationCause {
|
||||
derived,
|
||||
impl_def_id: def_id,
|
||||
span,
|
||||
}));
|
||||
let cause = ObligationCause::new(cause.span, cause.body_id, code);
|
||||
let cause = cause.clone().derived_cause(parent_trait_pred, |derived| {
|
||||
ImplDerivedObligation(Box::new(ImplDerivedObligationCause {
|
||||
derived,
|
||||
impl_def_id: def_id,
|
||||
span,
|
||||
}))
|
||||
});
|
||||
let predicate = normalize_with_depth_to(
|
||||
self,
|
||||
param_env,
|
||||
|
@ -2340,42 +2338,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
trait TraitObligationExt<'tcx> {
|
||||
fn derived_cause(
|
||||
&self,
|
||||
variant: fn(DerivedObligationCause<'tcx>) -> ObligationCauseCode<'tcx>,
|
||||
) -> ObligationCause<'tcx>;
|
||||
}
|
||||
|
||||
impl<'tcx> TraitObligationExt<'tcx> for TraitObligation<'tcx> {
|
||||
fn derived_cause(
|
||||
&self,
|
||||
variant: fn(DerivedObligationCause<'tcx>) -> ObligationCauseCode<'tcx>,
|
||||
) -> ObligationCause<'tcx> {
|
||||
/*!
|
||||
* Creates a cause for obligations that are derived from
|
||||
* `obligation` by a recursive search (e.g., for a builtin
|
||||
* bound, or eventually a `auto trait Foo`). If `obligation`
|
||||
* is itself a derived obligation, this is just a clone, but
|
||||
* otherwise we create a "derived obligation" cause so as to
|
||||
* keep track of the original root obligation for error
|
||||
* reporting.
|
||||
*/
|
||||
|
||||
let obligation = self;
|
||||
|
||||
// NOTE(flaper87): As of now, it keeps track of the whole error
|
||||
// chain. Ideally, we should have a way to configure this either
|
||||
// by using -Z verbose or just a CLI argument.
|
||||
let derived_cause = DerivedObligationCause {
|
||||
parent_trait_pred: obligation.predicate,
|
||||
parent_code: obligation.cause.clone_code(),
|
||||
};
|
||||
let derived_code = variant(derived_cause);
|
||||
ObligationCause::new(obligation.cause.span, obligation.cause.body_id, derived_code)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'o, 'tcx> TraitObligationStack<'o, 'tcx> {
|
||||
fn list(&'o self) -> TraitObligationStackList<'o, 'tcx> {
|
||||
TraitObligationStackList::with(self)
|
||||
|
|
|
@ -294,30 +294,22 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
|||
let obligations = self.nominal_obligations(trait_ref.def_id, trait_ref.substs);
|
||||
|
||||
debug!("compute_trait_ref obligations {:?}", obligations);
|
||||
let cause = self.cause(traits::MiscObligation);
|
||||
let param_env = self.param_env;
|
||||
let depth = self.recursion_depth;
|
||||
|
||||
let item = self.item;
|
||||
|
||||
let extend = |obligation: traits::PredicateObligation<'tcx>| {
|
||||
let mut cause = cause.clone();
|
||||
if let Some(parent_trait_pred) = obligation.predicate.to_opt_poly_trait_pred() {
|
||||
let derived_cause = traits::DerivedObligationCause {
|
||||
let extend = |traits::PredicateObligation { predicate, mut cause, .. }| {
|
||||
if let Some(parent_trait_pred) = predicate.to_opt_poly_trait_pred() {
|
||||
cause = cause.derived_cause(
|
||||
parent_trait_pred,
|
||||
parent_code: obligation.cause.clone_code(),
|
||||
};
|
||||
*cause.make_mut_code() =
|
||||
traits::ObligationCauseCode::DerivedObligation(derived_cause);
|
||||
traits::ObligationCauseCode::DerivedObligation,
|
||||
);
|
||||
}
|
||||
extend_cause_with_original_assoc_item_obligation(
|
||||
tcx,
|
||||
trait_ref,
|
||||
item,
|
||||
&mut cause,
|
||||
obligation.predicate,
|
||||
tcx, trait_ref, item, &mut cause, predicate,
|
||||
);
|
||||
traits::Obligation::with_depth(cause, depth, param_env, obligation.predicate)
|
||||
traits::Obligation::with_depth(cause, depth, param_env, predicate)
|
||||
};
|
||||
|
||||
if let Elaborate::All = elaborate {
|
||||
|
@ -339,17 +331,17 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
|||
})
|
||||
.filter(|(_, arg)| !arg.has_escaping_bound_vars())
|
||||
.map(|(i, arg)| {
|
||||
let mut new_cause = cause.clone();
|
||||
let mut cause = traits::ObligationCause::misc(self.span, self.body_id);
|
||||
// The first subst is the self ty - use the correct span for it.
|
||||
if i == 0 {
|
||||
if let Some(hir::ItemKind::Impl(hir::Impl { self_ty, .. })) =
|
||||
item.map(|i| &i.kind)
|
||||
{
|
||||
new_cause.span = self_ty.span;
|
||||
cause.span = self_ty.span;
|
||||
}
|
||||
}
|
||||
traits::Obligation::with_depth(
|
||||
new_cause,
|
||||
cause,
|
||||
depth,
|
||||
param_env,
|
||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)).to_predicate(tcx),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue