Add a helper function for a common piece of code
This commit is contained in:
parent
05a62c5527
commit
5b5b549580
3 changed files with 32 additions and 68 deletions
|
@ -427,25 +427,27 @@ pub struct ImplDerivedObligationCause<'tcx> {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObligationCauseCode<'_> {
|
impl<'tcx> ObligationCauseCode<'tcx> {
|
||||||
// Return the base obligation, ignoring derived obligations.
|
// Return the base obligation, ignoring derived obligations.
|
||||||
pub fn peel_derives(&self) -> &Self {
|
pub fn peel_derives(&self) -> &Self {
|
||||||
let mut base_cause = self;
|
let mut base_cause = self;
|
||||||
loop {
|
while let Some((parent_code, _)) = base_cause.parent() {
|
||||||
match base_cause {
|
base_cause = parent_code;
|
||||||
BuiltinDerivedObligation(DerivedObligationCause { parent_code, .. })
|
|
||||||
| DerivedObligation(DerivedObligationCause { parent_code, .. })
|
|
||||||
| FunctionArgumentObligation { parent_code, .. } => {
|
|
||||||
base_cause = &parent_code;
|
|
||||||
}
|
|
||||||
ImplDerivedObligation(obligation_cause) => {
|
|
||||||
base_cause = &*obligation_cause.derived.parent_code;
|
|
||||||
}
|
|
||||||
_ => break,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
base_cause
|
base_cause
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parent(&self) -> Option<(&Self, Option<ty::PolyTraitPredicate<'tcx>>)> {
|
||||||
|
match self {
|
||||||
|
FunctionArgumentObligation { parent_code, .. } => Some((parent_code, None)),
|
||||||
|
BuiltinDerivedObligation(derived)
|
||||||
|
| DerivedObligation(derived)
|
||||||
|
| ImplDerivedObligation(box ImplDerivedObligationCause { derived, .. }) => {
|
||||||
|
Some((&derived.parent_code, Some(derived.parent_trait_pred)))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger.
|
// `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||||
|
|
|
@ -2,11 +2,10 @@ pub mod on_unimplemented;
|
||||||
pub mod suggestions;
|
pub mod suggestions;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
DerivedObligationCause, EvaluationResult, FulfillmentContext, FulfillmentError,
|
EvaluationResult, FulfillmentContext, FulfillmentError, FulfillmentErrorCode,
|
||||||
FulfillmentErrorCode, ImplDerivedObligationCause, MismatchedProjectionTypes, Obligation,
|
MismatchedProjectionTypes, Obligation, ObligationCause, ObligationCauseCode,
|
||||||
ObligationCause, ObligationCauseCode, OnUnimplementedDirective, OnUnimplementedNote,
|
OnUnimplementedDirective, OnUnimplementedNote, OutputTypeParameterMismatch, Overflow,
|
||||||
OutputTypeParameterMismatch, Overflow, PredicateObligation, SelectionContext, SelectionError,
|
PredicateObligation, SelectionContext, SelectionError, TraitNotObjectSafe,
|
||||||
TraitNotObjectSafe,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
|
use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
|
||||||
|
@ -684,32 +683,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
let mut code = obligation.cause.code();
|
let mut code = obligation.cause.code();
|
||||||
let mut trait_pred = trait_predicate;
|
let mut trait_pred = trait_predicate;
|
||||||
let mut peeled = false;
|
let mut peeled = false;
|
||||||
loop {
|
while let Some((parent_code, parent_trait_pred)) = code.parent() {
|
||||||
match &*code {
|
code = parent_code;
|
||||||
ObligationCauseCode::FunctionArgumentObligation {
|
if let Some(parent_trait_pred) = parent_trait_pred {
|
||||||
parent_code,
|
trait_pred = parent_trait_pred;
|
||||||
..
|
peeled = true;
|
||||||
} => {
|
}
|
||||||
code = &parent_code;
|
|
||||||
}
|
|
||||||
ObligationCauseCode::ImplDerivedObligation(
|
|
||||||
box ImplDerivedObligationCause {
|
|
||||||
derived,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
)
|
|
||||||
| ObligationCauseCode::BuiltinDerivedObligation(
|
|
||||||
derived,
|
|
||||||
)
|
|
||||||
| ObligationCauseCode::DerivedObligation(
|
|
||||||
derived,
|
|
||||||
) => {
|
|
||||||
peeled = true;
|
|
||||||
code = &derived.parent_code;
|
|
||||||
trait_pred = derived.parent_trait_pred;
|
|
||||||
}
|
|
||||||
_ => break,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
let def_id = trait_pred.def_id();
|
let def_id = trait_pred.def_id();
|
||||||
// Mention *all* the `impl`s for the *top most* obligation, the
|
// Mention *all* the `impl`s for the *top most* obligation, the
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use super::{
|
use super::{
|
||||||
DerivedObligationCause, EvaluationResult, ImplDerivedObligationCause, Obligation,
|
EvaluationResult, Obligation, ObligationCause, ObligationCauseCode, PredicateObligation,
|
||||||
ObligationCause, ObligationCauseCode, PredicateObligation, SelectionContext,
|
SelectionContext,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::autoderef::Autoderef;
|
use crate::autoderef::Autoderef;
|
||||||
|
@ -623,28 +623,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
let span = obligation.cause.span;
|
let span = obligation.cause.span;
|
||||||
let mut real_trait_pred = trait_pred;
|
let mut real_trait_pred = trait_pred;
|
||||||
let mut code = obligation.cause.code();
|
let mut code = obligation.cause.code();
|
||||||
loop {
|
while let Some((parent_code, parent_trait_pred)) = code.parent() {
|
||||||
match &code {
|
code = parent_code;
|
||||||
ObligationCauseCode::FunctionArgumentObligation { parent_code, .. } => {
|
if let Some(parent_trait_pred) = parent_trait_pred {
|
||||||
code = &parent_code;
|
real_trait_pred = parent_trait_pred;
|
||||||
}
|
}
|
||||||
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,
|
|
||||||
};
|
|
||||||
let Some(real_ty) = real_trait_pred.self_ty().no_bound_vars() else {
|
let Some(real_ty) = real_trait_pred.self_ty().no_bound_vars() else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue