@@ -125,6 +125,15 @@ impl<'tcx> ObligationCause<'tcx> {
125125 self
126126 }
127127
128+ pub fn derived_host_cause (
129+ mut self ,
130+ parent_host_pred : ty:: Binder < ' tcx , ty:: HostEffectPredicate < ' tcx > > ,
131+ variant : impl FnOnce ( DerivedHostCause < ' tcx > ) -> ObligationCauseCode < ' tcx > ,
132+ ) -> ObligationCause < ' tcx > {
133+ self . code = variant ( DerivedHostCause { parent_host_pred, parent_code : self . code } ) . into ( ) ;
134+ self
135+ }
136+
128137 pub fn to_constraint_category ( & self ) -> ConstraintCategory < ' tcx > {
129138 match self . code ( ) {
130139 ObligationCauseCode :: MatchImpl ( cause, _) => cause. to_constraint_category ( ) ,
@@ -278,6 +287,14 @@ pub enum ObligationCauseCode<'tcx> {
278287 /// Derived obligation for WF goals.
279288 WellFormedDerived ( DerivedCause < ' tcx > ) ,
280289
290+ /// Derived obligation (i.e. `where` clause) on an user-provided impl
291+ /// or a trait alias.
292+ ImplDerivedHost ( Box < ImplDerivedHostCause < ' tcx > > ) ,
293+
294+ /// Derived obligation (i.e. `where` clause) on an user-provided impl
295+ /// or a trait alias.
296+ BuiltinDerivedHost ( DerivedHostCause < ' tcx > ) ,
297+
281298 /// Derived obligation refined to point at a specific argument in
282299 /// a call or method expression.
283300 FunctionArg {
@@ -437,36 +454,38 @@ pub enum WellFormedLoc {
437454 } ,
438455}
439456
440- #[ derive( Clone , Debug , PartialEq , Eq , HashStable , TyEncodable , TyDecodable ) ]
441- #[ derive( TypeVisitable , TypeFoldable ) ]
442- pub struct ImplDerivedCause < ' tcx > {
443- pub derived : DerivedCause < ' tcx > ,
444- /// The `DefId` of the `impl` that gave rise to the `derived` obligation.
445- /// If the `derived` obligation arose from a trait alias, which conceptually has a synthetic impl,
446- /// then this will be the `DefId` of that trait alias. Care should therefore be taken to handle
447- /// that exceptional case where appropriate.
448- pub impl_or_alias_def_id : DefId ,
449- /// The index of the derived predicate in the parent impl's predicates.
450- pub impl_def_predicate_index : Option < usize > ,
451- pub span : Span ,
452- }
453-
454457impl < ' tcx > ObligationCauseCode < ' tcx > {
455458 /// Returns the base obligation, ignoring derived obligations.
456459 pub fn peel_derives ( & self ) -> & Self {
457460 let mut base_cause = self ;
458- while let Some ( ( parent_code, _ ) ) = base_cause. parent ( ) {
461+ while let Some ( parent_code) = base_cause. parent ( ) {
459462 base_cause = parent_code;
460463 }
461464 base_cause
462465 }
463466
467+ pub fn parent ( & self ) -> Option < & Self > {
468+ match self {
469+ ObligationCauseCode :: FunctionArg { parent_code, .. } => Some ( parent_code) ,
470+ ObligationCauseCode :: BuiltinDerived ( derived)
471+ | ObligationCauseCode :: WellFormedDerived ( derived)
472+ | ObligationCauseCode :: ImplDerived ( box ImplDerivedCause { derived, .. } ) => {
473+ Some ( & derived. parent_code )
474+ }
475+ ObligationCauseCode :: BuiltinDerivedHost ( derived)
476+ | ObligationCauseCode :: ImplDerivedHost ( box ImplDerivedHostCause { derived, .. } ) => {
477+ Some ( & derived. parent_code )
478+ }
479+ _ => None ,
480+ }
481+ }
482+
464483 /// Returns the base obligation and the base trait predicate, if any, ignoring
465484 /// derived obligations.
466485 pub fn peel_derives_with_predicate ( & self ) -> ( & Self , Option < ty:: PolyTraitPredicate < ' tcx > > ) {
467486 let mut base_cause = self ;
468487 let mut base_trait_pred = None ;
469- while let Some ( ( parent_code, parent_pred) ) = base_cause. parent ( ) {
488+ while let Some ( ( parent_code, parent_pred) ) = base_cause. parent_with_predicate ( ) {
470489 base_cause = parent_code;
471490 if let Some ( parent_pred) = parent_pred {
472491 base_trait_pred = Some ( parent_pred) ;
@@ -476,7 +495,7 @@ impl<'tcx> ObligationCauseCode<'tcx> {
476495 ( base_cause, base_trait_pred)
477496 }
478497
479- pub fn parent ( & self ) -> Option < ( & Self , Option < ty:: PolyTraitPredicate < ' tcx > > ) > {
498+ pub fn parent_with_predicate ( & self ) -> Option < ( & Self , Option < ty:: PolyTraitPredicate < ' tcx > > ) > {
480499 match self {
481500 ObligationCauseCode :: FunctionArg { parent_code, .. } => Some ( ( parent_code, None ) ) ,
482501 ObligationCauseCode :: BuiltinDerived ( derived)
@@ -573,6 +592,42 @@ pub struct DerivedCause<'tcx> {
573592 pub parent_code : InternedObligationCauseCode < ' tcx > ,
574593}
575594
595+ #[ derive( Clone , Debug , PartialEq , Eq , HashStable , TyEncodable , TyDecodable ) ]
596+ #[ derive( TypeVisitable , TypeFoldable ) ]
597+ pub struct ImplDerivedCause < ' tcx > {
598+ pub derived : DerivedCause < ' tcx > ,
599+ /// The `DefId` of the `impl` that gave rise to the `derived` obligation.
600+ /// If the `derived` obligation arose from a trait alias, which conceptually has a synthetic impl,
601+ /// then this will be the `DefId` of that trait alias. Care should therefore be taken to handle
602+ /// that exceptional case where appropriate.
603+ pub impl_or_alias_def_id : DefId ,
604+ /// The index of the derived predicate in the parent impl's predicates.
605+ pub impl_def_predicate_index : Option < usize > ,
606+ pub span : Span ,
607+ }
608+
609+ #[ derive( Clone , Debug , PartialEq , Eq , HashStable , TyEncodable , TyDecodable ) ]
610+ #[ derive( TypeVisitable , TypeFoldable ) ]
611+ pub struct DerivedHostCause < ' tcx > {
612+ /// The trait predicate of the parent obligation that led to the
613+ /// current obligation. Note that only trait obligations lead to
614+ /// derived obligations, so we just store the trait predicate here
615+ /// directly.
616+ pub parent_host_pred : ty:: Binder < ' tcx , ty:: HostEffectPredicate < ' tcx > > ,
617+
618+ /// The parent trait had this cause.
619+ pub parent_code : InternedObligationCauseCode < ' tcx > ,
620+ }
621+
622+ #[ derive( Clone , Debug , PartialEq , Eq , HashStable , TyEncodable , TyDecodable ) ]
623+ #[ derive( TypeVisitable , TypeFoldable ) ]
624+ pub struct ImplDerivedHostCause < ' tcx > {
625+ pub derived : DerivedHostCause < ' tcx > ,
626+ /// The `DefId` of the `impl` that gave rise to the `derived` obligation.
627+ pub impl_def_id : DefId ,
628+ pub span : Span ,
629+ }
630+
576631#[ derive( Clone , Debug , PartialEq , Eq , TypeVisitable ) ]
577632pub enum SelectionError < ' tcx > {
578633 /// The trait is not implemented.
0 commit comments