|
| 1 | +use std::fmt; |
| 2 | + |
1 | 3 | use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
|
2 | 4 | use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
|
3 | 5 |
|
@@ -67,3 +69,78 @@ impl<I: Interner> TraitRef<I> {
|
67 | 69 | self.args.type_at(0)
|
68 | 70 | }
|
69 | 71 | }
|
| 72 | + |
| 73 | +#[derive(derivative::Derivative)] |
| 74 | +#[derivative( |
| 75 | + Clone(bound = ""), |
| 76 | + Copy(bound = ""), |
| 77 | + Hash(bound = ""), |
| 78 | + PartialEq(bound = ""), |
| 79 | + Eq(bound = "") |
| 80 | +)] |
| 81 | +#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] |
| 82 | +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] |
| 83 | +pub struct TraitPredicate<I: Interner> { |
| 84 | + pub trait_ref: TraitRef<I>, |
| 85 | + |
| 86 | + /// If polarity is Positive: we are proving that the trait is implemented. |
| 87 | + /// |
| 88 | + /// If polarity is Negative: we are proving that a negative impl of this trait |
| 89 | + /// exists. (Note that coherence also checks whether negative impls of supertraits |
| 90 | + /// exist via a series of predicates.) |
| 91 | + /// |
| 92 | + /// If polarity is Reserved: that's a bug. |
| 93 | + pub polarity: PredicatePolarity, |
| 94 | +} |
| 95 | + |
| 96 | +impl<I: Interner> TraitPredicate<I> { |
| 97 | + pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self { |
| 98 | + Self { trait_ref: self.trait_ref.with_self_ty(interner, self_ty), polarity: self.polarity } |
| 99 | + } |
| 100 | + |
| 101 | + pub fn def_id(self) -> I::DefId { |
| 102 | + self.trait_ref.def_id |
| 103 | + } |
| 104 | + |
| 105 | + pub fn self_ty(self) -> I::Ty { |
| 106 | + self.trait_ref.self_ty() |
| 107 | + } |
| 108 | +} |
| 109 | + |
| 110 | +impl<I: Interner> fmt::Debug for TraitPredicate<I> { |
| 111 | + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 112 | + // FIXME(effects) printing? |
| 113 | + write!(f, "TraitPredicate({:?}, polarity:{:?})", self.trait_ref, self.polarity) |
| 114 | + } |
| 115 | +} |
| 116 | + |
| 117 | +/// Polarity for a trait predicate. May either be negative or positive. |
| 118 | +/// Distinguished from [`ImplPolarity`] since we never compute goals with |
| 119 | +/// "reservation" level. |
| 120 | +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] |
| 121 | +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] |
| 122 | +pub enum PredicatePolarity { |
| 123 | + /// `Type: Trait` |
| 124 | + Positive, |
| 125 | + /// `Type: !Trait` |
| 126 | + Negative, |
| 127 | +} |
| 128 | + |
| 129 | +impl PredicatePolarity { |
| 130 | + /// Flips polarity by turning `Positive` into `Negative` and `Negative` into `Positive`. |
| 131 | + pub fn flip(&self) -> PredicatePolarity { |
| 132 | + match self { |
| 133 | + PredicatePolarity::Positive => PredicatePolarity::Negative, |
| 134 | + PredicatePolarity::Negative => PredicatePolarity::Positive, |
| 135 | + } |
| 136 | + } |
| 137 | +} |
| 138 | + |
| 139 | +impl fmt::Display for PredicatePolarity { |
| 140 | + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 141 | + match self { |
| 142 | + Self::Positive => f.write_str("positive"), |
| 143 | + Self::Negative => f.write_str("negative"), |
| 144 | + } |
| 145 | + } |
| 146 | +} |
0 commit comments