about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/dep_graph/dep_node.rs1
-rw-r--r--src/librustc/infer/mod.rs136
-rw-r--r--src/librustc/traits/mod.rs5
-rw-r--r--src/librustc/traits/trans/mod.rs80
-rw-r--r--src/librustc/ty/context.rs3
-rw-r--r--src/librustc/ty/instance.rs2
-rw-r--r--src/librustc/ty/layout.rs12
-rw-r--r--src/librustc/ty/maps/config.rs6
-rw-r--r--src/librustc/ty/maps/mod.rs5
-rw-r--r--src/librustc/ty/maps/plumbing.rs1
-rw-r--r--src/librustc_lint/types.rs19
-rw-r--r--src/librustc_mir/borrow_check/mod.rs2
-rw-r--r--src/librustc_mir/interpret/eval_context.rs6
-rw-r--r--src/librustc_mir/interpret/terminator/mod.rs15
-rw-r--r--src/librustc_mir/monomorphize/item.rs5
-rw-r--r--src/librustc_mir/monomorphize/mod.rs2
-rw-r--r--src/librustc_mir/shim.rs9
-rw-r--r--src/librustc_mir/util/elaborate_drops.rs9
-rw-r--r--src/librustc_trans/abi.rs2
-rw-r--r--src/librustc_trans/base.rs2
-rw-r--r--src/librustc_trans/debuginfo/metadata.rs9
-rw-r--r--src/librustc_trans/debuginfo/mod.rs6
-rw-r--r--src/librustc_trans/debuginfo/type_names.rs8
-rw-r--r--src/librustc_trans/declare.rs4
-rw-r--r--src/librustc_trans/intrinsic.rs7
-rw-r--r--src/librustc_trans/mir/block.rs10
-rw-r--r--src/librustc_trans/mir/mod.rs3
-rw-r--r--src/librustc_trans/type_of.rs5
28 files changed, 91 insertions, 283 deletions
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 130fbc19267..8d7fef90b75 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -635,7 +635,6 @@ define_dep_nodes!( <'tcx>
     [] CodegenUnit(InternedString),
     [] CompileCodegenUnit(InternedString),
     [input] OutputFilenames,
-    [anon] NormalizeTy,
     [] NormalizeProjectionTy(CanonicalProjectionGoal<'tcx>),
     [] NormalizeTyAfterErasingRegions(ParamEnvAnd<'tcx, Ty<'tcx>>),
     [] DropckOutlives(CanonicalTyGoal<'tcx>),
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index 2c58e17b283..217a157cb33 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -21,7 +21,6 @@ use hir::def_id::DefId;
 use middle::free_region::RegionRelations;
 use middle::region;
 use middle::lang_items;
-use mir::tcx::PlaceTy;
 use ty::subst::Substs;
 use ty::{TyVid, IntVid, FloatVid};
 use ty::{self, Ty, TyCtxt};
@@ -35,7 +34,7 @@ use std::collections::BTreeMap;
 use std::fmt;
 use syntax::ast;
 use errors::DiagnosticBuilder;
-use syntax_pos::{self, Span, DUMMY_SP};
+use syntax_pos::{self, Span};
 use util::nodemap::FxHashMap;
 use arena::DroplessArena;
 
@@ -493,140 +492,7 @@ pub struct CombinedSnapshot<'a, 'tcx:'a> {
     _in_progress_tables: Option<Ref<'a, ty::TypeckTables<'tcx>>>,
 }
 
-/// Helper trait for shortening the lifetimes inside a
-/// value for post-type-checking normalization.
-///
-/// This trait offers a normalization method where the inputs and
-/// outputs both have the `'gcx` lifetime; the implementations
-/// internally create inference contexts and/or lift as needed.
-pub trait TransNormalize<'gcx>: TypeFoldable<'gcx> {
-    fn trans_normalize<'a, 'tcx>(&self,
-                                 infcx: &InferCtxt<'a, 'gcx, 'tcx>,
-                                 param_env: ty::ParamEnv<'tcx>)
-                                 -> Self;
-}
-
-macro_rules! items { ($($item:item)+) => ($($item)+) }
-macro_rules! impl_trans_normalize {
-    ($lt_gcx:tt, $($ty:ty),+) => {
-        items!($(impl<$lt_gcx> TransNormalize<$lt_gcx> for $ty {
-            fn trans_normalize<'a, 'tcx>(&self,
-                                         infcx: &InferCtxt<'a, $lt_gcx, 'tcx>,
-                                         param_env: ty::ParamEnv<'tcx>)
-                                         -> Self {
-                infcx.normalize_projections_in(param_env, self)
-            }
-        })+);
-    }
-}
-
-impl_trans_normalize!('gcx,
-    Ty<'gcx>,
-    &'gcx ty::Const<'gcx>,
-    &'gcx Substs<'gcx>,
-    ty::FnSig<'gcx>,
-    ty::PolyFnSig<'gcx>,
-    ty::ClosureSubsts<'gcx>,
-    ty::PolyTraitRef<'gcx>,
-    ty::ExistentialTraitRef<'gcx>
-);
-
-impl<'gcx> TransNormalize<'gcx> for PlaceTy<'gcx> {
-    fn trans_normalize<'a, 'tcx>(&self,
-                                 infcx: &InferCtxt<'a, 'gcx, 'tcx>,
-                                 param_env: ty::ParamEnv<'tcx>)
-                                 -> Self {
-        match *self {
-            PlaceTy::Ty { ty } => PlaceTy::Ty { ty: ty.trans_normalize(infcx, param_env) },
-            PlaceTy::Downcast { adt_def, substs, variant_index } => {
-                PlaceTy::Downcast {
-                    adt_def,
-                    substs: substs.trans_normalize(infcx, param_env),
-                    variant_index,
-                }
-            }
-        }
-    }
-}
-
-// NOTE: Callable from trans only!
-impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
-    /// Currently, higher-ranked type bounds inhibit normalization. Therefore,
-    /// each time we erase them in translation, we need to normalize
-    /// the contents.
-    pub fn erase_late_bound_regions_and_normalize<T>(self, value: &ty::Binder<T>)
-        -> T
-        where T: TransNormalize<'tcx>
-    {
-        assert!(!value.needs_subst());
-        let value = self.erase_late_bound_regions(value);
-        self.fully_normalize_associated_types_in(&value)
-    }
-
-    /// Fully normalizes any associated types in `value`, using an
-    /// empty environment and `Reveal::All` mode (therefore, suitable
-    /// only for monomorphized code during trans, basically).
-    pub fn fully_normalize_associated_types_in<T>(self, value: &T) -> T
-        where T: TransNormalize<'tcx>
-    {
-        debug!("fully_normalize_associated_types_in(t={:?})", value);
-
-        let param_env = ty::ParamEnv::reveal_all();
-        let value = self.erase_regions(value);
-
-        if !value.has_projections() {
-            return value;
-        }
-
-        self.infer_ctxt().enter(|infcx| {
-            value.trans_normalize(&infcx, param_env)
-        })
-    }
-
-    /// Does a best-effort to normalize any associated types in
-    /// `value`; this includes revealing specializable types, so this
-    /// should be not be used during type-checking, but only during
-    /// optimization and code generation.
-    pub fn normalize_associated_type_in_env<T>(
-        self, value: &T, env: ty::ParamEnv<'tcx>
-    ) -> T
-        where T: TransNormalize<'tcx>
-    {
-        debug!("normalize_associated_type_in_env(t={:?})", value);
-
-        let value = self.erase_regions(value);
-
-        if !value.has_projections() {
-            return value;
-        }
-
-        self.infer_ctxt().enter(|infcx| {
-            value.trans_normalize(&infcx, env.with_reveal_all())
-       })
-    }
-}
-
 impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
-    fn normalize_projections_in<T>(&self, param_env: ty::ParamEnv<'tcx>, value: &T) -> T::Lifted
-        where T: TypeFoldable<'tcx> + ty::Lift<'gcx>
-    {
-        let mut selcx = traits::SelectionContext::new(self);
-        let cause = traits::ObligationCause::dummy();
-        let traits::Normalized { value: result, obligations } =
-            traits::normalize(&mut selcx, param_env, cause, value);
-
-        debug!("normalize_projections_in: result={:?} obligations={:?}",
-                result, obligations);
-
-        let mut fulfill_cx = traits::FulfillmentContext::new();
-
-        for obligation in obligations {
-            fulfill_cx.register_predicate_obligation(self, obligation);
-        }
-
-        self.drain_fulfillment_cx_or_panic(DUMMY_SP, &mut fulfill_cx, &result)
-    }
-
     /// Finishes processes any obligations that remain in the
     /// fulfillment context, and then returns the result with all type
     /// variables removed and regions erased. Because this is intended
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index 3e23e382347..a2a5aa246cf 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -770,7 +770,10 @@ fn vtable_methods<'a, 'tcx>(
                 // the trait type may have higher-ranked lifetimes in it;
                 // so erase them if they appear, so that we get the type
                 // at some particular call site
-                let substs = tcx.erase_late_bound_regions_and_normalize(&ty::Binder(substs));
+                let substs = tcx.normalize_erasing_late_bound_regions(
+                    ty::ParamEnv::reveal_all(),
+                    &ty::Binder(substs),
+                );
 
                 // It's possible that the method relies on where clauses that
                 // do not hold for this particular set of type parameters.
diff --git a/src/librustc/traits/trans/mod.rs b/src/librustc/traits/trans/mod.rs
index c873580e3ad..c97f6f199d2 100644
--- a/src/librustc/traits/trans/mod.rs
+++ b/src/librustc/traits/trans/mod.rs
@@ -14,14 +14,13 @@
 // general routines.
 
 use dep_graph::{DepKind, DepTrackingMapConfig};
-use infer::TransNormalize;
 use std::marker::PhantomData;
 use syntax_pos::DUMMY_SP;
 use hir::def_id::DefId;
 use traits::{FulfillmentContext, Obligation, ObligationCause, SelectionContext, Vtable};
 use ty::{self, Ty, TyCtxt};
 use ty::subst::{Subst, Substs};
-use ty::fold::{TypeFoldable, TypeFolder};
+use ty::fold::TypeFoldable;
 
 /// Attempts to resolve an obligation to a vtable.. The result is
 /// a shallow vtable resolution -- meaning that we do not
@@ -93,12 +92,11 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
                                        param_substs: &Substs<'tcx>,
                                        value: &T)
                                        -> T
-        where T: TransNormalize<'tcx>
+        where T: TypeFoldable<'tcx>
     {
         debug!("apply_param_substs(param_substs={:?}, value={:?})", param_substs, value);
         let substituted = value.subst(self, param_substs);
-        let substituted = self.erase_regions(&substituted);
-        AssociatedTypeNormalizer::new(self).fold(&substituted)
+        self.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substituted)
     }
 
     pub fn trans_apply_param_substs_env<T>(
@@ -108,7 +106,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
         value: &T,
     ) -> T
     where
-        T: TransNormalize<'tcx>,
+        T: TypeFoldable<'tcx>,
     {
         debug!(
             "apply_param_substs_env(param_substs={:?}, value={:?}, param_env={:?})",
@@ -117,8 +115,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
             param_env,
         );
         let substituted = value.subst(self, param_substs);
-        let substituted = self.erase_regions(&substituted);
-        AssociatedTypeNormalizerEnv::new(self, param_env).fold(&substituted)
+        self.normalize_erasing_regions(param_env, substituted)
     }
 
     pub fn trans_impl_self_ty(&self, def_id: DefId, substs: &'tcx Substs<'tcx>)
@@ -128,73 +125,6 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
     }
 }
 
-struct AssociatedTypeNormalizer<'a, 'gcx: 'a> {
-    tcx: TyCtxt<'a, 'gcx, 'gcx>,
-}
-
-impl<'a, 'gcx> AssociatedTypeNormalizer<'a, 'gcx> {
-    fn new(tcx: TyCtxt<'a, 'gcx, 'gcx>) -> Self {
-        AssociatedTypeNormalizer { tcx }
-    }
-
-    fn fold<T:TypeFoldable<'gcx>>(&mut self, value: &T) -> T {
-        if !value.has_projections() {
-            value.clone()
-        } else {
-            value.fold_with(self)
-        }
-    }
-}
-
-impl<'a, 'gcx> TypeFolder<'gcx, 'gcx> for AssociatedTypeNormalizer<'a, 'gcx> {
-    fn tcx<'c>(&'c self) -> TyCtxt<'c, 'gcx, 'gcx> {
-        self.tcx
-    }
-
-    fn fold_ty(&mut self, ty: Ty<'gcx>) -> Ty<'gcx> {
-        if !ty.has_projections() {
-            ty
-        } else {
-            debug!("AssociatedTypeNormalizer: ty={:?}", ty);
-            self.tcx.fully_normalize_monormophic_ty(ty)
-        }
-    }
-}
-
-struct AssociatedTypeNormalizerEnv<'a, 'gcx: 'a> {
-    tcx: TyCtxt<'a, 'gcx, 'gcx>,
-    param_env: ty::ParamEnv<'gcx>,
-}
-
-impl<'a, 'gcx> AssociatedTypeNormalizerEnv<'a, 'gcx> {
-    fn new(tcx: TyCtxt<'a, 'gcx, 'gcx>, param_env: ty::ParamEnv<'gcx>) -> Self {
-        Self { tcx, param_env }
-    }
-
-    fn fold<T: TypeFoldable<'gcx>>(&mut self, value: &T) -> T {
-        if !value.has_projections() {
-            value.clone()
-        } else {
-            value.fold_with(self)
-        }
-    }
-}
-
-impl<'a, 'gcx> TypeFolder<'gcx, 'gcx> for AssociatedTypeNormalizerEnv<'a, 'gcx> {
-    fn tcx<'c>(&'c self) -> TyCtxt<'c, 'gcx, 'gcx> {
-        self.tcx
-    }
-
-    fn fold_ty(&mut self, ty: Ty<'gcx>) -> Ty<'gcx> {
-        if !ty.has_projections() {
-            ty
-        } else {
-            debug!("AssociatedTypeNormalizerEnv: ty={:?}", ty);
-            self.tcx.normalize_associated_type_in_env(&ty, self.param_env)
-        }
-    }
-}
-
 // Implement DepTrackingMapConfig for `trait_cache`
 pub struct TraitSelectionCache<'tcx> {
     data: PhantomData<&'tcx ()>
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 24d3b37f804..9a687028b58 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -2537,9 +2537,6 @@ pub fn provide(providers: &mut ty::maps::Providers) {
         assert_eq!(cnum, LOCAL_CRATE);
         tcx.features().clone_closures
     };
-    providers.fully_normalize_monormophic_ty = |tcx, ty| {
-        tcx.fully_normalize_associated_types_in(&ty)
-    };
     providers.features_query = |tcx, cnum| {
         assert_eq!(cnum, LOCAL_CRATE);
         Lrc::new(tcx.sess.features_untracked().clone())
diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs
index ebb058c5d29..180fb9cabd3 100644
--- a/src/librustc/ty/instance.rs
+++ b/src/librustc/ty/instance.rs
@@ -352,7 +352,7 @@ fn fn_once_adapter_instance<'a, 'tcx>(
         closure_did, substs);
 
     let sig = substs.closure_sig(closure_did, tcx);
-    let sig = tcx.erase_late_bound_regions_and_normalize(&sig);
+    let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
     assert_eq!(sig.inputs().len(), 1);
     let substs = tcx.mk_substs([Kind::from(self_ty), sig.inputs()[0].into()].iter().cloned());
 
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index 9ce232ba173..04353d2ece1 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -1213,7 +1213,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
                     data_ptr.valid_range.start = 1;
                 }
 
-                let pointee = tcx.normalize_associated_type_in_env(&pointee, param_env);
+                let pointee = tcx.normalize_erasing_regions(param_env, pointee);
                 if pointee.is_sized(tcx.at(DUMMY_SP), param_env) {
                     return Ok(tcx.intern_layout(LayoutDetails::scalar(self, data_ptr)));
                 }
@@ -1241,7 +1241,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
             // Arrays and slices.
             ty::TyArray(element, mut count) => {
                 if count.has_projections() {
-                    count = tcx.normalize_associated_type_in_env(&count, param_env);
+                    count = tcx.normalize_erasing_regions(param_env, count);
                     if count.has_projections() {
                         return Err(LayoutError::Unknown(ty));
                     }
@@ -1686,7 +1686,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
 
             // Types with no meaningful known layout.
             ty::TyProjection(_) | ty::TyAnon(..) => {
-                let normalized = tcx.normalize_associated_type_in_env(&ty, param_env);
+                let normalized = tcx.normalize_erasing_regions(param_env, ty);
                 if ty == normalized {
                     return Err(LayoutError::Unknown(ty));
                 }
@@ -1953,7 +1953,7 @@ impl<'a, 'tcx> SizeSkeleton<'tcx> {
             }
 
             ty::TyProjection(_) | ty::TyAnon(..) => {
-                let normalized = tcx.normalize_associated_type_in_env(&ty, param_env);
+                let normalized = tcx.normalize_erasing_regions(param_env, ty);
                 if ty == normalized {
                     Err(err)
                 } else {
@@ -2059,7 +2059,7 @@ impl<'a, 'tcx> LayoutOf<Ty<'tcx>> for LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
     /// executes in "reveal all" mode.
     fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
         let param_env = self.param_env.with_reveal_all();
-        let ty = self.tcx.normalize_associated_type_in_env(&ty, param_env);
+        let ty = self.tcx.normalize_erasing_regions(param_env, ty);
         let details = self.tcx.layout_raw(param_env.and(ty))?;
         let layout = TyLayout {
             ty,
@@ -2085,7 +2085,7 @@ impl<'a, 'tcx> LayoutOf<Ty<'tcx>> for LayoutCx<'tcx, ty::maps::TyCtxtAt<'a, 'tcx
     /// executes in "reveal all" mode.
     fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
         let param_env = self.param_env.with_reveal_all();
-        let ty = self.tcx.normalize_associated_type_in_env(&ty, param_env);
+        let ty = self.tcx.normalize_erasing_regions(param_env, ty);
         let details = self.tcx.layout_raw(param_env.and(ty))?;
         let layout = TyLayout {
             ty,
diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs
index 487bcf1f96a..dbfe7770bbd 100644
--- a/src/librustc/ty/maps/config.rs
+++ b/src/librustc/ty/maps/config.rs
@@ -610,12 +610,6 @@ impl<'tcx> QueryDescription<'tcx> for queries::has_copy_closures<'tcx> {
     }
 }
 
-impl<'tcx> QueryDescription<'tcx> for queries::fully_normalize_monormophic_ty<'tcx> {
-    fn describe(_tcx: TyCtxt, _: Ty) -> String {
-        format!("normalizing types")
-    }
-}
-
 impl<'tcx> QueryDescription<'tcx> for queries::features_query<'tcx> {
     fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
         format!("looking up enabled feature gates")
diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs
index 15e309c13d5..7d726d2e3cd 100644
--- a/src/librustc/ty/maps/mod.rs
+++ b/src/librustc/ty/maps/mod.rs
@@ -384,7 +384,6 @@ define_maps! { <'tcx>
     // Normally you would just use `tcx.erase_regions(&value)`,
     // however, which uses this query as a kind of cache.
     [] fn erase_regions_ty: erase_regions_ty(Ty<'tcx>) -> Ty<'tcx>,
-    [] fn fully_normalize_monormophic_ty: normalize_ty_node(Ty<'tcx>) -> Ty<'tcx>,
 
     /// Do not call this query directly: invoke `normalize` instead.
     [] fn normalize_projection_ty: NormalizeProjectionTy(
@@ -565,10 +564,6 @@ fn vtable_methods_node<'tcx>(trait_ref: ty::PolyTraitRef<'tcx>) -> DepConstructo
     DepConstructor::VtableMethods{ trait_ref }
 }
 
-fn normalize_ty_node<'tcx>(_: Ty<'tcx>) -> DepConstructor<'tcx> {
-    DepConstructor::NormalizeTy
-}
-
 fn substitute_normalize_and_test_predicates_node<'tcx>(key: (DefId, &'tcx Substs<'tcx>))
                                             -> DepConstructor<'tcx> {
     DepConstructor::SubstituteNormalizeAndTestPredicates { key }
diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs
index 53a3bcdba33..bc7186f781a 100644
--- a/src/librustc/ty/maps/plumbing.rs
+++ b/src/librustc/ty/maps/plumbing.rs
@@ -774,7 +774,6 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
         DepKind::EraseRegionsTy |
         DepKind::NormalizeProjectionTy |
         DepKind::NormalizeTyAfterErasingRegions |
-        DepKind::NormalizeTy |
         DepKind::DropckOutlives |
         DepKind::SubstituteNormalizeAndTestPredicates |
         DepKind::InstanceDefSizeEstimate |
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index 266f322e397..445fe0cc401 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -12,7 +12,7 @@
 
 use rustc::hir::map as hir_map;
 use rustc::ty::subst::Substs;
-use rustc::ty::{self, AdtKind, Ty, TyCtxt};
+use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
 use rustc::ty::layout::{self, LayoutOf};
 use util::nodemap::FxHashSet;
 use lint::{LateContext, LintContext, LintArray};
@@ -509,8 +509,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                         // make sure the fields are actually safe.
                         let mut all_phantom = true;
                         for field in &def.non_enum_variant().fields {
-                            let field_ty = cx.fully_normalize_associated_types_in(
-                                &field.ty(cx, substs)
+                            let field_ty = cx.normalize_erasing_regions(
+                                ParamEnv::reveal_all(),
+                                field.ty(cx, substs),
                             );
                             // repr(transparent) types are allowed to have arbitrary ZSTs, not just
                             // PhantomData -- skip checking all ZST fields
@@ -556,8 +557,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
 
                         let mut all_phantom = true;
                         for field in &def.non_enum_variant().fields {
-                            let field_ty = cx.fully_normalize_associated_types_in(
-                                &field.ty(cx, substs)
+                            let field_ty = cx.normalize_erasing_regions(
+                                ParamEnv::reveal_all(),
+                                field.ty(cx, substs),
                             );
                             let r = self.check_type_for_ffi(cache, field_ty);
                             match r {
@@ -596,8 +598,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                         // Check the contained variants.
                         for variant in &def.variants {
                             for field in &variant.fields {
-                                let arg = cx.fully_normalize_associated_types_in(
-                                    &field.ty(cx, substs)
+                                let arg = cx.normalize_erasing_regions(
+                                    ParamEnv::reveal_all(),
+                                    field.ty(cx, substs),
                                 );
                                 let r = self.check_type_for_ffi(cache, arg);
                                 match r {
@@ -716,7 +719,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
     fn check_type_for_ffi_and_report_errors(&mut self, sp: Span, ty: Ty<'tcx>) {
         // it is only OK to use this function because extern fns cannot have
         // any generic types right now:
-        let ty = self.cx.tcx.fully_normalize_associated_types_in(&ty);
+        let ty = self.cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
 
         match self.check_type_for_ffi(&mut FxHashSet(), ty) {
             FfiResult::FfiSafe => {}
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 3f111ebcb78..8da7c497973 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -732,7 +732,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                 for (index, field) in def.all_fields().enumerate() {
                     let gcx = self.tcx.global_tcx();
                     let field_ty = field.ty(gcx, substs);
-                    let field_ty = gcx.normalize_associated_type_in_env(&field_ty, self.param_env);
+                    let field_ty = gcx.normalize_erasing_regions(self.param_env, field_ty);
                     let place = drop_place.clone().field(Field::new(index), field_ty);
 
                     self.visit_terminator_drop(loc, term, flow_state, &place, field_ty, span);
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index d766ea3e2bd..abe45267a1f 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -285,10 +285,8 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
     pub fn monomorphize(&self, ty: Ty<'tcx>, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
         // miri doesn't care about lifetimes, and will choke on some crazy ones
         // let's simply get rid of them
-        let without_lifetimes = self.tcx.erase_regions(&ty);
-        let substituted = without_lifetimes.subst(*self.tcx, substs);
-        let substituted = self.tcx.fully_normalize_monormophic_ty(&substituted);
-        substituted
+        let substituted = ty.subst(*self.tcx, substs);
+        self.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substituted)
     }
 
     /// Return the size and aligment of the value at the given type.
diff --git a/src/librustc_mir/interpret/terminator/mod.rs b/src/librustc_mir/interpret/terminator/mod.rs
index babc7847014..a729e3a5dda 100644
--- a/src/librustc_mir/interpret/terminator/mod.rs
+++ b/src/librustc_mir/interpret/terminator/mod.rs
@@ -75,8 +75,14 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
                         match instance_ty.sty {
                             ty::TyFnDef(..) => {
                                 let real_sig = instance_ty.fn_sig(*self.tcx);
-                                let sig = self.tcx.erase_late_bound_regions_and_normalize(&sig);
-                                let real_sig = self.tcx.erase_late_bound_regions_and_normalize(&real_sig);
+                                let sig = self.tcx.normalize_erasing_late_bound_regions(
+                                    ty::ParamEnv::reveal_all(),
+                                    &sig,
+                                );
+                                let real_sig = self.tcx.normalize_erasing_late_bound_regions(
+                                    ty::ParamEnv::reveal_all(),
+                                    &real_sig,
+                                );
                                 if !self.check_sig_compat(sig, real_sig)? {
                                     return err!(FunctionPointerTyMismatch(real_sig, sig));
                                 }
@@ -95,7 +101,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
                     }
                 };
                 let args = self.operands_to_args(args)?;
-                let sig = self.tcx.erase_late_bound_regions_and_normalize(&sig);
+                let sig = self.tcx.normalize_erasing_late_bound_regions(
+                    ty::ParamEnv::reveal_all(),
+                    &sig,
+                );
                 self.eval_fn_call(
                     fn_def,
                     destination,
diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs
index 1f7f1237ba7..10e2a84038d 100644
--- a/src/librustc_mir/monomorphize/item.rs
+++ b/src/librustc_mir/monomorphize/item.rs
@@ -347,7 +347,10 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
 
                 output.push_str("fn(");
 
-                let sig = self.tcx.erase_late_bound_regions_and_normalize(&sig);
+                let sig = self.tcx.normalize_erasing_late_bound_regions(
+                    ty::ParamEnv::reveal_all(),
+                    &sig,
+                );
 
                 if !sig.inputs().is_empty() {
                     for &parameter_type in sig.inputs() {
diff --git a/src/librustc_mir/monomorphize/mod.rs b/src/librustc_mir/monomorphize/mod.rs
index 4c9789782a6..5c38735d920 100644
--- a/src/librustc_mir/monomorphize/mod.rs
+++ b/src/librustc_mir/monomorphize/mod.rs
@@ -88,7 +88,7 @@ fn fn_once_adapter_instance<'a, 'tcx>(
         closure_did, substs);
 
     let sig = substs.closure_sig(closure_did, tcx);
-    let sig = tcx.erase_late_bound_regions_and_normalize(&sig);
+    let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
     assert_eq!(sig.inputs().len(), 1);
     let substs = tcx.mk_substs([
         Kind::from(self_ty),
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index 9aff7fa2a2c..62af09cc491 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -832,14 +832,11 @@ pub fn build_adt_ctor<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a, 'gcx, 'tcx>,
     let tcx = infcx.tcx;
     let gcx = tcx.global_tcx();
     let def_id = tcx.hir.local_def_id(ctor_id);
-    let sig = gcx.fn_sig(def_id).no_late_bound_regions()
-        .expect("LBR in ADT constructor signature");
-    let sig = gcx.erase_regions(&sig);
     let param_env = gcx.param_env(def_id);
 
-    // Normalize the sig now that we have liberated the late-bound
-    // regions.
-    let sig = gcx.normalize_associated_type_in_env(&sig, param_env);
+    // Normalize the sig.
+    let sig = gcx.fn_sig(def_id).no_late_bound_regions().expect("LBR in ADT constructor signature");
+    let sig = gcx.normalize_erasing_regions(param_env, sig);
 
     let (adt_def, substs) = match sig.output().sty {
         ty::TyAdt(adt_def, substs) => (adt_def, substs),
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index 458dd488409..3f5208dd2d4 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -206,11 +206,10 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
             let field = Field::new(i);
             let subpath = self.elaborator.field_subpath(variant_path, field);
 
-            let field_ty =
-                self.tcx().normalize_associated_type_in_env(
-                    &f.ty(self.tcx(), substs),
-                    self.elaborator.param_env()
-                );
+            let field_ty = self.tcx().normalize_erasing_regions(
+                self.elaborator.param_env(),
+                f.ty(self.tcx(), substs),
+            );
             (base_place.clone().field(field, field_ty), subpath)
         }).collect()
     }
diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs
index ee0f2415bd8..c1dc8c6684a 100644
--- a/src/librustc_trans/abi.rs
+++ b/src/librustc_trans/abi.rs
@@ -650,7 +650,7 @@ impl<'a, 'tcx> FnType<'tcx> {
                        -> Self {
         let fn_ty = instance.ty(cx.tcx);
         let sig = ty_fn_sig(cx, fn_ty);
-        let sig = cx.tcx.erase_late_bound_regions_and_normalize(&sig);
+        let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
         FnType::new(cx, sig, &[])
     }
 
diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs
index 76e05ae7dcb..4da082e9d50 100644
--- a/src/librustc_trans/base.rs
+++ b/src/librustc_trans/base.rs
@@ -462,7 +462,7 @@ pub fn trans_instance<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, instance: Instance<'tc
 
     let fn_ty = instance.ty(cx.tcx);
     let sig = common::ty_fn_sig(cx, fn_ty);
-    let sig = cx.tcx.erase_late_bound_regions_and_normalize(&sig);
+    let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
 
     let lldecl = match cx.instances.borrow().get(&instance) {
         Some(&val) => val,
diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs
index d20b51ca0fd..20cc57522b5 100644
--- a/src/librustc_trans/debuginfo/metadata.rs
+++ b/src/librustc_trans/debuginfo/metadata.rs
@@ -30,7 +30,7 @@ use rustc::ty::util::TypeIdHasher;
 use rustc::ich::Fingerprint;
 use rustc::ty::Instance;
 use common::CodegenCx;
-use rustc::ty::{self, AdtKind, Ty, TyCtxt};
+use rustc::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt};
 use rustc::ty::layout::{self, Align, LayoutOf, Size, TyLayout};
 use rustc::session::config;
 use rustc::util::nodemap::FxHashMap;
@@ -353,7 +353,10 @@ fn subroutine_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
                                       span: Span)
                                       -> MetadataCreationResult
 {
-    let signature = cx.tcx.erase_late_bound_regions_and_normalize(&signature);
+    let signature = cx.tcx.normalize_erasing_late_bound_regions(
+        ty::ParamEnv::reveal_all(),
+        &signature,
+    );
 
     let mut signature_metadata: Vec<DIType> = Vec::with_capacity(signature.inputs().len() + 1);
 
@@ -589,7 +592,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
         }
         ty::TyGenerator(def_id, substs, _) => {
             let upvar_tys : Vec<_> = substs.field_tys(def_id, cx.tcx).map(|t| {
-                cx.tcx.fully_normalize_associated_types_in(&t)
+                cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t)
             }).collect();
             prepare_tuple_metadata(cx,
                                    t,
diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs
index 16279f31836..683e1835968 100644
--- a/src/librustc_trans/debuginfo/mod.rs
+++ b/src/librustc_trans/debuginfo/mod.rs
@@ -30,7 +30,7 @@ use abi::Abi;
 use common::CodegenCx;
 use builder::Builder;
 use monomorphize::Instance;
-use rustc::ty::{self, Ty};
+use rustc::ty::{self, ParamEnv, Ty};
 use rustc::mir;
 use rustc::session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
 use rustc::util::nodemap::{DefIdMap, FxHashMap, FxHashSet};
@@ -378,7 +378,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
                 name_to_append_suffix_to.push_str(",");
             }
 
-            let actual_type = cx.tcx.fully_normalize_associated_types_in(&actual_type);
+            let actual_type = cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), actual_type);
             // Add actual type name to <...> clause of function name
             let actual_type_name = compute_debuginfo_type_name(cx,
                                                                actual_type,
@@ -391,7 +391,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
         let template_params: Vec<_> = if cx.sess().opts.debuginfo == FullDebugInfo {
             let names = get_type_parameter_names(cx, generics);
             substs.types().zip(names).map(|(ty, name)| {
-                let actual_type = cx.tcx.fully_normalize_associated_types_in(&ty);
+                let actual_type = cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
                 let actual_type_metadata = type_metadata(cx, actual_type, syntax_pos::DUMMY_SP);
                 let name = CString::new(name.as_str().as_bytes()).unwrap();
                 unsafe {
diff --git a/src/librustc_trans/debuginfo/type_names.rs b/src/librustc_trans/debuginfo/type_names.rs
index a88eb9ae354..211de95c96e 100644
--- a/src/librustc_trans/debuginfo/type_names.rs
+++ b/src/librustc_trans/debuginfo/type_names.rs
@@ -117,8 +117,10 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
         },
         ty::TyDynamic(ref trait_data, ..) => {
             if let Some(principal) = trait_data.principal() {
-                let principal = cx.tcx.erase_late_bound_regions_and_normalize(
-                    &principal);
+                let principal = cx.tcx.normalize_erasing_late_bound_regions(
+                    ty::ParamEnv::reveal_all(),
+                    &principal,
+                );
                 push_item_name(cx, principal.def_id, false, output);
                 push_type_params(cx, principal.substs, output);
             }
@@ -138,7 +140,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
 
             output.push_str("fn(");
 
-            let sig = cx.tcx.erase_late_bound_regions_and_normalize(&sig);
+            let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
             if !sig.inputs().is_empty() {
                 for &parameter_type in sig.inputs() {
                     push_debuginfo_type_name(cx, parameter_type, true, output);
diff --git a/src/librustc_trans/declare.rs b/src/librustc_trans/declare.rs
index aa1cd0c27e7..c2010feb1b6 100644
--- a/src/librustc_trans/declare.rs
+++ b/src/librustc_trans/declare.rs
@@ -22,7 +22,7 @@
 
 use llvm::{self, ValueRef};
 use llvm::AttributePlace::Function;
-use rustc::ty::Ty;
+use rustc::ty::{self, Ty};
 use rustc::session::config::Sanitizer;
 use rustc_back::PanicStrategy;
 use abi::{Abi, FnType};
@@ -127,7 +127,7 @@ pub fn declare_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, name: &str,
                             fn_type: Ty<'tcx>) -> ValueRef {
     debug!("declare_rust_fn(name={:?}, fn_type={:?})", name, fn_type);
     let sig = common::ty_fn_sig(cx, fn_type);
-    let sig = cx.tcx.erase_late_bound_regions_and_normalize(&sig);
+    let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
     debug!("declare_rust_fn (after region erasure) sig={:?}", sig);
 
     let fty = FnType::new(cx, sig, &[]);
diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs
index 3f87ce7e047..4cef7470c62 100644
--- a/src/librustc_trans/intrinsic.rs
+++ b/src/librustc_trans/intrinsic.rs
@@ -100,7 +100,7 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
     };
 
     let sig = callee_ty.fn_sig(tcx);
-    let sig = tcx.erase_late_bound_regions_and_normalize(&sig);
+    let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
     let arg_tys = sig.inputs();
     let ret_ty = sig.output();
     let name = &*tcx.item_name(def_id);
@@ -1035,7 +1035,10 @@ fn generic_simd_intrinsic<'a, 'tcx>(
 
 
     let tcx = bx.tcx();
-    let sig = tcx.erase_late_bound_regions_and_normalize(&callee_ty.fn_sig(tcx));
+    let sig = tcx.normalize_erasing_late_bound_regions(
+        ty::ParamEnv::reveal_all(),
+        &callee_ty.fn_sig(tcx),
+    );
     let arg_tys = sig.inputs();
 
     // every intrinsic takes a SIMD vector as its first argument
diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs
index 606c1396c1d..96c5bb3b91d 100644
--- a/src/librustc_trans/mir/block.rs
+++ b/src/librustc_trans/mir/block.rs
@@ -281,7 +281,10 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
                     ty::TyDynamic(..) => {
                         let fn_ty = drop_fn.ty(bx.cx.tcx);
                         let sig = common::ty_fn_sig(bx.cx, fn_ty);
-                        let sig = bx.tcx().erase_late_bound_regions_and_normalize(&sig);
+                        let sig = bx.tcx().normalize_erasing_late_bound_regions(
+                            ty::ParamEnv::reveal_all(),
+                            &sig,
+                        );
                         let fn_ty = FnType::new_vtable(bx.cx, sig, &[]);
                         args = &args[..1];
                         (meth::DESTRUCTOR.get_fn(&bx, place.llextra, &fn_ty), fn_ty)
@@ -430,7 +433,10 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
                 };
                 let def = instance.map(|i| i.def);
                 let sig = callee.layout.ty.fn_sig(bx.tcx());
-                let sig = bx.tcx().erase_late_bound_regions_and_normalize(&sig);
+                let sig = bx.tcx().normalize_erasing_late_bound_regions(
+                    ty::ParamEnv::reveal_all(),
+                    &sig,
+                );
                 let abi = sig.abi;
 
                 // Handle intrinsics old trans wants Expr's for, ourselves.
diff --git a/src/librustc_trans/mir/mod.rs b/src/librustc_trans/mir/mod.rs
index a1044ac87e4..a92a59edfde 100644
--- a/src/librustc_trans/mir/mod.rs
+++ b/src/librustc_trans/mir/mod.rs
@@ -16,7 +16,6 @@ use rustc::ty::{self, TypeFoldable};
 use rustc::ty::layout::{LayoutOf, TyLayout};
 use rustc::mir::{self, Mir};
 use rustc::ty::subst::Substs;
-use rustc::infer::TransNormalize;
 use rustc::session::config::FullDebugInfo;
 use base;
 use builder::Builder;
@@ -108,7 +107,7 @@ pub struct FunctionCx<'a, 'tcx:'a> {
 
 impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
     pub fn monomorphize<T>(&self, value: &T) -> T
-        where T: TransNormalize<'tcx>
+        where T: TypeFoldable<'tcx>
     {
         self.cx.tcx.trans_apply_param_substs(self.param_substs, value)
     }
diff --git a/src/librustc_trans/type_of.rs b/src/librustc_trans/type_of.rs
index af957500f70..f37114ee4ac 100644
--- a/src/librustc_trans/type_of.rs
+++ b/src/librustc_trans/type_of.rs
@@ -258,7 +258,10 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
                     cx.layout_of(self.ty.boxed_ty()).llvm_type(cx).ptr_to()
                 }
                 ty::TyFnPtr(sig) => {
-                    let sig = cx.tcx.erase_late_bound_regions_and_normalize(&sig);
+                    let sig = cx.tcx.normalize_erasing_late_bound_regions(
+                        ty::ParamEnv::reveal_all(),
+                        &sig,
+                    );
                     FnType::new(cx, sig, &[]).llvm_type(cx).ptr_to()
                 }
                 _ => self.scalar_llvm_type_at(cx, scalar, Size::from_bytes(0))