about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/ich/impls_ty.rs8
-rw-r--r--src/librustc/traits/mod.rs22
-rw-r--r--src/librustc/traits/structural_impls.rs9
-rw-r--r--src/librustc_traits/lowering/environment.rs11
-rw-r--r--src/librustc_traits/lowering/mod.rs13
5 files changed, 55 insertions, 8 deletions
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
index 8df249d7341..36c0f30f0bf 100644
--- a/src/librustc/ich/impls_ty.rs
+++ b/src/librustc/ich/impls_ty.rs
@@ -1395,10 +1395,16 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::Goal<'tcx> {
 
 impl_stable_hash_for!(
     impl<'tcx> for struct traits::ProgramClause<'tcx> {
-        goal, hypotheses
+        goal, hypotheses, category
     }
 );
 
+impl_stable_hash_for!(enum traits::ProgramClauseCategory {
+    ImpliedBound,
+    WellFormed,
+    Other,
+});
+
 impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::Clause<'tcx> {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index 7bfb6f060cd..d129cd486cf 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -341,7 +341,8 @@ impl<'tcx> DomainGoal<'tcx> {
     pub fn into_program_clause(self) -> ProgramClause<'tcx> {
         ProgramClause {
             goal: self,
-            hypotheses: &ty::List::empty(),
+            hypotheses: ty::List::empty(),
+            category: ProgramClauseCategory::Other,
         }
     }
 }
@@ -369,6 +370,15 @@ pub enum Clause<'tcx> {
     ForAll(ty::Binder<ProgramClause<'tcx>>),
 }
 
+impl Clause<'tcx> {
+    pub fn category(self) -> ProgramClauseCategory {
+        match self {
+            Clause::Implies(clause) => clause.category,
+            Clause::ForAll(clause) => clause.skip_binder().category,
+        }
+    }
+}
+
 /// Multiple clauses.
 pub type Clauses<'tcx> = &'tcx List<Clause<'tcx>>;
 
@@ -385,6 +395,16 @@ pub struct ProgramClause<'tcx> {
 
     /// ...if we can prove these hypotheses (there may be no hypotheses at all):
     pub hypotheses: Goals<'tcx>,
+
+    /// Useful for filtering clauses.
+    pub category: ProgramClauseCategory,
+}
+
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
+pub enum ProgramClauseCategory {
+    ImpliedBound,
+    WellFormed,
+    Other,
 }
 
 /// A set of clauses that we assume to be true.
diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs
index 7b7446e27d2..c50c9703eb5 100644
--- a/src/librustc/traits/structural_impls.rs
+++ b/src/librustc/traits/structural_impls.rs
@@ -496,7 +496,7 @@ impl<'tcx> fmt::Display for traits::Goal<'tcx> {
 
 impl<'tcx> fmt::Display for traits::ProgramClause<'tcx> {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let traits::ProgramClause { goal, hypotheses } = self;
+        let traits::ProgramClause { goal, hypotheses, .. } = self;
         write!(fmt, "{}", goal)?;
         if !hypotheses.is_empty() {
             write!(fmt, " :- ")?;
@@ -647,10 +647,15 @@ impl<'tcx> TypeFoldable<'tcx> for traits::Goal<'tcx> {
 BraceStructTypeFoldableImpl! {
     impl<'tcx> TypeFoldable<'tcx> for traits::ProgramClause<'tcx> {
         goal,
-        hypotheses
+        hypotheses,
+        category,
     }
 }
 
+CloneTypeFoldableAndLiftImpls! {
+    traits::ProgramClauseCategory,
+}
+
 EnumTypeFoldableImpl! {
     impl<'tcx> TypeFoldable<'tcx> for traits::Clause<'tcx> {
         (traits::Clause::Implies)(clause),
diff --git a/src/librustc_traits/lowering/environment.rs b/src/librustc_traits/lowering/environment.rs
index 1f3fec46990..a1cdb622f37 100644
--- a/src/librustc_traits/lowering/environment.rs
+++ b/src/librustc_traits/lowering/environment.rs
@@ -14,6 +14,7 @@ use rustc::traits::{
     DomainGoal,
     FromEnv,
     ProgramClause,
+    ProgramClauseCategory,
     Environment,
 };
 use rustc::ty::{self, TyCtxt, Ty};
@@ -39,6 +40,7 @@ impl ClauseVisitor<'set, 'a, 'tcx> {
                 self.round.extend(
                     self.tcx.program_clauses_for(data.item_def_id)
                         .iter()
+                        .filter(|c| c.category() == ProgramClauseCategory::ImpliedBound)
                         .cloned()
                 );
             }
@@ -56,6 +58,7 @@ impl ClauseVisitor<'set, 'a, 'tcx> {
                 self.round.extend(
                     self.tcx.program_clauses_for(def.did)
                         .iter()
+                        .filter(|c| c.category() == ProgramClauseCategory::ImpliedBound)
                         .cloned()
                 );
             }
@@ -68,6 +71,7 @@ impl ClauseVisitor<'set, 'a, 'tcx> {
                 self.round.extend(
                     self.tcx.program_clauses_for(def_id)
                         .iter()
+                        .filter(|c| c.category() == ProgramClauseCategory::ImpliedBound)
                         .cloned()
                 );
             }
@@ -98,6 +102,7 @@ impl ClauseVisitor<'set, 'a, 'tcx> {
                 self.round.extend(
                     self.tcx.program_clauses_for(predicate.def_id())
                         .iter()
+                        .filter(|c| c.category() == ProgramClauseCategory::ImpliedBound)
                         .cloned()
                 );
             }
@@ -176,7 +181,7 @@ crate fn environment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> En
     // Compute the bounds on `Self` and the type parameters.
     let ty::InstantiatedPredicates { predicates } =
         tcx.predicates_of(def_id).instantiate_identity(tcx);
-    
+
     let clauses = predicates.into_iter()
         .map(|predicate| predicate.lower())
         .map(|domain_goal| domain_goal.map_bound(|bound| bound.into_from_env_goal()))
@@ -185,7 +190,7 @@ crate fn environment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> En
         // `ForAll` because each `domain_goal` is a `PolyDomainGoal` and
         // could bound lifetimes.
         .map(Clause::ForAll);
-    
+
     let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
     let node = tcx.hir.get(node_id);
 
@@ -243,7 +248,7 @@ crate fn environment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> En
             .map(|domain_goal| domain_goal.into_program_clause())
             .map(Clause::Implies)
     );
-    
+
     Environment {
         clauses: tcx.mk_clauses(clauses),
     }
diff --git a/src/librustc_traits/lowering/mod.rs b/src/librustc_traits/lowering/mod.rs
index a6bf28b6ad8..fb598a33548 100644
--- a/src/librustc_traits/lowering/mod.rs
+++ b/src/librustc_traits/lowering/mod.rs
@@ -22,6 +22,7 @@ use rustc::traits::{
     GoalKind,
     PolyDomainGoal,
     ProgramClause,
+    ProgramClauseCategory,
     WellFormed,
     WhereClause,
 };
@@ -204,6 +205,7 @@ fn program_clauses_for_trait<'a, 'tcx>(
     let implemented_from_env = ProgramClause {
         goal: impl_trait,
         hypotheses,
+        category: ProgramClauseCategory::ImpliedBound,
     };
 
     let clauses = iter::once(Clause::ForAll(ty::Binder::dummy(implemented_from_env)));
@@ -231,6 +233,7 @@ fn program_clauses_for_trait<'a, 'tcx>(
         .map(|wc| wc.map_bound(|goal| ProgramClause {
             goal: goal.into_from_env_goal(),
             hypotheses,
+            category: ProgramClauseCategory::ImpliedBound,
         }))
         .map(Clause::ForAll);
 
@@ -257,6 +260,7 @@ fn program_clauses_for_trait<'a, 'tcx>(
         hypotheses: tcx.mk_goals(
             wf_conditions.map(|wc| tcx.mk_goal(GoalKind::from_poly_domain_goal(wc, tcx))),
         ),
+        category: ProgramClauseCategory::WellFormed,
     };
     let wf_clause = iter::once(Clause::ForAll(ty::Binder::dummy(wf_clause)));
 
@@ -299,6 +303,7 @@ fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId
             where_clauses
                 .map(|wc| tcx.mk_goal(GoalKind::from_poly_domain_goal(wc, tcx))),
         ),
+        category: ProgramClauseCategory::Other,
     };
     tcx.mk_clauses(iter::once(Clause::ForAll(ty::Binder::dummy(clause))))
 }
@@ -335,6 +340,7 @@ pub fn program_clauses_for_type_def<'a, 'tcx>(
                 .cloned()
                 .map(|wc| tcx.mk_goal(GoalKind::from_poly_domain_goal(wc, tcx))),
         ),
+        category: ProgramClauseCategory::WellFormed,
     };
 
     let well_formed_clause = iter::once(Clause::ForAll(ty::Binder::dummy(well_formed)));
@@ -360,6 +366,7 @@ pub fn program_clauses_for_type_def<'a, 'tcx>(
         .map(|wc| wc.map_bound(|goal| ProgramClause {
             goal: goal.into_from_env_goal(),
             hypotheses,
+            category: ProgramClauseCategory::ImpliedBound,
         }))
 
         .map(Clause::ForAll);
@@ -407,7 +414,8 @@ pub fn program_clauses_for_associated_type_def<'a, 'tcx>(
 
     let projection_eq_clause = ProgramClause {
         goal: DomainGoal::Holds(projection_eq),
-        hypotheses: &ty::List::empty(),
+        hypotheses: ty::List::empty(),
+        category: ProgramClauseCategory::Other,
     };
 
     // Rule WellFormed-AssocTy
@@ -425,6 +433,7 @@ pub fn program_clauses_for_associated_type_def<'a, 'tcx>(
     let wf_clause = ProgramClause {
         goal: DomainGoal::WellFormed(WellFormed::Ty(placeholder_ty)),
         hypotheses: tcx.mk_goals(iter::once(hypothesis)),
+        category: ProgramClauseCategory::Other,
     };
 
     // Rule Implied-Trait-From-AssocTy
@@ -441,6 +450,7 @@ pub fn program_clauses_for_associated_type_def<'a, 'tcx>(
     let from_env_clause = ProgramClause {
         goal: DomainGoal::FromEnv(FromEnv::Trait(trait_predicate)),
         hypotheses: tcx.mk_goals(iter::once(hypothesis)),
+        category: ProgramClauseCategory::ImpliedBound,
     };
 
     let clauses = iter::once(projection_eq_clause)
@@ -506,6 +516,7 @@ pub fn program_clauses_for_associated_type_value<'a, 'tcx>(
                 .into_iter()
                 .map(|wc| tcx.mk_goal(GoalKind::from_poly_domain_goal(wc, tcx))),
         ),
+        category: ProgramClauseCategory::Other,
     };
     tcx.mk_clauses(iter::once(Clause::ForAll(ty::Binder::dummy(clause))))
 }