]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_trait_selection/traits/select/mod.rs
introduce PredicateAtom
[rust.git] / src / librustc_trait_selection / traits / select / mod.rs
index ba5e60012da19616b0d4a9dfe9f5cd104a09f3c9..4123f2938261c6478e92a14e79a8d425fff26ac8 100644 (file)
@@ -35,7 +35,9 @@
 use rustc_middle::ty::fast_reject;
 use rustc_middle::ty::relate::TypeRelation;
 use rustc_middle::ty::subst::{GenericArgKind, Subst, SubstsRef};
-use rustc_middle::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable};
+use rustc_middle::ty::{
+    self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness,
+};
 use rustc_span::symbol::sym;
 
 use std::cell::{Cell, RefCell};
@@ -406,14 +408,16 @@ fn evaluate_predicate_recursively<'o>(
             None => self.check_recursion_limit(&obligation, &obligation)?,
         }
 
-        match obligation.predicate.kind() {
-            &ty::PredicateKind::Trait(t, _) => {
+        match obligation.predicate.skip_binders() {
+            ty::PredicateAtom::Trait(t, _) => {
+                let t = ty::Binder::bind(t);
                 debug_assert!(!t.has_escaping_bound_vars());
                 let obligation = obligation.with(t);
                 self.evaluate_trait_predicate_recursively(previous_stack, obligation)
             }
 
-            &ty::PredicateKind::Subtype(p) => {
+            ty::PredicateAtom::Subtype(p) => {
+                let p = ty::Binder::bind(p);
                 // Does this code ever run?
                 match self.infcx.subtype_predicate(&obligation.cause, obligation.param_env, p) {
                     Some(Ok(InferOk { mut obligations, .. })) => {
@@ -428,7 +432,7 @@ fn evaluate_predicate_recursively<'o>(
                 }
             }
 
-            &ty::PredicateKind::WellFormed(arg) => match wf::obligations(
+            ty::PredicateAtom::WellFormed(arg) => match wf::obligations(
                 self.infcx,
                 obligation.param_env,
                 obligation.cause.body_id,
@@ -442,12 +446,12 @@ fn evaluate_predicate_recursively<'o>(
                 None => Ok(EvaluatedToAmbig),
             },
 
-            ty::PredicateKind::TypeOutlives(..) | ty::PredicateKind::RegionOutlives(..) => {
+            ty::PredicateAtom::TypeOutlives(..) | ty::PredicateAtom::RegionOutlives(..) => {
                 // We do not consider region relationships when evaluating trait matches.
                 Ok(EvaluatedToOkModuloRegions)
             }
 
-            &ty::PredicateKind::ObjectSafe(trait_def_id) => {
+            ty::PredicateAtom::ObjectSafe(trait_def_id) => {
                 if self.tcx().is_object_safe(trait_def_id) {
                     Ok(EvaluatedToOk)
                 } else {
@@ -455,7 +459,8 @@ fn evaluate_predicate_recursively<'o>(
                 }
             }
 
-            &ty::PredicateKind::Projection(data) => {
+            ty::PredicateAtom::Projection(data) => {
+                let data = ty::Binder::bind(data);
                 let project_obligation = obligation.with(data);
                 match project::poly_project_and_unify_type(self, &project_obligation) {
                     Ok(Some(mut subobligations)) => {
@@ -476,7 +481,7 @@ fn evaluate_predicate_recursively<'o>(
                 }
             }
 
-            &ty::PredicateKind::ClosureKind(_, closure_substs, kind) => {
+            ty::PredicateAtom::ClosureKind(_, closure_substs, kind) => {
                 match self.infcx.closure_kind(closure_substs) {
                     Some(closure_kind) => {
                         if closure_kind.extends(kind) {
@@ -489,7 +494,7 @@ fn evaluate_predicate_recursively<'o>(
                 }
             }
 
-            &ty::PredicateKind::ConstEvaluatable(def_id, substs) => {
+            ty::PredicateAtom::ConstEvaluatable(def_id, substs) => {
                 match self.tcx().const_eval_resolve(
                     obligation.param_env,
                     def_id,
@@ -503,15 +508,15 @@ fn evaluate_predicate_recursively<'o>(
                 }
             }
 
-            ty::PredicateKind::ConstEquate(c1, c2) => {
+            ty::PredicateAtom::ConstEquate(c1, c2) => {
                 debug!("evaluate_predicate_recursively: equating consts c1={:?} c2={:?}", c1, c2);
 
                 let evaluate = |c: &'tcx ty::Const<'tcx>| {
-                    if let ty::ConstKind::Unevaluated(def_id, substs, promoted) = c.val {
+                    if let ty::ConstKind::Unevaluated(def, substs, promoted) = c.val {
                         self.infcx
                             .const_eval_resolve(
                                 obligation.param_env,
-                                def_id,
+                                def,
                                 substs,
                                 promoted,
                                 Some(obligation.cause.span),
@@ -669,10 +674,8 @@ fn check_evaluation_cycle(
             // if the regions match exactly.
             let cycle = stack.iter().skip(1).take_while(|s| s.depth >= cycle_depth);
             let tcx = self.tcx();
-            let cycle = cycle.map(|stack| {
-                ty::PredicateKind::Trait(stack.obligation.predicate, hir::Constness::NotConst)
-                    .to_predicate(tcx)
-            });
+            let cycle =
+                cycle.map(|stack| stack.obligation.predicate.without_const().to_predicate(tcx));
             if self.coinductive_match(cycle) {
                 debug!("evaluate_stack({:?}) --> recursive, coinductive", stack.fresh_trait_ref);
                 Some(EvaluatedToOk)
@@ -786,8 +789,8 @@ pub fn coinductive_match<I>(&mut self, cycle: I) -> bool
     }
 
     fn coinductive_predicate(&self, predicate: ty::Predicate<'tcx>) -> bool {
-        let result = match predicate.kind() {
-            ty::PredicateKind::Trait(ref data, _) => self.tcx().trait_is_auto(data.def_id()),
+        let result = match predicate.skip_binders() {
+            ty::PredicateAtom::Trait(ref data, _) => self.tcx().trait_is_auto(data.def_id()),
             _ => false,
         };
         debug!("coinductive_predicate({:?}) = {:?}", predicate, result);
@@ -1295,8 +1298,8 @@ fn match_projection_obligation_against_definition_bounds(
         };
 
         let matching_bound = predicates.iter().find_map(|bound| {
-            if let ty::PredicateKind::Trait(bound, _) = bound.kind() {
-                let bound = bound.to_poly_trait_ref();
+            if let ty::PredicateAtom::Trait(pred, _) = bound.skip_binders() {
+                let bound = ty::Binder::bind(pred.trait_ref);
                 if self.infcx.probe(|_| {
                     self.match_projection(obligation, bound, placeholder_trait_predicate.trait_ref)
                 }) {