Skip to content

Commit 5b5b549

Browse files
committed
Add a helper function for a common piece of code
1 parent 05a62c5 commit 5b5b549

File tree

3 files changed

+32
-68
lines changed

3 files changed

+32
-68
lines changed

compiler/rustc_middle/src/traits/mod.rs

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -427,25 +427,27 @@ pub struct ImplDerivedObligationCause<'tcx> {
427427
pub span: Span,
428428
}
429429

430-
impl ObligationCauseCode<'_> {
430+
impl<'tcx> ObligationCauseCode<'tcx> {
431431
// Return the base obligation, ignoring derived obligations.
432432
pub fn peel_derives(&self) -> &Self {
433433
let mut base_cause = self;
434-
loop {
435-
match base_cause {
436-
BuiltinDerivedObligation(DerivedObligationCause { parent_code, .. })
437-
| DerivedObligation(DerivedObligationCause { parent_code, .. })
438-
| FunctionArgumentObligation { parent_code, .. } => {
439-
base_cause = &parent_code;
440-
}
441-
ImplDerivedObligation(obligation_cause) => {
442-
base_cause = &*obligation_cause.derived.parent_code;
443-
}
444-
_ => break,
445-
}
434+
while let Some((parent_code, _)) = base_cause.parent() {
435+
base_cause = parent_code;
446436
}
447437
base_cause
448438
}
439+
440+
pub fn parent(&self) -> Option<(&Self, Option<ty::PolyTraitPredicate<'tcx>>)> {
441+
match self {
442+
FunctionArgumentObligation { parent_code, .. } => Some((parent_code, None)),
443+
BuiltinDerivedObligation(derived)
444+
| DerivedObligation(derived)
445+
| ImplDerivedObligation(box ImplDerivedObligationCause { derived, .. }) => {
446+
Some((&derived.parent_code, Some(derived.parent_trait_pred)))
447+
}
448+
_ => None,
449+
}
450+
}
449451
}
450452

451453
// `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger.

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

Lines changed: 10 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@ pub mod on_unimplemented;
22
pub mod suggestions;
33

44
use super::{
5-
DerivedObligationCause, EvaluationResult, FulfillmentContext, FulfillmentError,
6-
FulfillmentErrorCode, ImplDerivedObligationCause, MismatchedProjectionTypes, Obligation,
7-
ObligationCause, ObligationCauseCode, OnUnimplementedDirective, OnUnimplementedNote,
8-
OutputTypeParameterMismatch, Overflow, PredicateObligation, SelectionContext, SelectionError,
9-
TraitNotObjectSafe,
5+
EvaluationResult, FulfillmentContext, FulfillmentError, FulfillmentErrorCode,
6+
MismatchedProjectionTypes, Obligation, ObligationCause, ObligationCauseCode,
7+
OnUnimplementedDirective, OnUnimplementedNote, OutputTypeParameterMismatch, Overflow,
8+
PredicateObligation, SelectionContext, SelectionError, TraitNotObjectSafe,
109
};
1110

1211
use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
@@ -684,32 +683,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
684683
let mut code = obligation.cause.code();
685684
let mut trait_pred = trait_predicate;
686685
let mut peeled = false;
687-
loop {
688-
match &*code {
689-
ObligationCauseCode::FunctionArgumentObligation {
690-
parent_code,
691-
..
692-
} => {
693-
code = &parent_code;
694-
}
695-
ObligationCauseCode::ImplDerivedObligation(
696-
box ImplDerivedObligationCause {
697-
derived,
698-
..
699-
},
700-
)
701-
| ObligationCauseCode::BuiltinDerivedObligation(
702-
derived,
703-
)
704-
| ObligationCauseCode::DerivedObligation(
705-
derived,
706-
) => {
707-
peeled = true;
708-
code = &derived.parent_code;
709-
trait_pred = derived.parent_trait_pred;
710-
}
711-
_ => break,
712-
};
686+
while let Some((parent_code, parent_trait_pred)) = code.parent() {
687+
code = parent_code;
688+
if let Some(parent_trait_pred) = parent_trait_pred {
689+
trait_pred = parent_trait_pred;
690+
peeled = true;
691+
}
713692
}
714693
let def_id = trait_pred.def_id();
715694
// Mention *all* the `impl`s for the *top most* obligation, the

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::{
2-
DerivedObligationCause, EvaluationResult, ImplDerivedObligationCause, Obligation,
3-
ObligationCause, ObligationCauseCode, PredicateObligation, SelectionContext,
2+
EvaluationResult, Obligation, ObligationCause, ObligationCauseCode, PredicateObligation,
3+
SelectionContext,
44
};
55

66
use crate::autoderef::Autoderef;
@@ -623,28 +623,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
623623
let span = obligation.cause.span;
624624
let mut real_trait_pred = trait_pred;
625625
let mut code = obligation.cause.code();
626-
loop {
627-
match &code {
628-
ObligationCauseCode::FunctionArgumentObligation { parent_code, .. } => {
629-
code = &parent_code;
630-
}
631-
ObligationCauseCode::ImplDerivedObligation(box ImplDerivedObligationCause {
632-
derived: DerivedObligationCause { parent_code, parent_trait_pred },
633-
..
634-
})
635-
| ObligationCauseCode::BuiltinDerivedObligation(DerivedObligationCause {
636-
parent_code,
637-
parent_trait_pred,
638-
})
639-
| ObligationCauseCode::DerivedObligation(DerivedObligationCause {
640-
parent_code,
641-
parent_trait_pred,
642-
}) => {
643-
code = &parent_code;
644-
real_trait_pred = *parent_trait_pred;
645-
}
646-
_ => break,
647-
};
626+
while let Some((parent_code, parent_trait_pred)) = code.parent() {
627+
code = parent_code;
628+
if let Some(parent_trait_pred) = parent_trait_pred {
629+
real_trait_pred = parent_trait_pred;
630+
}
648631
let Some(real_ty) = real_trait_pred.self_ty().no_bound_vars() else {
649632
continue;
650633
};

0 commit comments

Comments
 (0)