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