]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_middle/ty/structural_impls.rs
introduce PredicateAtom
[rust.git] / src / librustc_middle / ty / structural_impls.rs
index 159af277d240b56bbd3b31e8a714bee702f8dea0..cfe076e12070267024cc1046aed8f3b85cbac3c4 100644 (file)
@@ -226,27 +226,36 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 impl fmt::Debug for ty::PredicateKind<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match *self {
-            ty::PredicateKind::Trait(ref a, constness) => {
+            ty::PredicateKind::ForAll(binder) => write!(f, "ForAll({:?})", binder),
+            ty::PredicateKind::Atom(atom) => write!(f, "{:?}", atom),
+        }
+    }
+}
+
+impl fmt::Debug for ty::PredicateAtom<'tcx> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match *self {
+            ty::PredicateAtom::Trait(ref a, constness) => {
                 if let hir::Constness::Const = constness {
                     write!(f, "const ")?;
                 }
                 a.fmt(f)
             }
-            ty::PredicateKind::Subtype(ref pair) => pair.fmt(f),
-            ty::PredicateKind::RegionOutlives(ref pair) => pair.fmt(f),
-            ty::PredicateKind::TypeOutlives(ref pair) => pair.fmt(f),
-            ty::PredicateKind::Projection(ref pair) => pair.fmt(f),
-            ty::PredicateKind::WellFormed(data) => write!(f, "WellFormed({:?})", data),
-            ty::PredicateKind::ObjectSafe(trait_def_id) => {
+            ty::PredicateAtom::Subtype(ref pair) => pair.fmt(f),
+            ty::PredicateAtom::RegionOutlives(ref pair) => pair.fmt(f),
+            ty::PredicateAtom::TypeOutlives(ref pair) => pair.fmt(f),
+            ty::PredicateAtom::Projection(ref pair) => pair.fmt(f),
+            ty::PredicateAtom::WellFormed(data) => write!(f, "WellFormed({:?})", data),
+            ty::PredicateAtom::ObjectSafe(trait_def_id) => {
                 write!(f, "ObjectSafe({:?})", trait_def_id)
             }
-            ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind) => {
+            ty::PredicateAtom::ClosureKind(closure_def_id, closure_substs, kind) => {
                 write!(f, "ClosureKind({:?}, {:?}, {:?})", closure_def_id, closure_substs, kind)
             }
-            ty::PredicateKind::ConstEvaluatable(def_id, substs) => {
+            ty::PredicateAtom::ConstEvaluatable(def_id, substs) => {
                 write!(f, "ConstEvaluatable({:?}, {:?})", def_id, substs)
             }
-            ty::PredicateKind::ConstEquate(c1, c2) => write!(f, "ConstEquate({:?}, {:?})", c1, c2),
+            ty::PredicateAtom::ConstEquate(c1, c2) => write!(f, "ConstEquate({:?}, {:?})", c1, c2),
         }
     }
 }
@@ -272,6 +281,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     ::rustc_span::symbol::Symbol,
     ::rustc_hir::def::Res,
     ::rustc_hir::def_id::DefId,
+    ::rustc_hir::def_id::LocalDefId,
     ::rustc_hir::LlvmInlineAsmInner,
     ::rustc_hir::MatchSource,
     ::rustc_hir::Mutability,
@@ -477,35 +487,45 @@ impl<'a, 'tcx> Lift<'tcx> for ty::PredicateKind<'a> {
     type Lifted = ty::PredicateKind<'tcx>;
     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         match *self {
-            ty::PredicateKind::Trait(ref binder, constness) => {
-                tcx.lift(binder).map(|binder| ty::PredicateKind::Trait(binder, constness))
+            ty::PredicateKind::ForAll(ref binder) => {
+                tcx.lift(binder).map(ty::PredicateKind::ForAll)
             }
-            ty::PredicateKind::Subtype(ref binder) => {
-                tcx.lift(binder).map(ty::PredicateKind::Subtype)
+            ty::PredicateKind::Atom(ref atom) => tcx.lift(atom).map(ty::PredicateKind::Atom),
+        }
+    }
+}
+
+impl<'a, 'tcx> Lift<'tcx> for ty::PredicateAtom<'a> {
+    type Lifted = ty::PredicateAtom<'tcx>;
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
+        match *self {
+            ty::PredicateAtom::Trait(ref data, constness) => {
+                tcx.lift(data).map(|data| ty::PredicateAtom::Trait(data, constness))
             }
-            ty::PredicateKind::RegionOutlives(ref binder) => {
-                tcx.lift(binder).map(ty::PredicateKind::RegionOutlives)
+            ty::PredicateAtom::Subtype(ref data) => tcx.lift(data).map(ty::PredicateAtom::Subtype),
+            ty::PredicateAtom::RegionOutlives(ref data) => {
+                tcx.lift(data).map(ty::PredicateAtom::RegionOutlives)
             }
-            ty::PredicateKind::TypeOutlives(ref binder) => {
-                tcx.lift(binder).map(ty::PredicateKind::TypeOutlives)
+            ty::PredicateAtom::TypeOutlives(ref data) => {
+                tcx.lift(data).map(ty::PredicateAtom::TypeOutlives)
             }
-            ty::PredicateKind::Projection(ref binder) => {
-                tcx.lift(binder).map(ty::PredicateKind::Projection)
+            ty::PredicateAtom::Projection(ref data) => {
+                tcx.lift(data).map(ty::PredicateAtom::Projection)
             }
-            ty::PredicateKind::WellFormed(ty) => tcx.lift(&ty).map(ty::PredicateKind::WellFormed),
-            ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind) => {
+            ty::PredicateAtom::WellFormed(ty) => tcx.lift(&ty).map(ty::PredicateAtom::WellFormed),
+            ty::PredicateAtom::ClosureKind(closure_def_id, closure_substs, kind) => {
                 tcx.lift(&closure_substs).map(|closure_substs| {
-                    ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind)
+                    ty::PredicateAtom::ClosureKind(closure_def_id, closure_substs, kind)
                 })
             }
-            ty::PredicateKind::ObjectSafe(trait_def_id) => {
-                Some(ty::PredicateKind::ObjectSafe(trait_def_id))
+            ty::PredicateAtom::ObjectSafe(trait_def_id) => {
+                Some(ty::PredicateAtom::ObjectSafe(trait_def_id))
             }
-            ty::PredicateKind::ConstEvaluatable(def_id, substs) => {
-                tcx.lift(&substs).map(|substs| ty::PredicateKind::ConstEvaluatable(def_id, substs))
+            ty::PredicateAtom::ConstEvaluatable(def_id, substs) => {
+                tcx.lift(&substs).map(|substs| ty::PredicateAtom::ConstEvaluatable(def_id, substs))
             }
-            ty::PredicateKind::ConstEquate(c1, c2) => {
-                tcx.lift(&(c1, c2)).map(|(c1, c2)| ty::PredicateKind::ConstEquate(c1, c2))
+            ty::PredicateAtom::ConstEquate(c1, c2) => {
+                tcx.lift(&(c1, c2)).map(|(c1, c2)| ty::PredicateAtom::ConstEquate(c1, c2))
             }
         }
     }
@@ -719,6 +739,18 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
     }
 }
 
+impl<'tcx, A: TypeFoldable<'tcx>, B: TypeFoldable<'tcx>, C: TypeFoldable<'tcx>> TypeFoldable<'tcx>
+    for (A, B, C)
+{
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> (A, B, C) {
+        (self.0.fold_with(folder), self.1.fold_with(folder), self.2.fold_with(folder))
+    }
+
+    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
+        self.0.visit_with(visitor) || self.1.visit_with(visitor) || self.2.visit_with(visitor)
+    }
+}
+
 EnumTypeFoldableImpl! {
     impl<'tcx, T> TypeFoldable<'tcx> for Option<T> {
         (Some)(a),
@@ -838,7 +870,7 @@ fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         Self {
             substs: self.substs.fold_with(folder),
             def: match self.def {
-                Item(did) => Item(did.fold_with(folder)),
+                Item(def) => Item(def.fold_with(folder)),
                 VtableShim(did) => VtableShim(did.fold_with(folder)),
                 ReifyShim(did) => ReifyShim(did.fold_with(folder)),
                 Intrinsic(did) => Intrinsic(did.fold_with(folder)),
@@ -857,7 +889,8 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
         use crate::ty::InstanceDef::*;
         self.substs.visit_with(visitor)
             || match self.def {
-                Item(did) | VtableShim(did) | ReifyShim(did) | Intrinsic(did) | Virtual(did, _) => {
+                Item(def) => def.visit_with(visitor),
+                VtableShim(did) | ReifyShim(did) | Intrinsic(did) | Virtual(did, _) => {
                     did.visit_with(visitor)
                 }
                 FnPtrShim(did, ty) | CloneShim(did, ty) => {
@@ -984,7 +1017,7 @@ fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
 impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
     fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         let new = ty::PredicateKind::super_fold_with(&self.inner.kind, folder);
-        if new != self.inner.kind { folder.tcx().mk_predicate(new) } else { *self }
+        folder.tcx().reuse_or_mk_predicate(*self, new)
     }
 
     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {