diff options
| author | Michael Goulet <michael@errs.io> | 2023-06-16 06:27:41 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2023-06-19 15:46:08 +0000 |
| commit | 21226eefb2e2465b9730c37e7d08655865610d90 (patch) | |
| tree | 9145dee39689d2d919b3a4aae366eaf763c0da47 /compiler/rustc_middle/src | |
| parent | fca56a8d2c6f803aeec51167dd4dd22529f8bdd7 (diff) | |
Fully fledged Clause type
Diffstat (limited to 'compiler/rustc_middle/src')
| -rw-r--r-- | compiler/rustc_middle/src/ty/mod.rs | 113 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/structural_impls.rs | 25 |
2 files changed, 93 insertions, 45 deletions
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index f43be1468e8..79739adbb6d 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -561,6 +561,42 @@ impl rustc_errors::IntoDiagnosticArg for Predicate<'_> { } } +/// TODO: doc +#[derive(Clone, Copy, PartialEq, Eq, Hash, HashStable)] +#[rustc_pass_by_value] +pub struct Clause<'tcx>(Interned<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>); + +impl<'tcx> Clause<'tcx> { + pub fn as_predicate(self) -> Predicate<'tcx> { + Predicate(self.0) + } + + pub fn kind(self) -> Binder<'tcx, ClauseKind<'tcx>> { + self.0.internee.map_bound(|kind| match kind { + PredicateKind::Clause(clause) => clause, + _ => unreachable!(), + }) + } + + pub fn as_trait_clause(self) -> Option<Binder<'tcx, TraitPredicate<'tcx>>> { + let clause = self.kind(); + if let ty::ClauseKind::Trait(trait_clause) = clause.skip_binder() { + Some(clause.rebind(trait_clause)) + } else { + None + } + } + + pub fn as_projection_clause(self) -> Option<Binder<'tcx, ProjectionPredicate<'tcx>>> { + let clause = self.kind(); + if let ty::ClauseKind::Projection(projection_clause) = clause.skip_binder() { + Some(clause.rebind(projection_clause)) + } else { + None + } + } +} + #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] /// A clause is something that can appear in where bounds or be inferred @@ -592,24 +628,6 @@ pub enum ClauseKind<'tcx> { ConstEvaluatable(ty::Const<'tcx>), } -impl<'tcx> Binder<'tcx, ClauseKind<'tcx>> { - pub fn as_trait_clause(self) -> Option<Binder<'tcx, TraitPredicate<'tcx>>> { - if let ty::ClauseKind::Trait(trait_clause) = self.skip_binder() { - Some(self.rebind(trait_clause)) - } else { - None - } - } - - pub fn as_projection_clause(self) -> Option<Binder<'tcx, ProjectionPredicate<'tcx>>> { - if let ty::ClauseKind::Projection(projection_clause) = self.skip_binder() { - Some(self.rebind(projection_clause)) - } else { - None - } - } -} - #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] pub enum PredicateKind<'tcx> { @@ -1222,6 +1240,13 @@ impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, ClauseKind<'tcx>> { } } +impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for Binder<'tcx, ClauseKind<'tcx>> { + #[inline(always)] + fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> { + tcx.mk_predicate(self.map_bound(|clause| ty::PredicateKind::Clause(clause))).expect_clause() + } +} + impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> { #[inline(always)] fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { @@ -1229,14 +1254,11 @@ impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> { } } -impl<'tcx> ToPredicate<'tcx, Binder<'tcx, ClauseKind<'tcx>>> for TraitRef<'tcx> { +impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for TraitRef<'tcx> { #[inline(always)] - fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> Binder<'tcx, ClauseKind<'tcx>> { - Binder::dummy(ClauseKind::Trait(TraitPredicate { - trait_ref: self, - constness: ty::BoundConstness::NotConst, - polarity: ty::ImplPolarity::Positive, - })) + fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> { + let p: Predicate<'tcx> = self.to_predicate(tcx); + p.expect_clause() } } @@ -1248,9 +1270,9 @@ impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, TraitRef<'tcx>> { } } -impl<'tcx> ToPredicate<'tcx, Binder<'tcx, ClauseKind<'tcx>>> for Binder<'tcx, TraitRef<'tcx>> { +impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for Binder<'tcx, TraitRef<'tcx>> { #[inline(always)] - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Binder<'tcx, ClauseKind<'tcx>> { + fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> { let pred: PolyTraitPredicate<'tcx> = self.to_predicate(tcx); pred.to_predicate(tcx) } @@ -1285,9 +1307,10 @@ impl<'tcx> ToPredicate<'tcx> for PolyTraitPredicate<'tcx> { } } -impl<'tcx> ToPredicate<'tcx, Binder<'tcx, ClauseKind<'tcx>>> for PolyTraitPredicate<'tcx> { - fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> Binder<'tcx, ClauseKind<'tcx>> { - self.map_bound(|p| ClauseKind::Trait(p)) +impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for PolyTraitPredicate<'tcx> { + fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> { + let p: Predicate<'tcx> = self.to_predicate(tcx); + p.expect_clause() } } @@ -1309,9 +1332,10 @@ impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> { } } -impl<'tcx> ToPredicate<'tcx, Binder<'tcx, ClauseKind<'tcx>>> for PolyProjectionPredicate<'tcx> { - fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> Binder<'tcx, ClauseKind<'tcx>> { - self.map_bound(|p| ClauseKind::Projection(p)) +impl<'tcx> ToPredicate<'tcx, Clause<'tcx>> for PolyProjectionPredicate<'tcx> { + fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> { + let p: Predicate<'tcx> = self.to_predicate(tcx); + p.expect_clause() } } @@ -1385,18 +1409,17 @@ impl<'tcx> Predicate<'tcx> { } } - pub fn as_clause(self) -> Option<Binder<'tcx, ClauseKind<'tcx>>> { - let predicate = self.kind(); - match predicate.skip_binder() { - PredicateKind::Clause(clause) => Some(predicate.rebind(clause)), - PredicateKind::AliasRelate(..) - | PredicateKind::Subtype(..) - | PredicateKind::Coerce(..) - | PredicateKind::ObjectSafe(..) - | PredicateKind::ClosureKind(..) - | PredicateKind::ConstEquate(..) - | PredicateKind::Ambiguous - | PredicateKind::TypeWellFormedFromEnv(..) => None, + pub fn as_clause(self) -> Option<Clause<'tcx>> { + match self.kind().skip_binder() { + PredicateKind::Clause(..) => Some(self.expect_clause()), + _ => None, + } + } + + pub fn expect_clause(self) -> Clause<'tcx> { + match self.kind().skip_binder() { + PredicateKind::Clause(..) => Clause(self.0), + _ => bug!(), } } } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index ebc4a3d22ad..e53e1e0a54c 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -171,6 +171,12 @@ impl<'tcx> fmt::Debug for ty::Predicate<'tcx> { } } +impl<'tcx> fmt::Debug for ty::Clause<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}", self.kind()) + } +} + impl<'tcx> fmt::Debug for ty::ClauseKind<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { @@ -654,12 +660,31 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::Predicate<'tcx> { } } +// FIXME(clause): This is wonky +impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::Clause<'tcx> { + fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { + Ok(folder + .try_fold_predicate(self.as_predicate())? + .as_clause() + .expect("no sensible folder would do this")) + } +} + impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Predicate<'tcx> { fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { visitor.visit_predicate(*self) } } +impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Clause<'tcx> { + fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { + visitor.visit_predicate(self.as_predicate()) + } +} + impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Predicate<'tcx> { fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( self, |
