diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index 9a5c726901fe8..eca1ada851814 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -1456,7 +1456,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         // Even if the type may have no inference variables, during
         // type-checking closure types are in local tables only.
         if !self.in_progress_tables.is_some() || !ty.has_closure_types() {
-            if let Some((param_env, ty)) = self.tcx.lift_to_global(&(param_env, ty)) {
+            if !(param_env, ty).has_local_value() {
                 return ty.is_copy_modulo_regions(self.tcx.global_tcx(), param_env, span);
             }
         }
diff --git a/src/librustc/infer/outlives/free_region_map.rs b/src/librustc/infer/outlives/free_region_map.rs
index 1250995a59c10..c085df6a6e7ab 100644
--- a/src/librustc/infer/outlives/free_region_map.rs
+++ b/src/librustc/infer/outlives/free_region_map.rs
@@ -11,6 +11,10 @@ pub struct FreeRegionMap<'tcx> {
 }
 
 impl<'tcx> FreeRegionMap<'tcx> {
+    pub fn elements(&self) -> impl Iterator<Item=&Region<'tcx>> {
+        self.relation.elements()
+    }
+
     pub fn is_empty(&self) -> bool {
         self.relation.is_empty()
     }
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index e7253a73bd418..088c862dcb879 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -465,9 +465,11 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
     ) -> bool {
         self.infcx.map(|infcx| infcx.type_is_copy_modulo_regions(param_env, ty, span))
             .or_else(|| {
-                self.tcx.lift_to_global(&(param_env, ty)).map(|(param_env, ty)| {
-                    ty.is_copy_modulo_regions(self.tcx.global_tcx(), param_env, span)
-                })
+                if (param_env, ty).has_local_value() {
+                    None
+                } else {
+                    Some(ty.is_copy_modulo_regions(self.tcx, param_env, span))
+                }
             })
             .unwrap_or(true)
     }
diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs
index e8113b4516cda..b57fdc95830cd 100644
--- a/src/librustc/mir/interpret/error.rs
+++ b/src/librustc/mir/interpret/error.rs
@@ -37,6 +37,10 @@ impl ErrorHandled {
     }
 }
 
+CloneTypeFoldableImpls! {
+    ErrorHandled,
+}
+
 pub type ConstEvalRawResult<'tcx> = Result<RawConst<'tcx>, ErrorHandled>;
 pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, ErrorHandled>;
 
diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs
index f106458c7676a..99b5ef3894b9c 100644
--- a/src/librustc/traits/fulfill.rs
+++ b/src/librustc/traits/fulfill.rs
@@ -461,41 +461,35 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
             }
 
             ty::Predicate::ConstEvaluatable(def_id, substs) => {
-                match self.selcx.tcx().lift_to_global(&obligation.param_env) {
-                    None => {
+                if obligation.param_env.has_local_value() {
                         ProcessResult::Unchanged
-                    }
-                    Some(param_env) => {
-                        match self.selcx.tcx().lift_to_global(&substs) {
-                            Some(substs) => {
-                                let instance = ty::Instance::resolve(
-                                    self.selcx.tcx().global_tcx(),
-                                    param_env,
-                                    def_id,
-                                    substs,
-                                );
-                                if let Some(instance) = instance {
-                                    let cid = GlobalId {
-                                        instance,
-                                        promoted: None,
-                                    };
-                                    match self.selcx.tcx().at(obligation.cause.span)
-                                                          .const_eval(param_env.and(cid)) {
-                                        Ok(_) => ProcessResult::Changed(vec![]),
-                                        Err(err) => ProcessResult::Error(
-                                            CodeSelectionError(ConstEvalFailure(err)))
-                                    }
-                                } else {
-                                    ProcessResult::Error(CodeSelectionError(
-                                        ConstEvalFailure(ErrorHandled::TooGeneric)
-                                    ))
-                                }
-                            },
-                            None => {
-                                pending_obligation.stalled_on = substs.types().collect();
-                                ProcessResult::Unchanged
+                } else {
+                    if !substs.has_local_value() {
+                        let instance = ty::Instance::resolve(
+                            self.selcx.tcx().global_tcx(),
+                            obligation.param_env,
+                            def_id,
+                            substs,
+                        );
+                        if let Some(instance) = instance {
+                            let cid = GlobalId {
+                                instance,
+                                promoted: None,
+                            };
+                            match self.selcx.tcx().at(obligation.cause.span)
+                                                    .const_eval(obligation.param_env.and(cid)) {
+                                Ok(_) => ProcessResult::Changed(vec![]),
+                                Err(err) => ProcessResult::Error(
+                                    CodeSelectionError(ConstEvalFailure(err)))
                             }
+                        } else {
+                            ProcessResult::Error(CodeSelectionError(
+                                ConstEvalFailure(ErrorHandled::TooGeneric)
+                            ))
                         }
+                    } else {
+                        pending_obligation.stalled_on = substs.types().collect();
+                        ProcessResult::Unchanged
                     }
                 }
             }
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index 8d17df1e61055..1ca92d79fa5f6 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -457,6 +457,16 @@ pub enum SelectionError<'tcx> {
     Overflow,
 }
 
+EnumTypeFoldableImpl! {
+    impl<'tcx> TypeFoldable<'tcx> for SelectionError<'tcx> {
+        (SelectionError::Unimplemented),
+        (SelectionError::OutputTypeParameterMismatch)(a, b, c),
+        (SelectionError::TraitNotObjectSafe)(a),
+        (SelectionError::ConstEvalFailure)(a),
+        (SelectionError::Overflow),
+    }
+}
+
 pub struct FulfillmentError<'tcx> {
     pub obligation: PredicateObligation<'tcx>,
     pub code: FulfillmentErrorCode<'tcx>
@@ -782,13 +792,11 @@ fn do_normalize_predicates<'tcx>(
                 return Err(ErrorReported)
             }
         };
-
-        match tcx.lift_to_global(&predicates) {
-            Some(predicates) => Ok(predicates),
-            None => {
-                // FIXME: shouldn't we, you know, actually report an error here? or an ICE?
-                Err(ErrorReported)
-            }
+        if predicates.has_local_value() {
+            // FIXME: shouldn't we, you know, actually report an error here? or an ICE?
+            Err(ErrorReported)
+        } else {
+            Ok(predicates)
         }
     })
 }
diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs
index 0f4b7aff82bce..8bd8f941fb3dd 100644
--- a/src/librustc/traits/project.rs
+++ b/src/librustc/traits/project.rs
@@ -399,7 +399,8 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
     fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
         if let ConstValue::Unevaluated(def_id, substs) = constant.val {
             let tcx = self.selcx.tcx().global_tcx();
-            if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) {
+            let param_env = self.param_env;
+            if !param_env.has_local_value() {
                 if substs.needs_infer() || substs.has_placeholders() {
                     let identity_substs = InternalSubsts::identity_for_item(tcx, def_id);
                     let instance = ty::Instance::resolve(tcx, param_env, def_id, identity_substs);
@@ -414,7 +415,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
                         }
                     }
                 } else {
-                    if let Some(substs) = self.tcx().lift_to_global(&substs) {
+                    if !substs.has_local_value() {
                         let instance = ty::Instance::resolve(tcx, param_env, def_id, substs);
                         if let Some(instance) = instance {
                             let cid = GlobalId {
diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs
index 5dd1b9e3d53f3..55e622e46b966 100644
--- a/src/librustc/traits/query/normalize.rs
+++ b/src/librustc/traits/query/normalize.rs
@@ -193,7 +193,8 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
     fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
         if let ConstValue::Unevaluated(def_id, substs) = constant.val {
             let tcx = self.infcx.tcx.global_tcx();
-            if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) {
+            let param_env = self.param_env;
+            if !param_env.has_local_value() {
                 if substs.needs_infer() || substs.has_placeholders() {
                     let identity_substs = InternalSubsts::identity_for_item(tcx, def_id);
                     let instance = ty::Instance::resolve(tcx, param_env, def_id, identity_substs);
@@ -208,7 +209,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
                         }
                     }
                 } else {
-                    if let Some(substs) = self.tcx().lift_to_global(&substs) {
+                    if !substs.has_local_value() {
                         let instance = ty::Instance::resolve(tcx, param_env, def_id, substs);
                         if let Some(instance) = instance {
                             let cid = GlobalId {
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 7c4742259ac16..798a25fe7b1bc 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -328,6 +328,23 @@ impl<'a, 'tcx> ty::Lift<'tcx> for SelectionCandidate<'a> {
     }
 }
 
+EnumTypeFoldableImpl! {
+    impl<'tcx> TypeFoldable<'tcx> for SelectionCandidate<'tcx> {
+        (SelectionCandidate::BuiltinCandidate) { has_nested },
+        (SelectionCandidate::ParamCandidate)(poly_trait_ref),
+        (SelectionCandidate::ImplCandidate)(def_id),
+        (SelectionCandidate::AutoImplCandidate)(def_id),
+        (SelectionCandidate::ProjectionCandidate),
+        (SelectionCandidate::ClosureCandidate),
+        (SelectionCandidate::GeneratorCandidate),
+        (SelectionCandidate::FnPointerCandidate),
+        (SelectionCandidate::TraitAliasCandidate)(def_id),
+        (SelectionCandidate::ObjectCandidate),
+        (SelectionCandidate::BuiltinObjectCandidate),
+        (SelectionCandidate::BuiltinUnsizeCandidate),
+    }
+}
+
 struct SelectionCandidateSet<'tcx> {
     // a list of candidates that definitely apply to the current
     // obligation (meaning: types unify).
@@ -818,27 +835,25 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
             ty::Predicate::ConstEvaluatable(def_id, substs) => {
                 let tcx = self.tcx();
-                match tcx.lift_to_global(&(obligation.param_env, substs)) {
-                    Some((param_env, substs)) => {
-                        let instance =
-                            ty::Instance::resolve(tcx.global_tcx(), param_env, def_id, substs);
-                        if let Some(instance) = instance {
-                            let cid = GlobalId {
-                                instance,
-                                promoted: None,
-                            };
-                            match self.tcx().const_eval(param_env.and(cid)) {
-                                Ok(_) => Ok(EvaluatedToOk),
-                                Err(_) => Ok(EvaluatedToErr),
-                            }
-                        } else {
-                            Ok(EvaluatedToErr)
+                if !(obligation.param_env, substs).has_local_value() {
+                    let param_env = obligation.param_env;
+                    let instance =
+                        ty::Instance::resolve(tcx, param_env, def_id, substs);
+                    if let Some(instance) = instance {
+                        let cid = GlobalId {
+                            instance,
+                            promoted: None,
+                        };
+                        match self.tcx().const_eval(param_env.and(cid)) {
+                            Ok(_) => Ok(EvaluatedToOk),
+                            Err(_) => Ok(EvaluatedToErr),
                         }
+                    } else {
+                        Ok(EvaluatedToErr)
                     }
-                    None => {
-                        // Inference variables still left in param_env or substs.
-                        Ok(EvaluatedToAmbig)
-                    }
+                } else {
+                    // Inference variables still left in param_env or substs.
+                    Ok(EvaluatedToAmbig)
                 }
             }
         }
@@ -1172,7 +1187,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         }
 
         if self.can_use_global_caches(param_env) {
-            if let Some(trait_ref) = self.tcx().lift_to_global(&trait_ref) {
+            if !trait_ref.has_local_value() {
                 debug!(
                     "insert_evaluation_cache(trait_ref={:?}, candidate={:?}) global",
                     trait_ref, result,
@@ -1645,8 +1660,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             if let Err(Overflow) = candidate {
                 // Don't cache overflow globally; we only produce this
                 // in certain modes.
-            } else if let Some(trait_ref) = tcx.lift_to_global(&trait_ref) {
-                if let Some(candidate) = tcx.lift_to_global(&candidate) {
+            } else if !trait_ref.has_local_value() {
+                if !candidate.has_local_value() {
                     debug!(
                         "insert_candidate_cache(trait_ref={:?}, candidate={:?}) global",
                         trait_ref, candidate,
diff --git a/src/librustc/ty/erase_regions.rs b/src/librustc/ty/erase_regions.rs
index 999b4eff85697..3dd1fd100f2a4 100644
--- a/src/librustc/ty/erase_regions.rs
+++ b/src/librustc/ty/erase_regions.rs
@@ -42,10 +42,10 @@ impl TypeFolder<'tcx> for RegionEraserVisitor<'tcx> {
     }
 
     fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        if let Some(ty_lifted) = self.tcx.lift_to_global(&ty) {
-            self.tcx.erase_regions_ty(ty_lifted)
-        } else {
+        if ty.has_local_value() {
             ty.super_fold_with(self)
+        } else {
+            self.tcx.erase_regions_ty(ty)
         }
     }
 
diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs
index 8b98a2916a766..ab7df8e4e845b 100644
--- a/src/librustc/ty/fold.rs
+++ b/src/librustc/ty/fold.rs
@@ -91,6 +91,9 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
     fn has_infer_types(&self) -> bool {
         self.has_type_flags(TypeFlags::HAS_TY_INFER)
     }
+    fn has_local_value(&self) -> bool {
+        self.has_type_flags(TypeFlags::KEEP_IN_LOCAL_TCX)
+    }
     fn needs_infer(&self) -> bool {
         self.has_type_flags(
             TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER | TypeFlags::HAS_CT_INFER
@@ -922,6 +925,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor {
     }
 }
 
+// FIXME: Optimize for checking for infer flags
 struct HasTypeFlagsVisitor {
     flags: ty::TypeFlags,
 }
diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs
index 46adb7eb2a476..a6bfc2dee613b 100644
--- a/src/librustc/ty/relate.rs
+++ b/src/librustc/ty/relate.rs
@@ -550,7 +550,7 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
         if let ConstValue::Unevaluated(def_id, substs) = x.val {
             // FIXME(eddyb) get the right param_env.
             let param_env = ty::ParamEnv::empty();
-            if let Some(substs) = tcx.lift_to_global(&substs) {
+            if !substs.has_local_value() {
                 let instance = ty::Instance::resolve(
                     tcx.global_tcx(),
                     param_env,
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index 3d8170586c47f..27cd745c20fcb 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -821,6 +821,13 @@ EnumTypeFoldableImpl! {
     } where T: TypeFoldable<'tcx>
 }
 
+EnumTypeFoldableImpl! {
+    impl<'tcx, T, E> TypeFoldable<'tcx> for Result<T, E> {
+        (Ok)(a),
+        (Err)(a),
+    } where T: TypeFoldable<'tcx>, E: TypeFoldable<'tcx>,
+}
+
 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
     fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         Rc::new((**self).fold_with(folder))
diff --git a/src/librustc_data_structures/transitive_relation.rs b/src/librustc_data_structures/transitive_relation.rs
index 0974607fabea8..d7cbd1e2e4b47 100644
--- a/src/librustc_data_structures/transitive_relation.rs
+++ b/src/librustc_data_structures/transitive_relation.rs
@@ -58,6 +58,10 @@ impl<T: Clone + Debug + Eq + Hash> TransitiveRelation<T> {
         self.edges.is_empty()
     }
 
+    pub fn elements(&self) -> impl Iterator<Item=&T> {
+        self.elements.iter()
+    }
+
     fn index(&self, a: &T) -> Option<Index> {
         self.map.get(a).cloned()
     }
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
index 41ed564d0f0e1..a4fa1d98255ba 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
@@ -809,7 +809,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         ty: Ty<'tcx>,
     ) -> Option<ClosureOutlivesSubject<'tcx>> {
         let tcx = infcx.tcx;
-        let gcx = tcx.global_tcx();
 
         debug!("try_promote_type_test_subject(ty = {:?})", ty);
 
@@ -863,8 +862,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         });
         debug!("try_promote_type_test_subject: folded ty = {:?}", ty);
 
-        // `lift_to_global` will only fail if we failed to promote some region.
-        gcx.lift_to_global(&ty)?;
+        // `has_local_value` will only be true if we failed to promote some region.
+        if ty.has_local_value() {
+            return None;
+        }
 
         Some(ClosureOutlivesSubject::Ty(ty))
     }
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index 034ff5f834767..d612d042f7f23 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -3,7 +3,7 @@ use crate::constrained_generic_params::{identify_constrained_generic_params, Par
 
 use crate::hir::def_id::DefId;
 use rustc::traits::{self, ObligationCauseCode};
-use rustc::ty::{self, Lift, Ty, TyCtxt, GenericParamDefKind, TypeFoldable, ToPredicate};
+use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind, TypeFoldable, ToPredicate};
 use rustc::ty::subst::{Subst, InternalSubsts};
 use rustc::util::nodemap::{FxHashSet, FxHashMap};
 use rustc::mir::interpret::ConstValue;
@@ -261,14 +261,15 @@ fn check_type_defn<'tcx, F>(
             let needs_drop_copy = || {
                 packed && {
                     let ty = variant.fields.last().unwrap().ty;
-                    fcx.tcx.erase_regions(&ty).lift_to_tcx(fcx_tcx)
-                        .map(|ty| ty.needs_drop(fcx_tcx, fcx_tcx.param_env(def_id)))
-                        .unwrap_or_else(|| {
+                    let ty = fcx.tcx.erase_regions(&ty);
+                    if ty.has_local_value() {
                             fcx_tcx.sess.delay_span_bug(
                                 item.span, &format!("inference variables in {:?}", ty));
                             // Just treat unresolved type expression as if it needs drop.
                             true
-                        })
+                    } else {
+                        ty.needs_drop(fcx_tcx, fcx_tcx.param_env(def_id))
+                    }
                 }
             };
             let all_sized =
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index 6a95dec1c81bc..28711e32a4c51 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -363,10 +363,8 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
     }
 
     fn visit_free_region_map(&mut self) {
-        let free_region_map = self.tcx()
-            .lift_to_global(&self.fcx.tables.borrow().free_region_map);
-        let free_region_map = free_region_map.expect("all regions in free-region-map are global");
-        self.tables.free_region_map = free_region_map;
+        self.tables.free_region_map = self.fcx.tables.borrow().free_region_map.clone();
+        debug_assert!(!self.tables.free_region_map.elements().any(|r| r.has_local_value()));
     }
 
     fn visit_user_provided_tys(&mut self) {
@@ -381,12 +379,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                 local_id,
             };
 
-            let c_ty = if let Some(c_ty) = self.tcx().lift_to_global(c_ty) {
-                c_ty
-            } else {
+            if cfg!(debug_assertions) && c_ty.has_local_value() {
                 span_bug!(
                     hir_id.to_span(self.fcx.tcx),
-                    "writeback: `{:?}` missing from the global type context",
+                    "writeback: `{:?}` is a local value",
                     c_ty
                 );
             };
@@ -423,12 +419,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
         debug_assert_eq!(fcx_tables.local_id_root, self.tables.local_id_root);
 
         for (&def_id, c_sig) in fcx_tables.user_provided_sigs.iter() {
-            let c_sig = if let Some(c_sig) = self.tcx().lift_to_global(c_sig) {
-                c_sig
-            } else {
+            if cfg!(debug_assertions) && c_sig.has_local_value() {
                 span_bug!(
                     self.fcx.tcx.hir().span_if_local(def_id).unwrap(),
-                    "writeback: `{:?}` missing from the global type context",
+                    "writeback: `{:?}` is a local value",
                     c_sig
                 );
             };
@@ -592,10 +586,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                 }
             }
 
-            if let Some(substs) = self.tcx().lift_to_global(&opaque_defn.substs) {
+            if !opaque_defn.substs.has_local_value() {
                 let new = ty::ResolvedOpaqueTy {
                     concrete_type: definition_ty,
-                    substs,
+                    substs: opaque_defn.substs,
                 };
 
                 let old = self.tables
@@ -617,7 +611,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
             } else {
                 self.tcx().sess.delay_span_bug(
                     span,
-                    "cannot lift `opaque_defn` substs to global type context",
+                    "`opaque_defn` is a local value",
                 );
             }
         }
@@ -743,20 +737,19 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
         }
     }
 
-    fn resolve<T>(&self, x: &T, span: &dyn Locatable) -> T::Lifted
+    fn resolve<T>(&self, x: &T, span: &dyn Locatable) -> T
     where
-        T: TypeFoldable<'tcx> + ty::Lift<'tcx>,
+        T: TypeFoldable<'tcx>,
     {
         let x = x.fold_with(&mut Resolver::new(self.fcx, span, self.body));
-        if let Some(lifted) = self.tcx().lift_to_global(&x) {
-            lifted
-        } else {
+        if cfg!(debug_assertions) && x.has_local_value() {
             span_bug!(
                 span.to_span(self.fcx.tcx),
-                "writeback: `{:?}` missing from the global type context",
+                "writeback: `{:?}` is a local value",
                 x
             );
         }
+        x
     }
 }