@@ -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