about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorJack Huey <jack.huey@umassmed.edu>2020-05-01 12:36:18 -0400
committerJack Huey <jack.huey@umassmed.edu>2020-05-01 14:39:05 -0400
commitef0da3ba4eb5e03d904321bdd8cd8fd3eb8a30e5 (patch)
tree4d40801e69388786f492976a8b744d01f70a516c /src
parenta91d64873f5b8daa43f0e82dedad7e2bc39e8fba (diff)
downloadrust-ef0da3ba4eb5e03d904321bdd8cd8fd3eb8a30e5.tar.gz
rust-ef0da3ba4eb5e03d904321bdd8cd8fd3eb8a30e5.zip
Remove leftover chalk types
Diffstat (limited to 'src')
-rw-r--r--src/librustc_infer/infer/canonical/query_response.rs6
-rw-r--r--src/librustc_infer/infer/nll_relate/mod.rs13
-rw-r--r--src/librustc_interface/passes.rs4
-rw-r--r--src/librustc_middle/dep_graph/dep_node.rs1
-rw-r--r--src/librustc_middle/query/mod.rs14
-rw-r--r--src/librustc_middle/traits/mod.rs158
-rw-r--r--src/librustc_middle/traits/structural_impls.rs355
-rw-r--r--src/librustc_middle/ty/context.rs52
-rw-r--r--src/librustc_middle/ty/query/keys.rs12
-rw-r--r--src/librustc_middle/ty/query/mod.rs1
-rw-r--r--src/librustc_middle/ty/relate.rs224
-rw-r--r--src/librustc_middle/ty/subst.rs32
-rw-r--r--src/librustc_mir/borrow_check/type_check/relate_tys.rs5
-rw-r--r--src/librustc_traits/lib.rs2
-rw-r--r--src/librustc_traits/lowering/environment.rs267
-rw-r--r--src/librustc_traits/lowering/mod.rs627
16 files changed, 5 insertions, 1768 deletions
diff --git a/src/librustc_infer/infer/canonical/query_response.rs b/src/librustc_infer/infer/canonical/query_response.rs
index 79a0a507624..9fe7ebf58b3 100644
--- a/src/librustc_infer/infer/canonical/query_response.rs
+++ b/src/librustc_infer/infer/canonical/query_response.rs
@@ -16,7 +16,7 @@ use crate::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRelating
 use crate::infer::region_constraints::{Constraint, RegionConstraintData};
 use crate::infer::{InferCtxt, InferOk, InferResult, NLLRegionVariableOrigin};
 use crate::traits::query::{Fallible, NoSolution};
-use crate::traits::{DomainGoal, TraitEngine};
+use crate::traits::TraitEngine;
 use crate::traits::{Obligation, ObligationCause, PredicateObligation};
 use rustc_data_structures::captures::Captures;
 use rustc_index::vec::Idx;
@@ -671,10 +671,6 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> {
         });
     }
 
-    fn push_domain_goal(&mut self, _: DomainGoal<'tcx>) {
-        bug!("should never be invoked with eager normalization")
-    }
-
     fn normalization() -> NormalizationStrategy {
         NormalizationStrategy::Eager
     }
diff --git a/src/librustc_infer/infer/nll_relate/mod.rs b/src/librustc_infer/infer/nll_relate/mod.rs
index 23050a1d5d4..0fb926d9416 100644
--- a/src/librustc_infer/infer/nll_relate/mod.rs
+++ b/src/librustc_infer/infer/nll_relate/mod.rs
@@ -23,7 +23,6 @@
 
 use crate::infer::InferCtxt;
 use crate::infer::{ConstVarValue, ConstVariableValue};
-use crate::traits::DomainGoal;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::fold::{TypeFoldable, TypeVisitor};
@@ -78,10 +77,6 @@ pub trait TypeRelatingDelegate<'tcx> {
     /// delegate.
     fn push_outlives(&mut self, sup: ty::Region<'tcx>, sub: ty::Region<'tcx>);
 
-    /// Push a domain goal that will need to be proved for the two types to
-    /// be related. Used for lazy normalization.
-    fn push_domain_goal(&mut self, domain_goal: DomainGoal<'tcx>);
-
     /// Creates a new universe index. Used when instantiating placeholders.
     fn create_next_universe(&mut self) -> ty::UniverseIndex;
 
@@ -265,7 +260,6 @@ where
         value_ty: Ty<'tcx>,
     ) -> Ty<'tcx> {
         use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
-        use crate::traits::WhereClause;
         use rustc_span::DUMMY_SP;
 
         match value_ty.kind {
@@ -279,12 +273,7 @@ where
                 var
             }
 
-            _ => {
-                let projection = ty::ProjectionPredicate { projection_ty, ty: value_ty };
-                self.delegate
-                    .push_domain_goal(DomainGoal::Holds(WhereClause::ProjectionEq(projection)));
-                value_ty
-            }
+            _ => bug!("should never be invoked with eager normalization"),
         }
     }
 
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 9a8a05713c8..7b96d8df12d 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -838,10 +838,6 @@ fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> {
         tcx.par_body_owners(|def_id| tcx.ensure().mir_borrowck(def_id));
     });
 
-    sess.time("dumping_chalk_like_clauses", || {
-        rustc_traits::lowering::dump_program_clauses(tcx);
-    });
-
     sess.time("MIR_effect_checking", || {
         for def_id in tcx.body_owners() {
             mir::transform::check_unsafety::check_unsafety(tcx, def_id.to_def_id())
diff --git a/src/librustc_middle/dep_graph/dep_node.rs b/src/librustc_middle/dep_graph/dep_node.rs
index f4a4aab844c..d7f3ece83e1 100644
--- a/src/librustc_middle/dep_graph/dep_node.rs
+++ b/src/librustc_middle/dep_graph/dep_node.rs
@@ -51,7 +51,6 @@
 
 use crate::mir;
 use crate::mir::interpret::{GlobalId, LitToConstInput};
-use crate::traits;
 use crate::traits::query::{
     CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
     CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal,
diff --git a/src/librustc_middle/query/mod.rs b/src/librustc_middle/query/mod.rs
index e57c51b9eef..b0c44238148 100644
--- a/src/librustc_middle/query/mod.rs
+++ b/src/librustc_middle/query/mod.rs
@@ -1,7 +1,6 @@
 use crate::dep_graph::SerializedDepNodeIndex;
 use crate::mir;
 use crate::mir::interpret::{GlobalId, LitToConstInput};
-use crate::traits;
 use crate::traits::query::{
     CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
     CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal,
@@ -224,19 +223,6 @@ rustc_queries! {
             anon
             desc { "erasing regions from `{:?}`", ty }
         }
-
-        query program_clauses_for(_: DefId) -> Clauses<'tcx> {
-            desc { "generating chalk-style clauses" }
-        }
-
-        query program_clauses_for_env(_: traits::Environment<'tcx>) -> Clauses<'tcx> {
-            desc { "generating chalk-style clauses for environment" }
-        }
-
-        // Get the chalk-style environment of the given item.
-        query environment(_: DefId) -> traits::Environment<'tcx> {
-            desc { "return a chalk-style environment" }
-        }
     }
 
     Linking {
diff --git a/src/librustc_middle/traits/mod.rs b/src/librustc_middle/traits/mod.rs
index d22a4ac298e..d6989fd8e4e 100644
--- a/src/librustc_middle/traits/mod.rs
+++ b/src/librustc_middle/traits/mod.rs
@@ -9,7 +9,7 @@ mod structural_impls;
 
 use crate::mir::interpret::ErrorHandled;
 use crate::ty::subst::SubstsRef;
-use crate::ty::{self, AdtKind, List, Ty, TyCtxt};
+use crate::ty::{self, AdtKind, Ty, TyCtxt};
 
 use rustc_ast::ast;
 use rustc_hir as hir;
@@ -307,162 +307,6 @@ pub struct DerivedObligationCause<'tcx> {
     pub parent_code: Rc<ObligationCauseCode<'tcx>>,
 }
 
-/// The following types:
-/// * `WhereClause`,
-/// * `WellFormed`,
-/// * `FromEnv`,
-/// * `DomainGoal`,
-/// * `Goal`,
-/// * `Clause`,
-/// * `Environment`,
-/// * `InEnvironment`,
-/// are used for representing the trait system in the form of
-/// logic programming clauses. They are part of the interface
-/// for the chalk SLG solver.
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)]
-pub enum WhereClause<'tcx> {
-    Implemented(ty::TraitPredicate<'tcx>),
-    ProjectionEq(ty::ProjectionPredicate<'tcx>),
-    RegionOutlives(ty::RegionOutlivesPredicate<'tcx>),
-    TypeOutlives(ty::TypeOutlivesPredicate<'tcx>),
-}
-
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)]
-pub enum WellFormed<'tcx> {
-    Trait(ty::TraitPredicate<'tcx>),
-    Ty(Ty<'tcx>),
-}
-
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)]
-pub enum FromEnv<'tcx> {
-    Trait(ty::TraitPredicate<'tcx>),
-    Ty(Ty<'tcx>),
-}
-
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)]
-pub enum DomainGoal<'tcx> {
-    Holds(WhereClause<'tcx>),
-    WellFormed(WellFormed<'tcx>),
-    FromEnv(FromEnv<'tcx>),
-    Normalize(ty::ProjectionPredicate<'tcx>),
-}
-
-pub type PolyDomainGoal<'tcx> = ty::Binder<DomainGoal<'tcx>>;
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable)]
-pub enum QuantifierKind {
-    Universal,
-    Existential,
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, Lift)]
-pub enum GoalKind<'tcx> {
-    Implies(Clauses<'tcx>, Goal<'tcx>),
-    And(Goal<'tcx>, Goal<'tcx>),
-    Not(Goal<'tcx>),
-    DomainGoal(DomainGoal<'tcx>),
-    Quantified(QuantifierKind, ty::Binder<Goal<'tcx>>),
-    Subtype(Ty<'tcx>, Ty<'tcx>),
-    CannotProve,
-}
-
-pub type Goal<'tcx> = &'tcx GoalKind<'tcx>;
-
-pub type Goals<'tcx> = &'tcx List<Goal<'tcx>>;
-
-impl<'tcx> DomainGoal<'tcx> {
-    pub fn into_goal(self) -> GoalKind<'tcx> {
-        GoalKind::DomainGoal(self)
-    }
-
-    pub fn into_program_clause(self) -> ProgramClause<'tcx> {
-        ProgramClause {
-            goal: self,
-            hypotheses: ty::List::empty(),
-            category: ProgramClauseCategory::Other,
-        }
-    }
-}
-
-impl<'tcx> GoalKind<'tcx> {
-    pub fn from_poly_domain_goal(
-        domain_goal: PolyDomainGoal<'tcx>,
-        tcx: TyCtxt<'tcx>,
-    ) -> GoalKind<'tcx> {
-        match domain_goal.no_bound_vars() {
-            Some(p) => p.into_goal(),
-            None => GoalKind::Quantified(
-                QuantifierKind::Universal,
-                domain_goal.map_bound(|p| tcx.mk_goal(p.into_goal())),
-            ),
-        }
-    }
-}
-
-/// This matches the definition from Page 7 of "A Proof Procedure for the Logic of Hereditary
-/// Harrop Formulas".
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
-pub enum Clause<'tcx> {
-    Implies(ProgramClause<'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>>;
-
-/// A "program clause" has the form `D :- G1, ..., Gn`. It is saying
-/// that the domain goal `D` is true if `G1...Gn` are provable. This
-/// is equivalent to the implication `G1..Gn => D`; we usually write
-/// it with the reverse implication operator `:-` to emphasize the way
-/// that programs are actually solved (via backchaining, which starts
-/// with the goal to solve and proceeds from there).
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
-pub struct ProgramClause<'tcx> {
-    /// This goal will be considered true ...
-    pub goal: DomainGoal<'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, HashStable)]
-pub enum ProgramClauseCategory {
-    ImpliedBound,
-    WellFormed,
-    Other,
-}
-
-/// A set of clauses that we assume to be true.
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
-pub struct Environment<'tcx> {
-    pub clauses: Clauses<'tcx>,
-}
-
-impl Environment<'tcx> {
-    pub fn with<G>(self, goal: G) -> InEnvironment<'tcx, G> {
-        InEnvironment { environment: self, goal }
-    }
-}
-
-/// Something (usually a goal), along with an environment.
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable)]
-pub struct InEnvironment<'tcx, G> {
-    pub environment: Environment<'tcx>,
-    pub goal: G,
-}
-
 #[derive(Clone, Debug, TypeFoldable)]
 pub enum SelectionError<'tcx> {
     Unimplemented,
diff --git a/src/librustc_middle/traits/structural_impls.rs b/src/librustc_middle/traits/structural_impls.rs
index 5831cb3859f..69a5213d3e4 100644
--- a/src/librustc_middle/traits/structural_impls.rs
+++ b/src/librustc_middle/traits/structural_impls.rs
@@ -1,10 +1,6 @@
 use crate::traits;
-use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
-use crate::ty::{self, Lift, Ty, TyCtxt};
-use rustc_span::symbol::Symbol;
-use smallvec::SmallVec;
+use crate::ty::{Lift, TyCtxt};
 
-use std::collections::{BTreeMap, BTreeSet};
 use std::fmt;
 use std::rc::Rc;
 
@@ -106,295 +102,6 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableTraitAliasData<'tcx, N> {
     }
 }
 
-impl<'tcx> fmt::Display for traits::WhereClause<'tcx> {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        use crate::traits::WhereClause::*;
-
-        // Bypass `ty::print` because it does not print out anonymous regions.
-        // FIXME(eddyb) implement a custom `PrettyPrinter`, or move this to `ty::print`.
-        fn write_region_name<'tcx>(
-            r: ty::Region<'tcx>,
-            fmt: &mut fmt::Formatter<'_>,
-        ) -> fmt::Result {
-            match r {
-                ty::ReLateBound(index, br) => match br {
-                    ty::BoundRegion::BrNamed(_, name) => write!(fmt, "{}", name),
-                    ty::BoundRegion::BrAnon(var) => {
-                        if *index == ty::INNERMOST {
-                            write!(fmt, "'^{}", var)
-                        } else {
-                            write!(fmt, "'^{}_{}", index.index(), var)
-                        }
-                    }
-                    _ => write!(fmt, "'_"),
-                },
-
-                _ => write!(fmt, "{}", r),
-            }
-        }
-
-        match self {
-            Implemented(trait_ref) => write!(fmt, "Implemented({})", trait_ref),
-            ProjectionEq(projection) => write!(fmt, "ProjectionEq({})", projection),
-            RegionOutlives(predicate) => {
-                write!(fmt, "RegionOutlives({}: ", predicate.0)?;
-                write_region_name(predicate.1, fmt)?;
-                write!(fmt, ")")
-            }
-            TypeOutlives(predicate) => {
-                write!(fmt, "TypeOutlives({}: ", predicate.0)?;
-                write_region_name(predicate.1, fmt)?;
-                write!(fmt, ")")
-            }
-        }
-    }
-}
-
-impl<'tcx> fmt::Display for traits::WellFormed<'tcx> {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        use crate::traits::WellFormed::*;
-
-        match self {
-            Trait(trait_ref) => write!(fmt, "WellFormed({})", trait_ref),
-            Ty(ty) => write!(fmt, "WellFormed({})", ty),
-        }
-    }
-}
-
-impl<'tcx> fmt::Display for traits::FromEnv<'tcx> {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        use crate::traits::FromEnv::*;
-
-        match self {
-            Trait(trait_ref) => write!(fmt, "FromEnv({})", trait_ref),
-            Ty(ty) => write!(fmt, "FromEnv({})", ty),
-        }
-    }
-}
-
-impl<'tcx> fmt::Display for traits::DomainGoal<'tcx> {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        use crate::traits::DomainGoal::*;
-
-        match self {
-            Holds(wc) => write!(fmt, "{}", wc),
-            WellFormed(wf) => write!(fmt, "{}", wf),
-            FromEnv(from_env) => write!(fmt, "{}", from_env),
-            Normalize(projection) => {
-                write!(fmt, "Normalize({} -> {})", projection.projection_ty, projection.ty)
-            }
-        }
-    }
-}
-
-impl fmt::Display for traits::QuantifierKind {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        use crate::traits::QuantifierKind::*;
-
-        match self {
-            Universal => write!(fmt, "forall"),
-            Existential => write!(fmt, "exists"),
-        }
-    }
-}
-
-/// Collect names for regions / types bound by a quantified goal / clause.
-/// This collector does not try to do anything clever like in `ty::print`, it's just used
-/// for debug output in tests anyway.
-struct BoundNamesCollector {
-    // Just sort by name because `BoundRegion::BrNamed` does not have a `BoundVar` index anyway.
-    regions: BTreeSet<Symbol>,
-
-    // Sort by `BoundVar` index, so usually this should be equivalent to the order given
-    // by the list of type parameters.
-    types: BTreeMap<u32, Symbol>,
-
-    binder_index: ty::DebruijnIndex,
-}
-
-impl BoundNamesCollector {
-    fn new() -> Self {
-        BoundNamesCollector {
-            regions: BTreeSet::new(),
-            types: BTreeMap::new(),
-            binder_index: ty::INNERMOST,
-        }
-    }
-
-    fn is_empty(&self) -> bool {
-        self.regions.is_empty() && self.types.is_empty()
-    }
-
-    fn write_names(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let mut start = true;
-        for r in &self.regions {
-            if !start {
-                write!(fmt, ", ")?;
-            }
-            start = false;
-            write!(fmt, "{}", r)?;
-        }
-        for t in self.types.values() {
-            if !start {
-                write!(fmt, ", ")?;
-            }
-            start = false;
-            write!(fmt, "{}", t)?;
-        }
-        Ok(())
-    }
-}
-
-impl<'tcx> TypeVisitor<'tcx> for BoundNamesCollector {
-    fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> bool {
-        self.binder_index.shift_in(1);
-        let result = t.super_visit_with(self);
-        self.binder_index.shift_out(1);
-        result
-    }
-
-    fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
-        match t.kind {
-            ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => {
-                self.types.insert(
-                    bound_ty.var.as_u32(),
-                    match bound_ty.kind {
-                        ty::BoundTyKind::Param(name) => name,
-                        ty::BoundTyKind::Anon => {
-                            Symbol::intern(&format!("^{}", bound_ty.var.as_u32()))
-                        }
-                    },
-                );
-            }
-
-            _ => (),
-        };
-
-        t.super_visit_with(self)
-    }
-
-    fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
-        match c.val {
-            ty::ConstKind::Bound(debruijn, bound_var) if debruijn == self.binder_index => {
-                self.types.insert(
-                    bound_var.as_u32(),
-                    Symbol::intern(&format!("^{}", bound_var.as_u32())),
-                );
-            }
-            _ => (),
-        }
-
-        c.super_visit_with(self)
-    }
-
-    fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
-        match r {
-            ty::ReLateBound(index, br) if *index == self.binder_index => match br {
-                ty::BoundRegion::BrNamed(_, name) => {
-                    self.regions.insert(*name);
-                }
-
-                ty::BoundRegion::BrAnon(var) => {
-                    self.regions.insert(Symbol::intern(&format!("'^{}", var)));
-                }
-
-                _ => (),
-            },
-
-            _ => (),
-        };
-
-        r.super_visit_with(self)
-    }
-}
-
-impl<'tcx> fmt::Display for traits::Goal<'tcx> {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        use crate::traits::GoalKind::*;
-
-        match self {
-            Implies(hypotheses, goal) => {
-                write!(fmt, "if (")?;
-                for (index, hyp) in hypotheses.iter().enumerate() {
-                    if index > 0 {
-                        write!(fmt, ", ")?;
-                    }
-                    write!(fmt, "{}", hyp)?;
-                }
-                write!(fmt, ") {{ {} }}", goal)
-            }
-            And(goal1, goal2) => write!(fmt, "({} && {})", goal1, goal2),
-            Not(goal) => write!(fmt, "not {{ {} }}", goal),
-            DomainGoal(goal) => write!(fmt, "{}", goal),
-            Quantified(qkind, goal) => {
-                let mut collector = BoundNamesCollector::new();
-                goal.skip_binder().visit_with(&mut collector);
-
-                if !collector.is_empty() {
-                    write!(fmt, "{}<", qkind)?;
-                    collector.write_names(fmt)?;
-                    write!(fmt, "> {{ ")?;
-                }
-
-                write!(fmt, "{}", goal.skip_binder())?;
-
-                if !collector.is_empty() {
-                    write!(fmt, " }}")?;
-                }
-
-                Ok(())
-            }
-            Subtype(a, b) => write!(fmt, "{} <: {}", a, b),
-            CannotProve => write!(fmt, "CannotProve"),
-        }
-    }
-}
-
-impl<'tcx> fmt::Display for traits::ProgramClause<'tcx> {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let traits::ProgramClause { goal, hypotheses, .. } = self;
-        write!(fmt, "{}", goal)?;
-        if !hypotheses.is_empty() {
-            write!(fmt, " :- ")?;
-            for (index, condition) in hypotheses.iter().enumerate() {
-                if index > 0 {
-                    write!(fmt, ", ")?;
-                }
-                write!(fmt, "{}", condition)?;
-            }
-        }
-        write!(fmt, ".")
-    }
-}
-
-impl<'tcx> fmt::Display for traits::Clause<'tcx> {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        use crate::traits::Clause::*;
-
-        match self {
-            Implies(clause) => write!(fmt, "{}", clause),
-            ForAll(clause) => {
-                let mut collector = BoundNamesCollector::new();
-                clause.skip_binder().visit_with(&mut collector);
-
-                if !collector.is_empty() {
-                    write!(fmt, "forall<")?;
-                    collector.write_names(fmt)?;
-                    write!(fmt, "> {{ ")?;
-                }
-
-                write!(fmt, "{}", clause.skip_binder())?;
-
-                if !collector.is_empty() {
-                    write!(fmt, " }}")?;
-                }
-
-                Ok(())
-            }
-        }
-    }
-}
-
 ///////////////////////////////////////////////////////////////////////////
 // Lift implementations
 
@@ -592,63 +299,3 @@ impl<'a, 'tcx> Lift<'tcx> for traits::Vtable<'a, ()> {
         }
     }
 }
-
-impl<'a, 'tcx> Lift<'tcx> for traits::Environment<'a> {
-    type Lifted = traits::Environment<'tcx>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&self.clauses).map(|clauses| traits::Environment { clauses })
-    }
-}
-
-impl<'a, 'tcx, G: Lift<'tcx>> Lift<'tcx> for traits::InEnvironment<'a, G> {
-    type Lifted = traits::InEnvironment<'tcx, G::Lifted>;
-    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&self.environment).and_then(|environment| {
-            tcx.lift(&self.goal).map(|goal| traits::InEnvironment { environment, goal })
-        })
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////
-// TypeFoldable implementations.
-
-CloneTypeFoldableAndLiftImpls! {
-    traits::QuantifierKind,
-}
-
-impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<traits::Goal<'tcx>> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        let v = self.iter().map(|t| t.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
-        folder.tcx().intern_goals(&v)
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        self.iter().any(|t| t.visit_with(visitor))
-    }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for traits::Goal<'tcx> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        let v = (**self).fold_with(folder);
-        folder.tcx().mk_goal(v)
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        (**self).visit_with(visitor)
-    }
-}
-
-CloneTypeFoldableAndLiftImpls! {
-    traits::ProgramClauseCategory,
-}
-
-impl<'tcx> TypeFoldable<'tcx> for traits::Clauses<'tcx> {
-    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
-        let v = self.iter().map(|t| t.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
-        folder.tcx().intern_clauses(&v)
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        self.iter().any(|t| t.visit_with(visitor))
-    }
-}
diff --git a/src/librustc_middle/ty/context.rs b/src/librustc_middle/ty/context.rs
index ae06008d0f9..1999a32b3c6 100644
--- a/src/librustc_middle/ty/context.rs
+++ b/src/librustc_middle/ty/context.rs
@@ -16,7 +16,6 @@ use crate::middle::stability;
 use crate::mir::interpret::{Allocation, ConstValue, Scalar};
 use crate::mir::{interpret, Body, Field, Local, Place, PlaceElem, ProjectionKind, Promoted};
 use crate::traits;
-use crate::traits::{Clause, Clauses, Goal, GoalKind, Goals};
 use crate::ty::query;
 use crate::ty::steal::Steal;
 use crate::ty::subst::{GenericArg, InternalSubsts, Subst, SubstsRef};
@@ -92,9 +91,6 @@ pub struct CtxtInterners<'tcx> {
     region: InternedSet<'tcx, RegionKind>,
     existential_predicates: InternedSet<'tcx, List<ExistentialPredicate<'tcx>>>,
     predicates: InternedSet<'tcx, List<Predicate<'tcx>>>,
-    clauses: InternedSet<'tcx, List<Clause<'tcx>>>,
-    goal: InternedSet<'tcx, GoalKind<'tcx>>,
-    goal_list: InternedSet<'tcx, List<Goal<'tcx>>>,
     projs: InternedSet<'tcx, List<ProjectionKind>>,
     place_elems: InternedSet<'tcx, List<PlaceElem<'tcx>>>,
     const_: InternedSet<'tcx, Const<'tcx>>,
@@ -111,9 +107,6 @@ impl<'tcx> CtxtInterners<'tcx> {
             existential_predicates: Default::default(),
             canonical_var_infos: Default::default(),
             predicates: Default::default(),
-            clauses: Default::default(),
-            goal: Default::default(),
-            goal_list: Default::default(),
             projs: Default::default(),
             place_elems: Default::default(),
             const_: Default::default(),
@@ -1573,11 +1566,8 @@ macro_rules! nop_list_lift {
 
 nop_lift! {type_; Ty<'a> => Ty<'tcx>}
 nop_lift! {region; Region<'a> => Region<'tcx>}
-nop_lift! {goal; Goal<'a> => Goal<'tcx>}
 nop_lift! {const_; &'a Const<'a> => &'tcx Const<'tcx>}
 
-nop_list_lift! {goal_list; Goal<'a> => Goal<'tcx>}
-nop_list_lift! {clauses; Clause<'a> => Clause<'tcx>}
 nop_list_lift! {type_list; Ty<'a> => Ty<'tcx>}
 nop_list_lift! {existential_predicates; ExistentialPredicate<'a> => ExistentialPredicate<'tcx>}
 nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>}
@@ -1988,12 +1978,6 @@ impl<'tcx> Borrow<RegionKind> for Interned<'tcx, RegionKind> {
     }
 }
 
-impl<'tcx> Borrow<GoalKind<'tcx>> for Interned<'tcx, GoalKind<'tcx>> {
-    fn borrow<'a>(&'a self) -> &'a GoalKind<'tcx> {
-        &self.0
-    }
-}
-
 impl<'tcx> Borrow<[ExistentialPredicate<'tcx>]>
     for Interned<'tcx, List<ExistentialPredicate<'tcx>>>
 {
@@ -2014,18 +1998,6 @@ impl<'tcx> Borrow<Const<'tcx>> for Interned<'tcx, Const<'tcx>> {
     }
 }
 
-impl<'tcx> Borrow<[Clause<'tcx>]> for Interned<'tcx, List<Clause<'tcx>>> {
-    fn borrow<'a>(&'a self) -> &'a [Clause<'tcx>] {
-        &self.0[..]
-    }
-}
-
-impl<'tcx> Borrow<[Goal<'tcx>]> for Interned<'tcx, List<Goal<'tcx>>> {
-    fn borrow<'a>(&'a self) -> &'a [Goal<'tcx>] {
-        &self.0[..]
-    }
-}
-
 macro_rules! direct_interners {
     ($($name:ident: $method:ident($ty:ty)),+) => {
         $(impl<'tcx> PartialEq for Interned<'tcx, $ty> {
@@ -2052,11 +2024,7 @@ macro_rules! direct_interners {
     }
 }
 
-direct_interners!(
-    region: mk_region(RegionKind),
-    goal: mk_goal(GoalKind<'tcx>),
-    const_: mk_const(Const<'tcx>)
-);
+direct_interners!(region: mk_region(RegionKind), const_: mk_const(Const<'tcx>));
 
 macro_rules! slice_interners {
     ($($field:ident: $method:ident($ty:ty)),+) => (
@@ -2076,8 +2044,6 @@ slice_interners!(
     canonical_var_infos: _intern_canonical_var_infos(CanonicalVarInfo),
     existential_predicates: _intern_existential_predicates(ExistentialPredicate<'tcx>),
     predicates: _intern_predicates(Predicate<'tcx>),
-    clauses: _intern_clauses(Clause<'tcx>),
-    goal_list: _intern_goals(Goal<'tcx>),
     projs: _intern_projs(ProjectionKind),
     place_elems: _intern_place_elems(PlaceElem<'tcx>)
 );
@@ -2465,14 +2431,6 @@ impl<'tcx> TyCtxt<'tcx> {
         if ts.is_empty() { List::empty() } else { self._intern_canonical_var_infos(ts) }
     }
 
-    pub fn intern_clauses(self, ts: &[Clause<'tcx>]) -> Clauses<'tcx> {
-        if ts.is_empty() { List::empty() } else { self._intern_clauses(ts) }
-    }
-
-    pub fn intern_goals(self, ts: &[Goal<'tcx>]) -> Goals<'tcx> {
-        if ts.is_empty() { List::empty() } else { self._intern_goals(ts) }
-    }
-
     pub fn mk_fn_sig<I>(
         self,
         inputs: I,
@@ -2530,14 +2488,6 @@ impl<'tcx> TyCtxt<'tcx> {
         self.mk_substs(iter::once(self_ty.into()).chain(rest.iter().cloned()))
     }
 
-    pub fn mk_clauses<I: InternAs<[Clause<'tcx>], Clauses<'tcx>>>(self, iter: I) -> I::Output {
-        iter.intern_with(|xs| self.intern_clauses(xs))
-    }
-
-    pub fn mk_goals<I: InternAs<[Goal<'tcx>], Goals<'tcx>>>(self, iter: I) -> I::Output {
-        iter.intern_with(|xs| self.intern_goals(xs))
-    }
-
     /// Walks upwards from `id` to find a node which might change lint levels with attributes.
     /// It stops at `bound` and just returns it if reached.
     pub fn maybe_lint_level_root_bounded(self, mut id: HirId, bound: HirId) -> HirId {
diff --git a/src/librustc_middle/ty/query/keys.rs b/src/librustc_middle/ty/query/keys.rs
index 7354e89001c..239691dbd17 100644
--- a/src/librustc_middle/ty/query/keys.rs
+++ b/src/librustc_middle/ty/query/keys.rs
@@ -2,7 +2,6 @@
 
 use crate::infer::canonical::Canonical;
 use crate::mir;
-use crate::traits;
 use crate::ty::fast_reject::SimplifiedType;
 use crate::ty::subst::{GenericArg, SubstsRef};
 use crate::ty::{self, Ty, TyCtxt};
@@ -260,17 +259,6 @@ impl<'tcx, T: Key> Key for ty::ParamEnvAnd<'tcx, T> {
     }
 }
 
-impl<'tcx> Key for traits::Environment<'tcx> {
-    type CacheSelector = DefaultCacheSelector;
-
-    fn query_crate(&self) -> CrateNum {
-        LOCAL_CRATE
-    }
-    fn default_span(&self, _: TyCtxt<'_>) -> Span {
-        DUMMY_SP
-    }
-}
-
 impl Key for Symbol {
     type CacheSelector = DefaultCacheSelector;
 
diff --git a/src/librustc_middle/ty/query/mod.rs b/src/librustc_middle/ty/query/mod.rs
index 899479e65a7..67c84c330b8 100644
--- a/src/librustc_middle/ty/query/mod.rs
+++ b/src/librustc_middle/ty/query/mod.rs
@@ -27,7 +27,6 @@ use crate::traits::query::{
     OutlivesBound,
 };
 use crate::traits::specialization_graph;
-use crate::traits::Clauses;
 use crate::traits::{self, Vtable};
 use crate::ty::steal::Steal;
 use crate::ty::subst::{GenericArg, SubstsRef};
diff --git a/src/librustc_middle/ty/relate.rs b/src/librustc_middle/ty/relate.rs
index f4f0b6c41b9..c14d8da5b9f 100644
--- a/src/librustc_middle/ty/relate.rs
+++ b/src/librustc_middle/ty/relate.rs
@@ -5,7 +5,6 @@
 //! subtyping, type equality, etc.
 
 use crate::mir::interpret::{get_slice_bytes, ConstValue};
-use crate::traits;
 use crate::ty::error::{ExpectedFound, TypeError};
 use crate::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
 use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
@@ -754,229 +753,6 @@ impl<'tcx> Relate<'tcx> for ty::ProjectionPredicate<'tcx> {
     }
 }
 
-impl<'tcx> Relate<'tcx> for traits::WhereClause<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &traits::WhereClause<'tcx>,
-        b: &traits::WhereClause<'tcx>,
-    ) -> RelateResult<'tcx, traits::WhereClause<'tcx>> {
-        use crate::traits::WhereClause::*;
-        match (a, b) {
-            (Implemented(a_pred), Implemented(b_pred)) => {
-                Ok(Implemented(relation.relate(a_pred, b_pred)?))
-            }
-
-            (ProjectionEq(a_pred), ProjectionEq(b_pred)) => {
-                Ok(ProjectionEq(relation.relate(a_pred, b_pred)?))
-            }
-
-            (RegionOutlives(a_pred), RegionOutlives(b_pred)) => {
-                Ok(RegionOutlives(ty::OutlivesPredicate(
-                    relation.relate(&a_pred.0, &b_pred.0)?,
-                    relation.relate(&a_pred.1, &b_pred.1)?,
-                )))
-            }
-
-            (TypeOutlives(a_pred), TypeOutlives(b_pred)) => {
-                Ok(TypeOutlives(ty::OutlivesPredicate(
-                    relation.relate(&a_pred.0, &b_pred.0)?,
-                    relation.relate(&a_pred.1, &b_pred.1)?,
-                )))
-            }
-
-            _ => Err(TypeError::Mismatch),
-        }
-    }
-}
-
-impl<'tcx> Relate<'tcx> for traits::WellFormed<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &traits::WellFormed<'tcx>,
-        b: &traits::WellFormed<'tcx>,
-    ) -> RelateResult<'tcx, traits::WellFormed<'tcx>> {
-        use crate::traits::WellFormed::*;
-        match (a, b) {
-            (Trait(a_pred), Trait(b_pred)) => Ok(Trait(relation.relate(a_pred, b_pred)?)),
-            (Ty(a_ty), Ty(b_ty)) => Ok(Ty(relation.relate(a_ty, b_ty)?)),
-            _ => Err(TypeError::Mismatch),
-        }
-    }
-}
-
-impl<'tcx> Relate<'tcx> for traits::FromEnv<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &traits::FromEnv<'tcx>,
-        b: &traits::FromEnv<'tcx>,
-    ) -> RelateResult<'tcx, traits::FromEnv<'tcx>> {
-        use crate::traits::FromEnv::*;
-        match (a, b) {
-            (Trait(a_pred), Trait(b_pred)) => Ok(Trait(relation.relate(a_pred, b_pred)?)),
-            (Ty(a_ty), Ty(b_ty)) => Ok(Ty(relation.relate(a_ty, b_ty)?)),
-            _ => Err(TypeError::Mismatch),
-        }
-    }
-}
-
-impl<'tcx> Relate<'tcx> for traits::DomainGoal<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &traits::DomainGoal<'tcx>,
-        b: &traits::DomainGoal<'tcx>,
-    ) -> RelateResult<'tcx, traits::DomainGoal<'tcx>> {
-        use crate::traits::DomainGoal::*;
-        match (a, b) {
-            (Holds(a_wc), Holds(b_wc)) => Ok(Holds(relation.relate(a_wc, b_wc)?)),
-            (WellFormed(a_wf), WellFormed(b_wf)) => Ok(WellFormed(relation.relate(a_wf, b_wf)?)),
-            (FromEnv(a_fe), FromEnv(b_fe)) => Ok(FromEnv(relation.relate(a_fe, b_fe)?)),
-
-            (Normalize(a_pred), Normalize(b_pred)) => {
-                Ok(Normalize(relation.relate(a_pred, b_pred)?))
-            }
-
-            _ => Err(TypeError::Mismatch),
-        }
-    }
-}
-
-impl<'tcx> Relate<'tcx> for traits::Goal<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &traits::Goal<'tcx>,
-        b: &traits::Goal<'tcx>,
-    ) -> RelateResult<'tcx, traits::Goal<'tcx>> {
-        use crate::traits::GoalKind::*;
-        match (a, b) {
-            (Implies(a_clauses, a_goal), Implies(b_clauses, b_goal)) => {
-                let clauses = relation.relate(a_clauses, b_clauses)?;
-                let goal = relation.relate(a_goal, b_goal)?;
-                Ok(relation.tcx().mk_goal(Implies(clauses, goal)))
-            }
-
-            (And(a_left, a_right), And(b_left, b_right)) => {
-                let left = relation.relate(a_left, b_left)?;
-                let right = relation.relate(a_right, b_right)?;
-                Ok(relation.tcx().mk_goal(And(left, right)))
-            }
-
-            (Not(a_goal), Not(b_goal)) => {
-                let goal = relation.relate(a_goal, b_goal)?;
-                Ok(relation.tcx().mk_goal(Not(goal)))
-            }
-
-            (DomainGoal(a_goal), DomainGoal(b_goal)) => {
-                let goal = relation.relate(a_goal, b_goal)?;
-                Ok(relation.tcx().mk_goal(DomainGoal(goal)))
-            }
-
-            (Quantified(a_qkind, a_goal), Quantified(b_qkind, b_goal)) if a_qkind == b_qkind => {
-                let goal = relation.relate(a_goal, b_goal)?;
-                Ok(relation.tcx().mk_goal(Quantified(*a_qkind, goal)))
-            }
-
-            (CannotProve, CannotProve) => Ok(*a),
-
-            _ => Err(TypeError::Mismatch),
-        }
-    }
-}
-
-impl<'tcx> Relate<'tcx> for traits::Goals<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &traits::Goals<'tcx>,
-        b: &traits::Goals<'tcx>,
-    ) -> RelateResult<'tcx, traits::Goals<'tcx>> {
-        if a.len() != b.len() {
-            return Err(TypeError::Mismatch);
-        }
-
-        let tcx = relation.tcx();
-        let goals = a.iter().zip(b.iter()).map(|(a, b)| relation.relate(a, b));
-        Ok(tcx.mk_goals(goals)?)
-    }
-}
-
-impl<'tcx> Relate<'tcx> for traits::Clause<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &traits::Clause<'tcx>,
-        b: &traits::Clause<'tcx>,
-    ) -> RelateResult<'tcx, traits::Clause<'tcx>> {
-        use crate::traits::Clause::*;
-        match (a, b) {
-            (Implies(a_clause), Implies(b_clause)) => {
-                let clause = relation.relate(a_clause, b_clause)?;
-                Ok(Implies(clause))
-            }
-
-            (ForAll(a_clause), ForAll(b_clause)) => {
-                let clause = relation.relate(a_clause, b_clause)?;
-                Ok(ForAll(clause))
-            }
-
-            _ => Err(TypeError::Mismatch),
-        }
-    }
-}
-
-impl<'tcx> Relate<'tcx> for traits::Clauses<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &traits::Clauses<'tcx>,
-        b: &traits::Clauses<'tcx>,
-    ) -> RelateResult<'tcx, traits::Clauses<'tcx>> {
-        if a.len() != b.len() {
-            return Err(TypeError::Mismatch);
-        }
-
-        let tcx = relation.tcx();
-        let clauses = a.iter().zip(b.iter()).map(|(a, b)| relation.relate(a, b));
-        Ok(tcx.mk_clauses(clauses)?)
-    }
-}
-
-impl<'tcx> Relate<'tcx> for traits::ProgramClause<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &traits::ProgramClause<'tcx>,
-        b: &traits::ProgramClause<'tcx>,
-    ) -> RelateResult<'tcx, traits::ProgramClause<'tcx>> {
-        Ok(traits::ProgramClause {
-            goal: relation.relate(&a.goal, &b.goal)?,
-            hypotheses: relation.relate(&a.hypotheses, &b.hypotheses)?,
-            category: traits::ProgramClauseCategory::Other,
-        })
-    }
-}
-
-impl<'tcx> Relate<'tcx> for traits::Environment<'tcx> {
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &traits::Environment<'tcx>,
-        b: &traits::Environment<'tcx>,
-    ) -> RelateResult<'tcx, traits::Environment<'tcx>> {
-        Ok(traits::Environment { clauses: relation.relate(&a.clauses, &b.clauses)? })
-    }
-}
-
-impl<'tcx, G> Relate<'tcx> for traits::InEnvironment<'tcx, G>
-where
-    G: Relate<'tcx>,
-{
-    fn relate<R: TypeRelation<'tcx>>(
-        relation: &mut R,
-        a: &traits::InEnvironment<'tcx, G>,
-        b: &traits::InEnvironment<'tcx, G>,
-    ) -> RelateResult<'tcx, traits::InEnvironment<'tcx, G>> {
-        Ok(traits::InEnvironment {
-            environment: relation.relate(&a.environment, &b.environment)?,
-            goal: relation.relate(&a.goal, &b.goal)?,
-        })
-    }
-}
-
 ///////////////////////////////////////////////////////////////////////////
 // Error handling
 
diff --git a/src/librustc_middle/ty/subst.rs b/src/librustc_middle/ty/subst.rs
index 0f4485a7050..4d73f8f91ad 100644
--- a/src/librustc_middle/ty/subst.rs
+++ b/src/librustc_middle/ty/subst.rs
@@ -207,38 +207,6 @@ impl<'a, 'tcx> InternalSubsts<'tcx> {
         Self::for_item(tcx, def_id, |param, _| tcx.mk_param_from_def(param))
     }
 
-    /// Creates a `InternalSubsts` that maps each generic parameter to a higher-ranked
-    /// var bound at index `0`. For types, we use a `BoundVar` index equal to
-    /// the type parameter index. For regions, we use the `BoundRegion::BrNamed`
-    /// variant (which has a `DefId`).
-    pub fn bound_vars_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx> {
-        Self::for_item(tcx, def_id, |param, _| match param.kind {
-            ty::GenericParamDefKind::Type { .. } => tcx
-                .mk_ty(ty::Bound(
-                    ty::INNERMOST,
-                    ty::BoundTy {
-                        var: ty::BoundVar::from(param.index),
-                        kind: ty::BoundTyKind::Param(param.name),
-                    },
-                ))
-                .into(),
-
-            ty::GenericParamDefKind::Lifetime => tcx
-                .mk_region(ty::RegionKind::ReLateBound(
-                    ty::INNERMOST,
-                    ty::BoundRegion::BrNamed(param.def_id, param.name),
-                ))
-                .into(),
-
-            ty::GenericParamDefKind::Const => tcx
-                .mk_const(ty::Const {
-                    val: ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from(param.index)),
-                    ty: tcx.type_of(param.def_id),
-                })
-                .into(),
-        })
-    }
-
     /// Creates a `InternalSubsts` for generic parameter definitions,
     /// by calling closures to obtain each kind.
     /// The closures get to observe the `InternalSubsts` as they're
diff --git a/src/librustc_mir/borrow_check/type_check/relate_tys.rs b/src/librustc_mir/borrow_check/type_check/relate_tys.rs
index b9a76057d51..96ae534c396 100644
--- a/src/librustc_mir/borrow_check/type_check/relate_tys.rs
+++ b/src/librustc_mir/borrow_check/type_check/relate_tys.rs
@@ -4,7 +4,6 @@ use rustc_middle::mir::ConstraintCategory;
 use rustc_middle::ty::relate::TypeRelation;
 use rustc_middle::ty::{self, Ty};
 use rustc_trait_selection::traits::query::Fallible;
-use rustc_trait_selection::traits::DomainGoal;
 
 use crate::borrow_check::constraints::OutlivesConstraint;
 use crate::borrow_check::type_check::{BorrowCheckContext, Locations};
@@ -100,10 +99,6 @@ impl TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> {
         }
     }
 
-    fn push_domain_goal(&mut self, _: DomainGoal<'tcx>) {
-        bug!("should never be invoked with eager normalization")
-    }
-
     fn normalization() -> NormalizationStrategy {
         NormalizationStrategy::Eager
     }
diff --git a/src/librustc_traits/lib.rs b/src/librustc_traits/lib.rs
index ba840c283b8..e0533b11ecf 100644
--- a/src/librustc_traits/lib.rs
+++ b/src/librustc_traits/lib.rs
@@ -15,7 +15,6 @@ extern crate rustc_middle;
 mod dropck_outlives;
 mod evaluate_obligation;
 mod implied_outlives_bounds;
-pub mod lowering;
 mod normalize_erasing_regions;
 mod normalize_projection_ty;
 mod type_op;
@@ -26,7 +25,6 @@ pub fn provide(p: &mut Providers<'_>) {
     dropck_outlives::provide(p);
     evaluate_obligation::provide(p);
     implied_outlives_bounds::provide(p);
-    lowering::provide(p);
     normalize_projection_ty::provide(p);
     normalize_erasing_regions::provide(p);
     type_op::provide(p);
diff --git a/src/librustc_traits/lowering/environment.rs b/src/librustc_traits/lowering/environment.rs
deleted file mode 100644
index e7fa245fd40..00000000000
--- a/src/librustc_traits/lowering/environment.rs
+++ /dev/null
@@ -1,267 +0,0 @@
-use rustc_data_structures::fx::FxHashSet;
-use rustc_hir::def_id::DefId;
-use rustc_middle::traits::{
-    Clause, Clauses, DomainGoal, Environment, FromEnv, ProgramClause, ProgramClauseCategory,
-};
-use rustc_middle::ty::subst::GenericArgKind;
-use rustc_middle::ty::{self, Ty, TyCtxt};
-
-struct ClauseVisitor<'a, 'tcx> {
-    tcx: TyCtxt<'tcx>,
-    round: &'a mut FxHashSet<Clause<'tcx>>,
-}
-
-impl ClauseVisitor<'a, 'tcx> {
-    fn new(tcx: TyCtxt<'tcx>, round: &'a mut FxHashSet<Clause<'tcx>>) -> Self {
-        ClauseVisitor { tcx, round }
-    }
-
-    fn visit_ty(&mut self, ty: Ty<'tcx>) {
-        match ty.kind {
-            ty::Projection(data) => {
-                self.round.extend(
-                    self.tcx
-                        .program_clauses_for(data.item_def_id)
-                        .iter()
-                        .filter(|c| c.category() == ProgramClauseCategory::ImpliedBound)
-                        .cloned(),
-                );
-            }
-
-            ty::Dynamic(..) => {
-                // FIXME: trait object rules are not yet implemented
-            }
-
-            ty::Adt(def, ..) => {
-                self.round.extend(
-                    self.tcx
-                        .program_clauses_for(def.did)
-                        .iter()
-                        .filter(|c| c.category() == ProgramClauseCategory::ImpliedBound)
-                        .cloned(),
-                );
-            }
-
-            ty::Foreign(def_id)
-            | ty::FnDef(def_id, ..)
-            | ty::Closure(def_id, ..)
-            | ty::Generator(def_id, ..)
-            | ty::Opaque(def_id, ..) => {
-                self.round.extend(
-                    self.tcx
-                        .program_clauses_for(def_id)
-                        .iter()
-                        .filter(|c| c.category() == ProgramClauseCategory::ImpliedBound)
-                        .cloned(),
-                );
-            }
-
-            ty::Bool
-            | ty::Char
-            | ty::Int(..)
-            | ty::Uint(..)
-            | ty::Float(..)
-            | ty::Str
-            | ty::Array(..)
-            | ty::Slice(..)
-            | ty::RawPtr(..)
-            | ty::FnPtr(..)
-            | ty::Tuple(..)
-            | ty::Ref(..)
-            | ty::Never
-            | ty::Infer(..)
-            | ty::Placeholder(..)
-            | ty::Param(..)
-            | ty::Bound(..) => (),
-
-            ty::GeneratorWitness(..) | ty::UnnormalizedProjection(..) | ty::Error => {
-                bug!("unexpected type {:?}", ty);
-            }
-        }
-    }
-
-    fn visit_from_env(&mut self, from_env: FromEnv<'tcx>) {
-        match from_env {
-            FromEnv::Trait(predicate) => {
-                self.round.extend(
-                    self.tcx
-                        .program_clauses_for(predicate.def_id())
-                        .iter()
-                        .filter(|c| c.category() == ProgramClauseCategory::ImpliedBound)
-                        .cloned(),
-                );
-            }
-
-            FromEnv::Ty(ty) => self.visit_ty(ty),
-        }
-    }
-
-    fn visit_domain_goal(&mut self, domain_goal: DomainGoal<'tcx>) {
-        // The only domain goals we can find in an environment are:
-        // * `DomainGoal::Holds(..)`
-        // * `DomainGoal::FromEnv(..)`
-        // The former do not lead to any implied bounds. So we only need
-        // to visit the latter.
-        if let DomainGoal::FromEnv(from_env) = domain_goal {
-            self.visit_from_env(from_env);
-        }
-    }
-
-    fn visit_program_clause(&mut self, clause: ProgramClause<'tcx>) {
-        self.visit_domain_goal(clause.goal);
-        // No need to visit `clause.hypotheses`: they are always of the form
-        // `FromEnv(...)` and were visited at a previous round.
-    }
-
-    fn visit_clause(&mut self, clause: Clause<'tcx>) {
-        match clause {
-            Clause::Implies(clause) => self.visit_program_clause(clause),
-            Clause::ForAll(clause) => self.visit_program_clause(*clause.skip_binder()),
-        }
-    }
-}
-
-crate fn program_clauses_for_env<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    environment: Environment<'tcx>,
-) -> Clauses<'tcx> {
-    debug!("program_clauses_for_env(environment={:?})", environment);
-
-    let mut last_round = FxHashSet::default();
-    {
-        let mut visitor = ClauseVisitor::new(tcx, &mut last_round);
-        for &clause in environment.clauses {
-            visitor.visit_clause(clause);
-        }
-    }
-
-    let mut closure = last_round.clone();
-    let mut next_round = FxHashSet::default();
-    while !last_round.is_empty() {
-        let mut visitor = ClauseVisitor::new(tcx, &mut next_round);
-        for clause in last_round.drain() {
-            visitor.visit_clause(clause);
-        }
-        last_round.extend(next_round.drain().filter(|&clause| closure.insert(clause)));
-    }
-
-    debug!("program_clauses_for_env: closure = {:#?}", closure);
-
-    tcx.mk_clauses(closure.into_iter())
-}
-
-crate fn environment(tcx: TyCtxt<'_>, def_id: DefId) -> Environment<'_> {
-    use super::{IntoFromEnvGoal, Lower};
-    use rustc_hir::{ForeignItemKind, ImplItemKind, ItemKind, Node, TraitItemKind};
-
-    debug!("environment(def_id = {:?})", def_id);
-
-    // The environment of an impl Trait type is its defining function's environment.
-    if let Some(parent) = ty::is_impl_trait_defn(tcx, def_id) {
-        return environment(tcx, parent);
-    }
-
-    // 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()))
-        .map(|domain_goal| domain_goal.map_bound(|bound| bound.into_program_clause()))
-        // `ForAll` because each `domain_goal` is a `PolyDomainGoal` and
-        // could bound lifetimes.
-        .map(Clause::ForAll);
-
-    let hir_id = tcx.hir().as_local_hir_id(def_id.expect_local());
-    let node = tcx.hir().get(hir_id);
-
-    enum NodeKind {
-        TraitImpl,
-        InherentImpl,
-        Fn,
-        Other,
-    };
-
-    let node_kind = match node {
-        Node::TraitItem(item) => match item.kind {
-            TraitItemKind::Fn(..) => NodeKind::Fn,
-            _ => NodeKind::Other,
-        },
-
-        Node::ImplItem(item) => match item.kind {
-            ImplItemKind::Fn(..) => NodeKind::Fn,
-            _ => NodeKind::Other,
-        },
-
-        Node::Item(item) => match item.kind {
-            ItemKind::Impl { of_trait: Some(_), .. } => NodeKind::TraitImpl,
-            ItemKind::Impl { of_trait: None, .. } => NodeKind::InherentImpl,
-            ItemKind::Fn(..) => NodeKind::Fn,
-            _ => NodeKind::Other,
-        },
-
-        Node::ForeignItem(item) => match item.kind {
-            ForeignItemKind::Fn(..) => NodeKind::Fn,
-            _ => NodeKind::Other,
-        },
-
-        // FIXME: closures?
-        _ => NodeKind::Other,
-    };
-
-    // FIXME(eddyb) isn't the unordered nature of this a hazard?
-    let mut inputs = FxHashSet::default();
-
-    match node_kind {
-        // In a trait impl, we assume that the header trait ref and all its
-        // constituents are well-formed.
-        NodeKind::TraitImpl => {
-            let trait_ref = tcx.impl_trait_ref(def_id).expect("not an impl");
-
-            inputs.extend(trait_ref.substs.iter().flat_map(|&arg| arg.walk()));
-        }
-
-        // In an inherent impl, we assume that the receiver type and all its
-        // constituents are well-formed.
-        NodeKind::InherentImpl => {
-            let self_ty = tcx.type_of(def_id);
-            inputs.extend(self_ty.walk());
-        }
-
-        // In an fn, we assume that the arguments and all their constituents are
-        // well-formed.
-        NodeKind::Fn => {
-            let fn_sig = tcx.fn_sig(def_id);
-            let fn_sig = tcx.liberate_late_bound_regions(def_id, &fn_sig);
-
-            inputs.extend(fn_sig.inputs().iter().flat_map(|ty| ty.walk()));
-        }
-
-        NodeKind::Other => (),
-    }
-
-    let clauses = clauses.chain(
-        inputs
-            .into_iter()
-            .filter_map(|arg| {
-                match arg.unpack() {
-                    GenericArgKind::Type(ty) => Some(FromEnv::Ty(ty)),
-
-                    // FIXME(eddyb) no WF conditions from lifetimes?
-                    GenericArgKind::Lifetime(_) => None,
-
-                    // FIXME(eddyb) support const generics in Chalk
-                    GenericArgKind::Const(_) => None,
-                }
-            })
-            .map(DomainGoal::FromEnv)
-            .map(|domain_goal| domain_goal.into_program_clause())
-            .map(Clause::Implies),
-    );
-
-    debug!("environment: clauses = {:?}", clauses);
-
-    Environment { clauses: tcx.mk_clauses(clauses) }
-}
diff --git a/src/librustc_traits/lowering/mod.rs b/src/librustc_traits/lowering/mod.rs
deleted file mode 100644
index 19765c36ae2..00000000000
--- a/src/librustc_traits/lowering/mod.rs
+++ /dev/null
@@ -1,627 +0,0 @@
-mod environment;
-
-use rustc_ast::ast;
-use rustc_hir as hir;
-use rustc_hir::def::DefKind;
-use rustc_hir::def_id::DefId;
-use rustc_hir::definitions::DefPathData;
-use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
-use rustc_middle::hir::map::Map;
-use rustc_middle::traits::{
-    Clause, Clauses, DomainGoal, FromEnv, GoalKind, PolyDomainGoal, ProgramClause,
-    ProgramClauseCategory, WellFormed, WhereClause,
-};
-use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::subst::{InternalSubsts, Subst};
-use rustc_middle::ty::{self, List, TyCtxt};
-use rustc_span::symbol::sym;
-
-use std::iter;
-
-crate fn provide(p: &mut Providers<'_>) {
-    *p = Providers {
-        program_clauses_for,
-        program_clauses_for_env: environment::program_clauses_for_env,
-        environment: environment::environment,
-        ..*p
-    };
-}
-
-crate trait Lower<T> {
-    /// Lower a rustc construct (e.g., `ty::TraitPredicate`) to a chalk-like type.
-    fn lower(&self) -> T;
-}
-
-impl<T, U> Lower<Vec<U>> for Vec<T>
-where
-    T: Lower<U>,
-{
-    fn lower(&self) -> Vec<U> {
-        self.iter().map(|item| item.lower()).collect()
-    }
-}
-
-impl<'tcx> Lower<WhereClause<'tcx>> for ty::TraitPredicate<'tcx> {
-    fn lower(&self) -> WhereClause<'tcx> {
-        WhereClause::Implemented(*self)
-    }
-}
-
-impl<'tcx> Lower<WhereClause<'tcx>> for ty::ProjectionPredicate<'tcx> {
-    fn lower(&self) -> WhereClause<'tcx> {
-        WhereClause::ProjectionEq(*self)
-    }
-}
-
-impl<'tcx> Lower<WhereClause<'tcx>> for ty::RegionOutlivesPredicate<'tcx> {
-    fn lower(&self) -> WhereClause<'tcx> {
-        WhereClause::RegionOutlives(*self)
-    }
-}
-
-impl<'tcx> Lower<WhereClause<'tcx>> for ty::TypeOutlivesPredicate<'tcx> {
-    fn lower(&self) -> WhereClause<'tcx> {
-        WhereClause::TypeOutlives(*self)
-    }
-}
-
-impl<'tcx, T> Lower<DomainGoal<'tcx>> for T
-where
-    T: Lower<WhereClause<'tcx>>,
-{
-    fn lower(&self) -> DomainGoal<'tcx> {
-        DomainGoal::Holds(self.lower())
-    }
-}
-
-/// `ty::Binder` is used for wrapping a rustc construction possibly containing generic
-/// lifetimes, e.g., `for<'a> T: Fn(&'a i32)`. Instead of representing higher-ranked things
-/// in that leaf-form (i.e., `Holds(Implemented(Binder<TraitPredicate>))` in the previous
-/// example), we model them with quantified domain goals, e.g., as for the previous example:
-/// `forall<'a> { T: Fn(&'a i32) }` which corresponds to something like
-/// `Binder<Holds(Implemented(TraitPredicate))>`.
-impl<'tcx, T> Lower<PolyDomainGoal<'tcx>> for ty::Binder<T>
-where
-    T: Lower<DomainGoal<'tcx>> + ty::fold::TypeFoldable<'tcx>,
-{
-    fn lower(&self) -> PolyDomainGoal<'tcx> {
-        self.map_bound_ref(|p| p.lower())
-    }
-}
-
-impl<'tcx> Lower<PolyDomainGoal<'tcx>> for ty::Predicate<'tcx> {
-    fn lower(&self) -> PolyDomainGoal<'tcx> {
-        use rustc_middle::ty::Predicate;
-
-        match self {
-            Predicate::Trait(predicate, _) => predicate.lower(),
-            Predicate::RegionOutlives(predicate) => predicate.lower(),
-            Predicate::TypeOutlives(predicate) => predicate.lower(),
-            Predicate::Projection(predicate) => predicate.lower(),
-
-            Predicate::WellFormed(..)
-            | Predicate::ObjectSafe(..)
-            | Predicate::ClosureKind(..)
-            | Predicate::Subtype(..)
-            | Predicate::ConstEvaluatable(..) => bug!("unexpected predicate {}", self),
-        }
-    }
-}
-
-/// Used for implied bounds related rules (see rustc dev guide).
-trait IntoFromEnvGoal {
-    /// Transforms an existing goal into a `FromEnv` goal.
-    fn into_from_env_goal(self) -> Self;
-}
-
-/// Used for well-formedness related rules (see rustc dev guide).
-trait IntoWellFormedGoal {
-    /// Transforms an existing goal into a `WellFormed` goal.
-    fn into_well_formed_goal(self) -> Self;
-}
-
-impl<'tcx> IntoFromEnvGoal for DomainGoal<'tcx> {
-    fn into_from_env_goal(self) -> DomainGoal<'tcx> {
-        use self::WhereClause::*;
-
-        match self {
-            DomainGoal::Holds(Implemented(trait_ref)) => {
-                DomainGoal::FromEnv(FromEnv::Trait(trait_ref))
-            }
-            other => other,
-        }
-    }
-}
-
-impl<'tcx> IntoWellFormedGoal for DomainGoal<'tcx> {
-    fn into_well_formed_goal(self) -> DomainGoal<'tcx> {
-        use self::WhereClause::*;
-
-        match self {
-            DomainGoal::Holds(Implemented(trait_ref)) => {
-                DomainGoal::WellFormed(WellFormed::Trait(trait_ref))
-            }
-            other => other,
-        }
-    }
-}
-
-crate fn program_clauses_for(tcx: TyCtxt<'_>, def_id: DefId) -> Clauses<'_> {
-    // FIXME(eddyb) this should only be using `def_kind`.
-    match tcx.def_key(def_id).disambiguated_data.data {
-        DefPathData::TypeNs(..) => match tcx.def_kind(def_id) {
-            DefKind::Trait | DefKind::TraitAlias => program_clauses_for_trait(tcx, def_id),
-            // FIXME(eddyb) deduplicate this `associated_item` call with
-            // `program_clauses_for_associated_type_{value,def}`.
-            DefKind::AssocTy => match tcx.associated_item(def_id).container {
-                ty::AssocItemContainer::ImplContainer(_) => {
-                    program_clauses_for_associated_type_value(tcx, def_id)
-                }
-                ty::AssocItemContainer::TraitContainer(_) => {
-                    program_clauses_for_associated_type_def(tcx, def_id)
-                }
-            },
-            DefKind::Struct
-            | DefKind::Enum
-            | DefKind::TyAlias
-            | DefKind::Union
-            | DefKind::OpaqueTy => program_clauses_for_type_def(tcx, def_id),
-            _ => List::empty(),
-        },
-        DefPathData::Impl => program_clauses_for_impl(tcx, def_id),
-        _ => List::empty(),
-    }
-}
-
-fn program_clauses_for_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Clauses<'_> {
-    // `trait Trait<P1..Pn> where WC { .. } // P0 == Self`
-
-    // Rule Implemented-From-Env (see rustc dev guide)
-    //
-    // ```
-    // forall<Self, P1..Pn> {
-    //   Implemented(Self: Trait<P1..Pn>) :- FromEnv(Self: Trait<P1..Pn>)
-    // }
-    // ```
-
-    let bound_vars = InternalSubsts::bound_vars_for_item(tcx, def_id);
-
-    // `Self: Trait<P1..Pn>`
-    let trait_pred = ty::TraitPredicate { trait_ref: ty::TraitRef { def_id, substs: bound_vars } };
-
-    // `Implemented(Self: Trait<P1..Pn>)`
-    let impl_trait: DomainGoal<'_> = trait_pred.lower();
-
-    // `FromEnv(Self: Trait<P1..Pn>)`
-    let from_env_goal = tcx.mk_goal(impl_trait.into_from_env_goal().into_goal());
-    let hypotheses = tcx.intern_goals(&[from_env_goal]);
-
-    // `Implemented(Self: Trait<P1..Pn>) :- FromEnv(Self: Trait<P1..Pn>)`
-    let implemented_from_env = ProgramClause {
-        goal: impl_trait,
-        hypotheses,
-        category: ProgramClauseCategory::ImpliedBound,
-    };
-
-    let implemented_from_env = Clause::ForAll(ty::Binder::bind(implemented_from_env));
-
-    let predicates = tcx.predicates_defined_on(def_id).predicates;
-
-    // Warning: these where clauses are not substituted for bound vars yet,
-    // so that we don't need to adjust binders in the `FromEnv` rules below
-    // (see the FIXME).
-    let where_clauses = &predicates.iter().map(|(wc, _)| wc.lower()).collect::<Vec<_>>();
-
-    // Rule Implied-Bound-From-Trait
-    //
-    // For each where clause WC:
-    // ```
-    // forall<Self, P1..Pn> {
-    //   FromEnv(WC) :- FromEnv(Self: Trait<P1..Pn)
-    // }
-    // ```
-
-    // `FromEnv(WC) :- FromEnv(Self: Trait<P1..Pn>)`, for each where clause WC
-    let implied_bound_clauses = where_clauses
-        .iter()
-        .cloned()
-        // `FromEnv(WC) :- FromEnv(Self: Trait<P1..Pn>)`
-        .map(|wc| {
-            // we move binders to the left
-            wc.map_bound(|goal| ProgramClause {
-                // FIXME: As where clauses can only bind lifetimes for now, and that named
-                // bound regions have a def-id, it is safe to just inject `bound_vars` and
-                // `hypotheses` (which contain named vars bound at index `0`) into this
-                // binding level. This may change if we ever allow where clauses to bind
-                // types (e.g. for GATs things), because bound types only use a `BoundVar`
-                // index (no def-id).
-                goal: goal.subst(tcx, bound_vars).into_from_env_goal(),
-                hypotheses,
-
-                category: ProgramClauseCategory::ImpliedBound,
-            })
-        })
-        .map(Clause::ForAll);
-
-    // Rule WellFormed-TraitRef
-    //
-    // Here `WC` denotes the set of all where clauses:
-    // ```
-    // forall<Self, P1..Pn> {
-    //   WellFormed(Self: Trait<P1..Pn>) :- Implemented(Self: Trait<P1..Pn>) && WellFormed(WC)
-    // }
-    // ```
-
-    // `WellFormed(WC)`
-    let wf_conditions = where_clauses
-        .iter()
-        .map(|wc| wc.subst(tcx, bound_vars))
-        .map(|wc| wc.map_bound(|goal| goal.into_well_formed_goal()));
-
-    // `WellFormed(Self: Trait<P1..Pn>) :- Implemented(Self: Trait<P1..Pn>) && WellFormed(WC)`
-    let wf_clause = ProgramClause {
-        goal: DomainGoal::WellFormed(WellFormed::Trait(trait_pred)),
-        hypotheses: tcx.mk_goals(
-            iter::once(tcx.mk_goal(GoalKind::DomainGoal(impl_trait))).chain(
-                wf_conditions.map(|wc| tcx.mk_goal(GoalKind::from_poly_domain_goal(wc, tcx))),
-            ),
-        ),
-        category: ProgramClauseCategory::WellFormed,
-    };
-    let wf_clause = Clause::ForAll(ty::Binder::bind(wf_clause));
-
-    tcx.mk_clauses(
-        iter::once(implemented_from_env).chain(implied_bound_clauses).chain(iter::once(wf_clause)),
-    )
-}
-
-fn program_clauses_for_impl(tcx: TyCtxt<'tcx>, def_id: DefId) -> Clauses<'tcx> {
-    if let ty::ImplPolarity::Negative = tcx.impl_polarity(def_id) {
-        return List::empty();
-    }
-
-    // Rule Implemented-From-Impl (see rustc dev guide)
-    //
-    // `impl<P0..Pn> Trait<A1..An> for A0 where WC { .. }`
-    //
-    // ```
-    // forall<P0..Pn> {
-    //   Implemented(A0: Trait<A1..An>) :- WC
-    // }
-    // ```
-
-    let bound_vars = InternalSubsts::bound_vars_for_item(tcx, def_id);
-
-    let trait_ref = tcx.impl_trait_ref(def_id).expect("not an impl").subst(tcx, bound_vars);
-
-    // `Implemented(A0: Trait<A1..An>)`
-    let trait_pred = ty::TraitPredicate { trait_ref }.lower();
-
-    // `WC`
-    let predicates = tcx.predicates_of(def_id).predicates;
-    let where_clauses =
-        predicates.iter().map(|(wc, _)| wc.lower()).map(|wc| wc.subst(tcx, bound_vars));
-
-    // `Implemented(A0: Trait<A1..An>) :- WC`
-    let clause = ProgramClause {
-        goal: trait_pred,
-        hypotheses: tcx.mk_goals(
-            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::bind(clause))))
-}
-
-pub fn program_clauses_for_type_def(tcx: TyCtxt<'_>, def_id: DefId) -> Clauses<'_> {
-    // Rule WellFormed-Type
-    //
-    // `struct Ty<P1..Pn> where WC1, ..., WCm`
-    //
-    // ```
-    // forall<P1..Pn> {
-    //   WellFormed(Ty<...>) :- WellFormed(WC1), ..., WellFormed(WCm)`
-    // }
-    // ```
-
-    let bound_vars = InternalSubsts::bound_vars_for_item(tcx, def_id);
-
-    // `Ty<...>`
-    let ty = tcx.type_of(def_id).subst(tcx, bound_vars);
-
-    // Warning: these where clauses are not substituted for bound vars yet,
-    // so that we don't need to adjust binders in the `FromEnv` rules below
-    // (see the FIXME).
-    let where_clauses =
-        tcx.predicates_of(def_id).predicates.iter().map(|(wc, _)| wc.lower()).collect::<Vec<_>>();
-
-    // `WellFormed(Ty<...>) :- WellFormed(WC1), ..., WellFormed(WCm)`
-    let well_formed_clause = ProgramClause {
-        goal: DomainGoal::WellFormed(WellFormed::Ty(ty)),
-        hypotheses: tcx.mk_goals(
-            where_clauses
-                .iter()
-                .map(|wc| wc.subst(tcx, bound_vars))
-                .map(|wc| wc.map_bound(|bound| bound.into_well_formed_goal()))
-                .map(|wc| tcx.mk_goal(GoalKind::from_poly_domain_goal(wc, tcx))),
-        ),
-        category: ProgramClauseCategory::WellFormed,
-    };
-    let well_formed_clause = Clause::ForAll(ty::Binder::bind(well_formed_clause));
-
-    // Rule Implied-Bound-From-Type
-    //
-    // For each where clause `WC`:
-    // ```
-    // forall<P1..Pn> {
-    //   FromEnv(WC) :- FromEnv(Ty<...>)
-    // }
-    // ```
-
-    // `FromEnv(Ty<...>)`
-    let from_env_goal = tcx.mk_goal(DomainGoal::FromEnv(FromEnv::Ty(ty)).into_goal());
-    let hypotheses = tcx.intern_goals(&[from_env_goal]);
-
-    // For each where clause `WC`:
-    let from_env_clauses = where_clauses
-        .into_iter()
-        // `FromEnv(WC) :- FromEnv(Ty<...>)`
-        .map(|wc| {
-            // move the binders to the left
-            wc.map_bound(|goal| ProgramClause {
-                // FIXME: we inject `bound_vars` and `hypotheses` into this binding
-                // level, which may be incorrect in the future: see the FIXME in
-                // `program_clauses_for_trait`.
-                goal: goal.subst(tcx, bound_vars).into_from_env_goal(),
-                hypotheses,
-
-                category: ProgramClauseCategory::ImpliedBound,
-            })
-        })
-        .map(Clause::ForAll);
-
-    tcx.mk_clauses(iter::once(well_formed_clause).chain(from_env_clauses))
-}
-
-pub fn program_clauses_for_associated_type_def(tcx: TyCtxt<'_>, item_id: DefId) -> Clauses<'_> {
-    // Rule ProjectionEq-Placeholder
-    //
-    // ```
-    // trait Trait<P1..Pn> {
-    //     type AssocType<Pn+1..Pm>;
-    // }
-    // ```
-    //
-    // `ProjectionEq` can succeed by skolemizing, see "associated type"
-    // chapter for more:
-    // ```
-    // forall<Self, P1..Pn, Pn+1..Pm> {
-    //     ProjectionEq(
-    //         <Self as Trait<P1..Pn>>::AssocType<Pn+1..Pm> =
-    //         (Trait::AssocType)<Self, P1..Pn, Pn+1..Pm>
-    //     )
-    // }
-    // ```
-
-    let item = tcx.associated_item(item_id);
-    debug_assert_eq!(item.kind, ty::AssocKind::Type);
-    let trait_id = match item.container {
-        ty::AssocItemContainer::TraitContainer(trait_id) => trait_id,
-        _ => bug!("not an trait container"),
-    };
-
-    let trait_bound_vars = InternalSubsts::bound_vars_for_item(tcx, trait_id);
-    let trait_ref = ty::TraitRef { def_id: trait_id, substs: trait_bound_vars };
-
-    let projection_ty = ty::ProjectionTy::from_ref_and_name(tcx, trait_ref, item.ident);
-    let placeholder_ty = tcx.mk_ty(ty::UnnormalizedProjection(projection_ty));
-    let projection_eq =
-        WhereClause::ProjectionEq(ty::ProjectionPredicate { projection_ty, ty: placeholder_ty });
-
-    let projection_eq_clause = ProgramClause {
-        goal: DomainGoal::Holds(projection_eq),
-        hypotheses: ty::List::empty(),
-        category: ProgramClauseCategory::Other,
-    };
-    let projection_eq_clause = Clause::ForAll(ty::Binder::bind(projection_eq_clause));
-
-    // Rule WellFormed-AssocTy
-    // ```
-    // forall<Self, P1..Pn, Pn+1..Pm> {
-    //     WellFormed((Trait::AssocType)<Self, P1..Pn, Pn+1..Pm>)
-    //         :- WellFormed(Self: Trait<P1..Pn>)
-    // }
-    // ```
-
-    let trait_predicate = ty::TraitPredicate { trait_ref };
-    let hypothesis =
-        tcx.mk_goal(DomainGoal::WellFormed(WellFormed::Trait(trait_predicate)).into_goal());
-
-    let wf_clause = ProgramClause {
-        goal: DomainGoal::WellFormed(WellFormed::Ty(placeholder_ty)),
-        hypotheses: tcx.mk_goals(iter::once(hypothesis)),
-        category: ProgramClauseCategory::WellFormed,
-    };
-    let wf_clause = Clause::ForAll(ty::Binder::bind(wf_clause));
-
-    // Rule Implied-Trait-From-AssocTy
-    // ```
-    // forall<Self, P1..Pn, Pn+1..Pm> {
-    //     FromEnv(Self: Trait<P1..Pn>)
-    //         :- FromEnv((Trait::AssocType)<Self, P1..Pn, Pn+1..Pm>)
-    // }
-    // ```
-
-    let hypothesis = tcx.mk_goal(DomainGoal::FromEnv(FromEnv::Ty(placeholder_ty)).into_goal());
-
-    let from_env_clause = ProgramClause {
-        goal: DomainGoal::FromEnv(FromEnv::Trait(trait_predicate)),
-        hypotheses: tcx.mk_goals(iter::once(hypothesis)),
-        category: ProgramClauseCategory::ImpliedBound,
-    };
-    let from_env_clause = Clause::ForAll(ty::Binder::bind(from_env_clause));
-
-    // Rule ProjectionEq-Normalize
-    //
-    // ProjectionEq can succeed by normalizing:
-    // ```
-    // forall<Self, P1..Pn, Pn+1..Pm, U> {
-    //   ProjectionEq(<Self as Trait<P1..Pn>>::AssocType<Pn+1..Pm> = U) :-
-    //       Normalize(<Self as Trait<P1..Pn>>::AssocType<Pn+1..Pm> -> U)
-    // }
-    // ```
-
-    let offset = tcx.generics_of(trait_id).params.iter().map(|p| p.index).max().unwrap_or(0);
-    // Add a new type param after the existing ones (`U` in the comment above).
-    let ty_var = ty::Bound(ty::INNERMOST, ty::BoundVar::from_u32(offset + 1).into());
-
-    // `ProjectionEq(<Self as Trait<P1..Pn>>::AssocType<Pn+1..Pm> = U)`
-    let projection = ty::ProjectionPredicate { projection_ty, ty: tcx.mk_ty(ty_var) };
-
-    // `Normalize(<A0 as Trait<A1..An>>::AssocType<Pn+1..Pm> -> U)`
-    let hypothesis = tcx.mk_goal(DomainGoal::Normalize(projection).into_goal());
-
-    //  ProjectionEq(<Self as Trait<P1..Pn>>::AssocType<Pn+1..Pm> = U) :-
-    //      Normalize(<Self as Trait<P1..Pn>>::AssocType<Pn+1..Pm> -> U)
-    let normalize_clause = ProgramClause {
-        goal: DomainGoal::Holds(WhereClause::ProjectionEq(projection)),
-        hypotheses: tcx.mk_goals(iter::once(hypothesis)),
-        category: ProgramClauseCategory::Other,
-    };
-    let normalize_clause = Clause::ForAll(ty::Binder::bind(normalize_clause));
-
-    let clauses = iter::once(projection_eq_clause)
-        .chain(iter::once(wf_clause))
-        .chain(iter::once(from_env_clause))
-        .chain(iter::once(normalize_clause));
-
-    tcx.mk_clauses(clauses)
-}
-
-pub fn program_clauses_for_associated_type_value(tcx: TyCtxt<'_>, item_id: DefId) -> Clauses<'_> {
-    // Rule Normalize-From-Impl (see rustc dev guide)
-    //
-    // ```
-    // impl<P0..Pn> Trait<A1..An> for A0 {
-    //     type AssocType<Pn+1..Pm> = T;
-    // }
-    // ```
-    //
-    // FIXME: For the moment, we don't account for where clauses written on the associated
-    // ty definition (i.e., in the trait def, as in `type AssocType<T> where T: Sized`).
-    // ```
-    // forall<P0..Pm> {
-    //   forall<Pn+1..Pm> {
-    //     Normalize(<A0 as Trait<A1..An>>::AssocType<Pn+1..Pm> -> T) :-
-    //       Implemented(A0: Trait<A1..An>)
-    //   }
-    // }
-    // ```
-
-    let item = tcx.associated_item(item_id);
-    debug_assert_eq!(item.kind, ty::AssocKind::Type);
-    let impl_id = match item.container {
-        ty::AssocItemContainer::ImplContainer(impl_id) => impl_id,
-        _ => bug!("not an impl container"),
-    };
-
-    let impl_bound_vars = InternalSubsts::bound_vars_for_item(tcx, impl_id);
-
-    // `A0 as Trait<A1..An>`
-    let trait_ref = tcx.impl_trait_ref(impl_id).unwrap().subst(tcx, impl_bound_vars);
-
-    // `T`
-    let ty = tcx.type_of(item_id);
-
-    // `Implemented(A0: Trait<A1..An>)`
-    let trait_implemented: DomainGoal<'_> = ty::TraitPredicate { trait_ref }.lower();
-
-    // `<A0 as Trait<A1..An>>::AssocType<Pn+1..Pm>`
-    let projection_ty = ty::ProjectionTy::from_ref_and_name(tcx, trait_ref, item.ident);
-
-    // `Normalize(<A0 as Trait<A1..An>>::AssocType<Pn+1..Pm> -> T)`
-    let normalize_goal = DomainGoal::Normalize(ty::ProjectionPredicate { projection_ty, ty });
-
-    // `Normalize(... -> T) :- ...`
-    let normalize_clause = ProgramClause {
-        goal: normalize_goal,
-        hypotheses: tcx.mk_goals(iter::once(tcx.mk_goal(GoalKind::DomainGoal(trait_implemented)))),
-        category: ProgramClauseCategory::Other,
-    };
-    let normalize_clause = Clause::ForAll(ty::Binder::bind(normalize_clause));
-
-    tcx.mk_clauses(iter::once(normalize_clause))
-}
-
-pub fn dump_program_clauses(tcx: TyCtxt<'_>) {
-    if !tcx.features().rustc_attrs {
-        return;
-    }
-
-    let mut visitor = ClauseDumper { tcx };
-    tcx.hir().krate().visit_all_item_likes(&mut visitor.as_deep_visitor());
-}
-
-struct ClauseDumper<'tcx> {
-    tcx: TyCtxt<'tcx>,
-}
-
-impl ClauseDumper<'tcx> {
-    fn process_attrs(&mut self, hir_id: hir::HirId, attrs: &[ast::Attribute]) {
-        let def_id = self.tcx.hir().local_def_id(hir_id);
-        for attr in attrs {
-            let mut clauses = None;
-
-            if attr.check_name(sym::rustc_dump_program_clauses) {
-                clauses = Some(self.tcx.program_clauses_for(def_id));
-            }
-
-            if attr.check_name(sym::rustc_dump_env_program_clauses) {
-                let environment = self.tcx.environment(def_id);
-                clauses = Some(self.tcx.program_clauses_for_env(environment));
-            }
-
-            if let Some(clauses) = clauses {
-                let mut err = self.tcx.sess.struct_span_err(attr.span, "program clause dump");
-
-                let mut strings: Vec<_> = clauses.iter().map(|clause| clause.to_string()).collect();
-
-                strings.sort();
-
-                for string in strings {
-                    err.note(&string);
-                }
-
-                err.emit();
-            }
-        }
-    }
-}
-
-impl Visitor<'tcx> for ClauseDumper<'tcx> {
-    type Map = Map<'tcx>;
-
-    fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
-        NestedVisitorMap::OnlyBodies(self.tcx.hir())
-    }
-
-    fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
-        self.process_attrs(item.hir_id, &item.attrs);
-        intravisit::walk_item(self, item);
-    }
-
-    fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) {
-        self.process_attrs(trait_item.hir_id, &trait_item.attrs);
-        intravisit::walk_trait_item(self, trait_item);
-    }
-
-    fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) {
-        self.process_attrs(impl_item.hir_id, &impl_item.attrs);
-        intravisit::walk_impl_item(self, impl_item);
-    }
-
-    fn visit_struct_field(&mut self, s: &'tcx hir::StructField<'tcx>) {
-        self.process_attrs(s.hir_id, &s.attrs);
-        intravisit::walk_struct_field(self, s);
-    }
-}