@@ -125,6 +125,15 @@ impl<'tcx> ObligationCause<'tcx> {
125
125
self
126
126
}
127
127
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
+
128
137
pub fn to_constraint_category ( & self ) -> ConstraintCategory < ' tcx > {
129
138
match self . code ( ) {
130
139
ObligationCauseCode :: MatchImpl ( cause, _) => cause. to_constraint_category ( ) ,
@@ -278,6 +287,14 @@ pub enum ObligationCauseCode<'tcx> {
278
287
/// Derived obligation for WF goals.
279
288
WellFormedDerived ( DerivedCause < ' tcx > ) ,
280
289
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
+
281
298
/// Derived obligation refined to point at a specific argument in
282
299
/// a call or method expression.
283
300
FunctionArg {
@@ -437,36 +454,38 @@ pub enum WellFormedLoc {
437
454
} ,
438
455
}
439
456
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
-
454
457
impl < ' tcx > ObligationCauseCode < ' tcx > {
455
458
/// Returns the base obligation, ignoring derived obligations.
456
459
pub fn peel_derives ( & self ) -> & Self {
457
460
let mut base_cause = self ;
458
- while let Some ( ( parent_code, _ ) ) = base_cause. parent ( ) {
461
+ while let Some ( parent_code) = base_cause. parent ( ) {
459
462
base_cause = parent_code;
460
463
}
461
464
base_cause
462
465
}
463
466
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
+
464
483
/// Returns the base obligation and the base trait predicate, if any, ignoring
465
484
/// derived obligations.
466
485
pub fn peel_derives_with_predicate ( & self ) -> ( & Self , Option < ty:: PolyTraitPredicate < ' tcx > > ) {
467
486
let mut base_cause = self ;
468
487
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 ( ) {
470
489
base_cause = parent_code;
471
490
if let Some ( parent_pred) = parent_pred {
472
491
base_trait_pred = Some ( parent_pred) ;
@@ -476,7 +495,7 @@ impl<'tcx> ObligationCauseCode<'tcx> {
476
495
( base_cause, base_trait_pred)
477
496
}
478
497
479
- pub fn parent ( & self ) -> Option < ( & Self , Option < ty:: PolyTraitPredicate < ' tcx > > ) > {
498
+ pub fn parent_with_predicate ( & self ) -> Option < ( & Self , Option < ty:: PolyTraitPredicate < ' tcx > > ) > {
480
499
match self {
481
500
ObligationCauseCode :: FunctionArg { parent_code, .. } => Some ( ( parent_code, None ) ) ,
482
501
ObligationCauseCode :: BuiltinDerived ( derived)
@@ -573,6 +592,42 @@ pub struct DerivedCause<'tcx> {
573
592
pub parent_code : InternedObligationCauseCode < ' tcx > ,
574
593
}
575
594
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
+
576
631
#[ derive( Clone , Debug , PartialEq , Eq , TypeVisitable ) ]
577
632
pub enum SelectionError < ' tcx > {
578
633
/// The trait is not implemented.
0 commit comments