@@ -126,6 +126,15 @@ impl<'tcx> ObligationCause<'tcx> {
126126 self
127127 }
128128
129+ pub fn derived_host_cause (
130+ mut self ,
131+ parent_host_pred : ty:: Binder < ' tcx , ty:: HostEffectPredicate < ' tcx > > ,
132+ variant : impl FnOnce ( DerivedHostCause < ' tcx > ) -> ObligationCauseCode < ' tcx > ,
133+ ) -> ObligationCause < ' tcx > {
134+ self . code = variant ( DerivedHostCause { parent_host_pred, parent_code : self . code } ) . into ( ) ;
135+ self
136+ }
137+
129138 pub fn to_constraint_category ( & self ) -> ConstraintCategory < ' tcx > {
130139 match self . code ( ) {
131140 ObligationCauseCode :: MatchImpl ( cause, _) => cause. to_constraint_category ( ) ,
@@ -279,6 +288,14 @@ pub enum ObligationCauseCode<'tcx> {
279288 /// Derived obligation for WF goals.
280289 WellFormedDerived ( DerivedCause < ' tcx > ) ,
281290
291+ /// Derived obligation (i.e. `where` clause) on an user-provided impl
292+ /// or a trait alias.
293+ ImplDerivedHost ( Box < ImplDerivedHostCause < ' tcx > > ) ,
294+
295+ /// Derived obligation (i.e. `where` clause) on an user-provided impl
296+ /// or a trait alias.
297+ BuiltinDerivedHost ( DerivedHostCause < ' tcx > ) ,
298+
282299 /// Derived obligation refined to point at a specific argument in
283300 /// a call or method expression.
284301 FunctionArg {
@@ -438,36 +455,38 @@ pub enum WellFormedLoc {
438455 } ,
439456}
440457
441- #[ derive( Clone , Debug , PartialEq , Eq , HashStable , TyEncodable , TyDecodable ) ]
442- #[ derive( TypeVisitable , TypeFoldable ) ]
443- pub struct ImplDerivedCause < ' tcx > {
444- pub derived : DerivedCause < ' tcx > ,
445- /// The `DefId` of the `impl` that gave rise to the `derived` obligation.
446- /// If the `derived` obligation arose from a trait alias, which conceptually has a synthetic impl,
447- /// then this will be the `DefId` of that trait alias. Care should therefore be taken to handle
448- /// that exceptional case where appropriate.
449- pub impl_or_alias_def_id : DefId ,
450- /// The index of the derived predicate in the parent impl's predicates.
451- pub impl_def_predicate_index : Option < usize > ,
452- pub span : Span ,
453- }
454-
455458impl < ' tcx > ObligationCauseCode < ' tcx > {
456459 /// Returns the base obligation, ignoring derived obligations.
457460 pub fn peel_derives ( & self ) -> & Self {
458461 let mut base_cause = self ;
459- while let Some ( ( parent_code, _ ) ) = base_cause. parent ( ) {
462+ while let Some ( parent_code) = base_cause. parent ( ) {
460463 base_cause = parent_code;
461464 }
462465 base_cause
463466 }
464467
468+ pub fn parent ( & self ) -> Option < & Self > {
469+ match self {
470+ ObligationCauseCode :: FunctionArg { parent_code, .. } => Some ( parent_code) ,
471+ ObligationCauseCode :: BuiltinDerived ( derived)
472+ | ObligationCauseCode :: WellFormedDerived ( derived)
473+ | ObligationCauseCode :: ImplDerived ( box ImplDerivedCause { derived, .. } ) => {
474+ Some ( & derived. parent_code )
475+ }
476+ ObligationCauseCode :: BuiltinDerivedHost ( derived)
477+ | ObligationCauseCode :: ImplDerivedHost ( box ImplDerivedHostCause { derived, .. } ) => {
478+ Some ( & derived. parent_code )
479+ }
480+ _ => None ,
481+ }
482+ }
483+
465484 /// Returns the base obligation and the base trait predicate, if any, ignoring
466485 /// derived obligations.
467486 pub fn peel_derives_with_predicate ( & self ) -> ( & Self , Option < ty:: PolyTraitPredicate < ' tcx > > ) {
468487 let mut base_cause = self ;
469488 let mut base_trait_pred = None ;
470- while let Some ( ( parent_code, parent_pred) ) = base_cause. parent ( ) {
489+ while let Some ( ( parent_code, parent_pred) ) = base_cause. parent_with_predicate ( ) {
471490 base_cause = parent_code;
472491 if let Some ( parent_pred) = parent_pred {
473492 base_trait_pred = Some ( parent_pred) ;
@@ -477,7 +496,7 @@ impl<'tcx> ObligationCauseCode<'tcx> {
477496 ( base_cause, base_trait_pred)
478497 }
479498
480- pub fn parent ( & self ) -> Option < ( & Self , Option < ty:: PolyTraitPredicate < ' tcx > > ) > {
499+ pub fn parent_with_predicate ( & self ) -> Option < ( & Self , Option < ty:: PolyTraitPredicate < ' tcx > > ) > {
481500 match self {
482501 ObligationCauseCode :: FunctionArg { parent_code, .. } => Some ( ( parent_code, None ) ) ,
483502 ObligationCauseCode :: BuiltinDerived ( derived)
@@ -555,6 +574,42 @@ pub struct DerivedCause<'tcx> {
555574 pub parent_code : InternedObligationCauseCode < ' tcx > ,
556575}
557576
577+ #[ derive( Clone , Debug , PartialEq , Eq , HashStable , TyEncodable , TyDecodable ) ]
578+ #[ derive( TypeVisitable , TypeFoldable ) ]
579+ pub struct ImplDerivedCause < ' tcx > {
580+ pub derived : DerivedCause < ' tcx > ,
581+ /// The `DefId` of the `impl` that gave rise to the `derived` obligation.
582+ /// If the `derived` obligation arose from a trait alias, which conceptually has a synthetic impl,
583+ /// then this will be the `DefId` of that trait alias. Care should therefore be taken to handle
584+ /// that exceptional case where appropriate.
585+ pub impl_or_alias_def_id : DefId ,
586+ /// The index of the derived predicate in the parent impl's predicates.
587+ pub impl_def_predicate_index : Option < usize > ,
588+ pub span : Span ,
589+ }
590+
591+ #[ derive( Clone , Debug , PartialEq , Eq , HashStable , TyEncodable , TyDecodable ) ]
592+ #[ derive( TypeVisitable , TypeFoldable ) ]
593+ pub struct DerivedHostCause < ' tcx > {
594+ /// The trait predicate of the parent obligation that led to the
595+ /// current obligation. Note that only trait obligations lead to
596+ /// derived obligations, so we just store the trait predicate here
597+ /// directly.
598+ pub parent_host_pred : ty:: Binder < ' tcx , ty:: HostEffectPredicate < ' tcx > > ,
599+
600+ /// The parent trait had this cause.
601+ pub parent_code : InternedObligationCauseCode < ' tcx > ,
602+ }
603+
604+ #[ derive( Clone , Debug , PartialEq , Eq , HashStable , TyEncodable , TyDecodable ) ]
605+ #[ derive( TypeVisitable , TypeFoldable ) ]
606+ pub struct ImplDerivedHostCause < ' tcx > {
607+ pub derived : DerivedHostCause < ' tcx > ,
608+ /// The `DefId` of the `impl` that gave rise to the `derived` obligation.
609+ pub impl_def_id : DefId ,
610+ pub span : Span ,
611+ }
612+
558613#[ derive( Clone , Debug , PartialEq , Eq , TypeVisitable ) ]
559614pub enum SelectionError < ' tcx > {
560615 /// The trait is not implemented.
0 commit comments