about summary refs log tree commit diff
path: root/src/librustc
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2019-06-14 00:48:52 +0300
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2019-06-14 18:58:23 +0300
commitf3f9d6dfd92dfaeb14df891ad27b2531809dd734 (patch)
treecc6b503f85dcfa52dde1c95b52a35c3b94569a84 /src/librustc
parent0e4a56b4b04ea98bb16caada30cb2418dd06e250 (diff)
downloadrust-f3f9d6dfd92dfaeb14df891ad27b2531809dd734.tar.gz
rust-f3f9d6dfd92dfaeb14df891ad27b2531809dd734.zip
Unify all uses of 'gcx and 'tcx.
Diffstat (limited to 'src/librustc')
-rw-r--r--src/librustc/cfg/construct.rs4
-rw-r--r--src/librustc/cfg/graphviz.rs2
-rw-r--r--src/librustc/cfg/mod.rs2
-rw-r--r--src/librustc/dep_graph/dep_node.rs58
-rw-r--r--src/librustc/dep_graph/graph.rs10
-rw-r--r--src/librustc/dep_graph/safe.rs2
-rw-r--r--src/librustc/hir/check_attr.rs4
-rw-r--r--src/librustc/hir/def_id.rs2
-rw-r--r--src/librustc/hir/lowering.rs34
-rw-r--r--src/librustc/hir/upvars.rs2
-rw-r--r--src/librustc/ich/hcx.rs10
-rw-r--r--src/librustc/ich/impls_syntax.rs4
-rw-r--r--src/librustc/ich/impls_ty.rs16
-rw-r--r--src/librustc/infer/at.rs20
-rw-r--r--src/librustc/infer/canonical/canonicalizer.rs48
-rw-r--r--src/librustc/infer/canonical/mod.rs22
-rw-r--r--src/librustc/infer/canonical/query_response.rs32
-rw-r--r--src/librustc/infer/canonical/substitute.rs6
-rw-r--r--src/librustc/infer/combine.rs30
-rw-r--r--src/librustc/infer/equate.rs14
-rw-r--r--src/librustc/infer/error_reporting/mod.rs14
-rw-r--r--src/librustc/infer/error_reporting/need_type_info.rs26
-rw-r--r--src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs2
-rw-r--r--src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs28
-rw-r--r--src/librustc/infer/error_reporting/nice_region_error/mod.rs14
-rw-r--r--src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs2
-rw-r--r--src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs2
-rw-r--r--src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs15
-rw-r--r--src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs2
-rw-r--r--src/librustc/infer/error_reporting/nice_region_error/util.rs2
-rw-r--r--src/librustc/infer/error_reporting/note.rs2
-rw-r--r--src/librustc/infer/freshen.rs14
-rw-r--r--src/librustc/infer/fudge.rs10
-rw-r--r--src/librustc/infer/glb.rs20
-rw-r--r--src/librustc/infer/higher_ranked/mod.rs4
-rw-r--r--src/librustc/infer/lattice.rs8
-rw-r--r--src/librustc/infer/lexical_region_resolve/graphviz.rs20
-rw-r--r--src/librustc/infer/lexical_region_resolve/mod.rs16
-rw-r--r--src/librustc/infer/lub.rs20
-rw-r--r--src/librustc/infer/mod.rs48
-rw-r--r--src/librustc/infer/nll_relate/mod.rs32
-rw-r--r--src/librustc/infer/opaque_types/mod.rs41
-rw-r--r--src/librustc/infer/outlives/env.rs6
-rw-r--r--src/librustc/infer/outlives/free_region_map.rs6
-rw-r--r--src/librustc/infer/outlives/obligations.rs14
-rw-r--r--src/librustc/infer/outlives/verify.rs14
-rw-r--r--src/librustc/infer/region_constraints/leak_check.rs4
-rw-r--r--src/librustc/infer/region_constraints/mod.rs12
-rw-r--r--src/librustc/infer/resolve.rs44
-rw-r--r--src/librustc/infer/sub.rs14
-rw-r--r--src/librustc/infer/unify_key.rs6
-rw-r--r--src/librustc/lint/context.rs18
-rw-r--r--src/librustc/lint/mod.rs6
-rw-r--r--src/librustc/macros.rs14
-rw-r--r--src/librustc/middle/cstore.rs4
-rw-r--r--src/librustc/middle/dead.rs16
-rw-r--r--src/librustc/middle/dependency_format.rs10
-rw-r--r--src/librustc/middle/entry.rs6
-rw-r--r--src/librustc/middle/exported_symbols.rs8
-rw-r--r--src/librustc/middle/expr_use_visitor.rs20
-rw-r--r--src/librustc/middle/free_region.rs8
-rw-r--r--src/librustc/middle/intrinsicck.rs8
-rw-r--r--src/librustc/middle/lang_items.rs8
-rw-r--r--src/librustc/middle/lib_features.rs6
-rw-r--r--src/librustc/middle/liveness.rs8
-rw-r--r--src/librustc/middle/mem_categorization.rs24
-rw-r--r--src/librustc/middle/reachable.rs10
-rw-r--r--src/librustc/middle/region.rs14
-rw-r--r--src/librustc/middle/resolve_lifetime.rs18
-rw-r--r--src/librustc/middle/stability.rs18
-rw-r--r--src/librustc/middle/weak_lang_items.rs10
-rw-r--r--src/librustc/mir/interpret/error.rs12
-rw-r--r--src/librustc/mir/interpret/mod.rs2
-rw-r--r--src/librustc/mir/mod.rs34
-rw-r--r--src/librustc/mir/mono.rs34
-rw-r--r--src/librustc/mir/tcx.rs18
-rw-r--r--src/librustc/traits/auto_trait.rs54
-rw-r--r--src/librustc/traits/chalk_fulfill.rs10
-rw-r--r--src/librustc/traits/codegen/mod.rs18
-rw-r--r--src/librustc/traits/coherence.rs30
-rw-r--r--src/librustc/traits/engine.rs16
-rw-r--r--src/librustc/traits/error_reporting.rs18
-rw-r--r--src/librustc/traits/fulfill.rs28
-rw-r--r--src/librustc/traits/mod.rs38
-rw-r--r--src/librustc/traits/object_safety.rs4
-rw-r--r--src/librustc/traits/on_unimplemented.rs18
-rw-r--r--src/librustc/traits/project.rs110
-rw-r--r--src/librustc/traits/query/dropck_outlives.rs8
-rw-r--r--src/librustc/traits/query/evaluate_obligation.rs2
-rw-r--r--src/librustc/traits/query/normalize.rs10
-rw-r--r--src/librustc/traits/query/normalize_erasing_regions.rs8
-rw-r--r--src/librustc/traits/query/outlives_bounds.rs2
-rw-r--r--src/librustc/traits/query/type_op/ascribe_user_type.rs12
-rw-r--r--src/librustc/traits/query/type_op/custom.rs14
-rw-r--r--src/librustc/traits/query/type_op/eq.rs12
-rw-r--r--src/librustc/traits/query/type_op/implied_outlives_bounds.rs12
-rw-r--r--src/librustc/traits/query/type_op/mod.rs34
-rw-r--r--src/librustc/traits/query/type_op/normalize.rs78
-rw-r--r--src/librustc/traits/query/type_op/outlives.rs15
-rw-r--r--src/librustc/traits/query/type_op/prove_predicate.rs12
-rw-r--r--src/librustc/traits/query/type_op/subtype.rs12
-rw-r--r--src/librustc/traits/select.rs32
-rw-r--r--src/librustc/traits/specialize/mod.rs12
-rw-r--r--src/librustc/traits/specialize/specialization_graph.rs26
-rw-r--r--src/librustc/traits/structural_impls.rs30
-rw-r--r--src/librustc/traits/util.rs84
-rw-r--r--src/librustc/ty/_match.rs12
-rw-r--r--src/librustc/ty/adjustment.rs4
-rw-r--r--src/librustc/ty/codec.rs2
-rw-r--r--src/librustc/ty/constness.rs8
-rw-r--r--src/librustc/ty/context.rs180
-rw-r--r--src/librustc/ty/erase_regions.rs12
-rw-r--r--src/librustc/ty/error.rs6
-rw-r--r--src/librustc/ty/fast_reject.rs4
-rw-r--r--src/librustc/ty/fold.rs66
-rw-r--r--src/librustc/ty/inhabitedness/def_id_forest.rs10
-rw-r--r--src/librustc/ty/inhabitedness/mod.rs18
-rw-r--r--src/librustc/ty/instance.rs28
-rw-r--r--src/librustc/ty/layout.rs54
-rw-r--r--src/librustc/ty/mod.rs130
-rw-r--r--src/librustc/ty/outlives.rs2
-rw-r--r--src/librustc/ty/print/mod.rs16
-rw-r--r--src/librustc/ty/print/obsolete.rs4
-rw-r--r--src/librustc/ty/print/pretty.rs56
-rw-r--r--src/librustc/ty/query/config.rs22
-rw-r--r--src/librustc/ty/query/job.rs14
-rw-r--r--src/librustc/ty/query/keys.rs42
-rw-r--r--src/librustc/ty/query/on_disk_cache.rs20
-rw-r--r--src/librustc/ty/query/plumbing.rs72
-rw-r--r--src/librustc/ty/query/values.rs12
-rw-r--r--src/librustc/ty/relate.rs359
-rw-r--r--src/librustc/ty/structural_impls.rs110
-rw-r--r--src/librustc/ty/sty.rs130
-rw-r--r--src/librustc/ty/subst.rs42
-rw-r--r--src/librustc/ty/trait_def.rs10
-rw-r--r--src/librustc/ty/util.rs56
-rw-r--r--src/librustc/ty/wf.rs16
137 files changed, 1592 insertions, 1802 deletions
diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs
index a2e7ebfdb0e..139c144fbcf 100644
--- a/src/librustc/cfg/construct.rs
+++ b/src/librustc/cfg/construct.rs
@@ -8,7 +8,7 @@ use crate::hir::{self, PatKind};
 use crate::hir::def_id::DefId;
 
 struct CFGBuilder<'a, 'tcx: 'a> {
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     owner_def_id: DefId,
     tables: &'a ty::TypeckTables<'tcx>,
     graph: CFGGraph,
@@ -30,7 +30,7 @@ struct LoopScope {
     break_index: CFGIndex,    // where to go on a `break`
 }
 
-pub fn construct<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, body: &hir::Body) -> CFG {
+pub fn construct<'tcx>(tcx: TyCtxt<'tcx>, body: &hir::Body) -> CFG {
     let mut graph = graph::Graph::new();
     let entry = graph.add_node(CFGNodeData::Entry);
 
diff --git a/src/librustc/cfg/graphviz.rs b/src/librustc/cfg/graphviz.rs
index 481b5c72e93..dbc462ee49b 100644
--- a/src/librustc/cfg/graphviz.rs
+++ b/src/librustc/cfg/graphviz.rs
@@ -12,7 +12,7 @@ pub type Node<'a> = (cfg::CFGIndex, &'a cfg::CFGNode);
 pub type Edge<'a> = &'a cfg::CFGEdge;
 
 pub struct LabelledCFG<'a, 'tcx: 'a> {
-    pub tcx: TyCtxt<'tcx, 'tcx>,
+    pub tcx: TyCtxt<'tcx>,
     pub cfg: &'a cfg::CFG,
     pub name: String,
     /// `labelled_edges` controls whether we emit labels on the edges
diff --git a/src/librustc/cfg/mod.rs b/src/librustc/cfg/mod.rs
index d25d58bfd1f..db168d99a08 100644
--- a/src/librustc/cfg/mod.rs
+++ b/src/librustc/cfg/mod.rs
@@ -49,7 +49,7 @@ pub type CFGNode = graph::Node<CFGNodeData>;
 pub type CFGEdge = graph::Edge<CFGEdgeData>;
 
 impl CFG {
-    pub fn new<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, body: &hir::Body) -> CFG {
+    pub fn new<'tcx>(tcx: TyCtxt<'tcx>, body: &hir::Body) -> CFG {
         construct::construct(tcx, body)
     }
 
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 82bba96dd4c..f7647167a75 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -204,10 +204,10 @@ macro_rules! define_dep_nodes {
         impl DepNode {
             #[allow(unreachable_code, non_snake_case)]
             #[inline(always)]
-            pub fn new<'a, 'gcx, 'tcx>(tcx: TyCtxt<'gcx, 'tcx>,
-                                       dep: DepConstructor<'gcx>)
+            pub fn new<'a, 'tcx>(tcx: TyCtxt<'tcx>,
+                                       dep: DepConstructor<'tcx>)
                                        -> DepNode
-                where 'gcx: 'a + 'tcx,
+                where 'tcx: 'a,
                       'tcx: 'a
             {
                 match dep {
@@ -307,7 +307,7 @@ macro_rules! define_dep_nodes {
             /// refers to something from the previous compilation session that
             /// has been removed.
             #[inline]
-            pub fn extract_def_id(&self, tcx: TyCtxt<'_, '_>) -> Option<DefId> {
+            pub fn extract_def_id(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
                 if self.kind.can_reconstruct_query_key() {
                     let def_path_hash = DefPathHash(self.hash);
                     tcx.def_path_hash_to_def_id.as_ref()?
@@ -400,7 +400,7 @@ impl DefPathHash {
 
 impl DefId {
     #[inline(always)]
-    pub fn to_dep_node(self, tcx: TyCtxt<'_, '_>, kind: DepKind) -> DepNode {
+    pub fn to_dep_node(self, tcx: TyCtxt<'_>, kind: DepKind) -> DepNode {
         DepNode::from_def_path_hash(kind, tcx.def_path_hash(self))
     }
 }
@@ -442,50 +442,50 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
 ]);
 
 pub trait RecoverKey<'tcx>: Sized {
-    fn recover(tcx: TyCtxt<'tcx, 'tcx>, dep_node: &DepNode) -> Option<Self>;
+    fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self>;
 }
 
 impl RecoverKey<'tcx> for CrateNum {
-    fn recover(tcx: TyCtxt<'tcx, 'tcx>, dep_node: &DepNode) -> Option<Self> {
+    fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
         dep_node.extract_def_id(tcx).map(|id| id.krate)
     }
 }
 
 impl RecoverKey<'tcx> for DefId {
-    fn recover(tcx: TyCtxt<'tcx, 'tcx>, dep_node: &DepNode) -> Option<Self> {
+    fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
         dep_node.extract_def_id(tcx)
     }
 }
 
 impl RecoverKey<'tcx> for DefIndex {
-    fn recover(tcx: TyCtxt<'tcx, 'tcx>, dep_node: &DepNode) -> Option<Self> {
+    fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
         dep_node.extract_def_id(tcx).map(|id| id.index)
     }
 }
 
-trait DepNodeParams<'gcx: 'tcx, 'tcx>: fmt::Debug {
+trait DepNodeParams<'tcx>: fmt::Debug {
     const CAN_RECONSTRUCT_QUERY_KEY: bool;
 
     /// This method turns the parameters of a DepNodeConstructor into an opaque
     /// Fingerprint to be used in DepNode.
     /// Not all DepNodeParams support being turned into a Fingerprint (they
     /// don't need to if the corresponding DepNode is anonymous).
-    fn to_fingerprint(&self, _: TyCtxt<'gcx, 'tcx>) -> Fingerprint {
+    fn to_fingerprint(&self, _: TyCtxt<'tcx>) -> Fingerprint {
         panic!("Not implemented. Accidentally called on anonymous node?")
     }
 
-    fn to_debug_str(&self, _: TyCtxt<'gcx, 'tcx>) -> String {
+    fn to_debug_str(&self, _: TyCtxt<'tcx>) -> String {
         format!("{:?}", self)
     }
 }
 
-impl<'gcx: 'tcx, 'tcx, T> DepNodeParams<'gcx, 'tcx> for T
+impl<'tcx, T> DepNodeParams<'tcx> for T
 where
     T: HashStable<StableHashingContext<'tcx>> + fmt::Debug,
 {
     default const CAN_RECONSTRUCT_QUERY_KEY: bool = false;
 
-    default fn to_fingerprint(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Fingerprint {
+    default fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
         let mut hcx = tcx.create_stable_hashing_context();
         let mut hasher = StableHasher::new();
 
@@ -494,39 +494,39 @@ where
         hasher.finish()
     }
 
-    default fn to_debug_str(&self, _: TyCtxt<'gcx, 'tcx>) -> String {
+    default fn to_debug_str(&self, _: TyCtxt<'tcx>) -> String {
         format!("{:?}", *self)
     }
 }
 
-impl<'gcx: 'tcx, 'tcx> DepNodeParams<'gcx, 'tcx> for DefId {
+impl<'tcx> DepNodeParams<'tcx> for DefId {
     const CAN_RECONSTRUCT_QUERY_KEY: bool = true;
 
-    fn to_fingerprint(&self, tcx: TyCtxt<'_, '_>) -> Fingerprint {
+    fn to_fingerprint(&self, tcx: TyCtxt<'_>) -> Fingerprint {
         tcx.def_path_hash(*self).0
     }
 
-    fn to_debug_str(&self, tcx: TyCtxt<'gcx, 'tcx>) -> String {
+    fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
         tcx.def_path_str(*self)
     }
 }
 
-impl<'gcx: 'tcx, 'tcx> DepNodeParams<'gcx, 'tcx> for DefIndex {
+impl<'tcx> DepNodeParams<'tcx> for DefIndex {
     const CAN_RECONSTRUCT_QUERY_KEY: bool = true;
 
-    fn to_fingerprint(&self, tcx: TyCtxt<'_, '_>) -> Fingerprint {
+    fn to_fingerprint(&self, tcx: TyCtxt<'_>) -> Fingerprint {
         tcx.hir().definitions().def_path_hash(*self).0
     }
 
-    fn to_debug_str(&self, tcx: TyCtxt<'gcx, 'tcx>) -> String {
+    fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
         tcx.def_path_str(DefId::local(*self))
     }
 }
 
-impl<'gcx: 'tcx, 'tcx> DepNodeParams<'gcx, 'tcx> for CrateNum {
+impl<'tcx> DepNodeParams<'tcx> for CrateNum {
     const CAN_RECONSTRUCT_QUERY_KEY: bool = true;
 
-    fn to_fingerprint(&self, tcx: TyCtxt<'_, '_>) -> Fingerprint {
+    fn to_fingerprint(&self, tcx: TyCtxt<'_>) -> Fingerprint {
         let def_id = DefId {
             krate: *self,
             index: CRATE_DEF_INDEX,
@@ -534,18 +534,18 @@ impl<'gcx: 'tcx, 'tcx> DepNodeParams<'gcx, 'tcx> for CrateNum {
         tcx.def_path_hash(def_id).0
     }
 
-    fn to_debug_str(&self, tcx: TyCtxt<'gcx, 'tcx>) -> String {
+    fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
         tcx.crate_name(*self).as_str().to_string()
     }
 }
 
-impl<'gcx: 'tcx, 'tcx> DepNodeParams<'gcx, 'tcx> for (DefId, DefId) {
+impl<'tcx> DepNodeParams<'tcx> for (DefId, DefId) {
     const CAN_RECONSTRUCT_QUERY_KEY: bool = false;
 
     // We actually would not need to specialize the implementation of this
     // method but it's faster to combine the hashes than to instantiate a full
     // hashing context and stable-hashing state.
-    fn to_fingerprint(&self, tcx: TyCtxt<'_, '_>) -> Fingerprint {
+    fn to_fingerprint(&self, tcx: TyCtxt<'_>) -> Fingerprint {
         let (def_id_0, def_id_1) = *self;
 
         let def_path_hash_0 = tcx.def_path_hash(def_id_0);
@@ -554,7 +554,7 @@ impl<'gcx: 'tcx, 'tcx> DepNodeParams<'gcx, 'tcx> for (DefId, DefId) {
         def_path_hash_0.0.combine(def_path_hash_1.0)
     }
 
-    fn to_debug_str(&self, tcx: TyCtxt<'gcx, 'tcx>) -> String {
+    fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
         let (def_id_0, def_id_1) = *self;
 
         format!("({}, {})",
@@ -563,13 +563,13 @@ impl<'gcx: 'tcx, 'tcx> DepNodeParams<'gcx, 'tcx> for (DefId, DefId) {
     }
 }
 
-impl<'gcx: 'tcx, 'tcx> DepNodeParams<'gcx, 'tcx> for HirId {
+impl<'tcx> DepNodeParams<'tcx> for HirId {
     const CAN_RECONSTRUCT_QUERY_KEY: bool = false;
 
     // We actually would not need to specialize the implementation of this
     // method but it's faster to combine the hashes than to instantiate a full
     // hashing context and stable-hashing state.
-    fn to_fingerprint(&self, tcx: TyCtxt<'_, '_>) -> Fingerprint {
+    fn to_fingerprint(&self, tcx: TyCtxt<'_>) -> Fingerprint {
         let HirId {
             owner,
             local_id,
diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs
index 40ccd6e7b28..c2e3c12cea8 100644
--- a/src/librustc/dep_graph/graph.rs
+++ b/src/librustc/dep_graph/graph.rs
@@ -557,7 +557,7 @@ impl DepGraph {
     /// a node index can be found for that node.
     pub fn try_mark_green_and_read(
         &self,
-        tcx: TyCtxt<'_, '_>,
+        tcx: TyCtxt<'_>,
         dep_node: &DepNode,
     ) -> Option<(SerializedDepNodeIndex, DepNodeIndex)> {
         self.try_mark_green(tcx, dep_node).map(|(prev_index, dep_node_index)| {
@@ -569,7 +569,7 @@ impl DepGraph {
 
     pub fn try_mark_green(
         &self,
-        tcx: TyCtxt<'_, '_>,
+        tcx: TyCtxt<'_>,
         dep_node: &DepNode,
     ) -> Option<(SerializedDepNodeIndex, DepNodeIndex)> {
         debug_assert!(!dep_node.kind.is_eval_always());
@@ -603,7 +603,7 @@ impl DepGraph {
     /// Try to mark a dep-node which existed in the previous compilation session as green.
     fn try_mark_previous_green<'tcx>(
         &self,
-        tcx: TyCtxt<'tcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         data: &DepGraphData,
         prev_dep_node_index: SerializedDepNodeIndex,
         dep_node: &DepNode,
@@ -790,7 +790,7 @@ impl DepGraph {
     #[inline(never)]
     fn emit_diagnostics<'tcx>(
         &self,
-        tcx: TyCtxt<'tcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         data: &DepGraphData,
         dep_node_index: DepNodeIndex,
         did_allocation: bool,
@@ -841,7 +841,7 @@ impl DepGraph {
     //
     // This method will only load queries that will end up in the disk cache.
     // Other queries will not be executed.
-    pub fn exec_cache_promotions<'tcx>(&self, tcx: TyCtxt<'tcx, 'tcx>) {
+    pub fn exec_cache_promotions<'tcx>(&self, tcx: TyCtxt<'tcx>) {
         let green_nodes: Vec<DepNode> = {
             let data = self.data.as_ref().unwrap();
             data.colors.values.indices().filter_map(|prev_index| {
diff --git a/src/librustc/dep_graph/safe.rs b/src/librustc/dep_graph/safe.rs
index 62667c957cd..e5eda14cdbe 100644
--- a/src/librustc/dep_graph/safe.rs
+++ b/src/librustc/dep_graph/safe.rs
@@ -33,7 +33,7 @@ impl DepGraphSafe for DefId {
 
 /// The type context itself can be used to access all kinds of tracked
 /// state, but those accesses should always generate read events.
-impl<'gcx, 'tcx> DepGraphSafe for TyCtxt<'gcx, 'tcx> {}
+impl<'tcx> DepGraphSafe for TyCtxt<'tcx> {}
 
 /// Tuples make it easy to build up state.
 impl<A, B> DepGraphSafe for (A, B)
diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs
index 4d13d91c8f2..4b84d56858c 100644
--- a/src/librustc/hir/check_attr.rs
+++ b/src/librustc/hir/check_attr.rs
@@ -88,7 +88,7 @@ impl Target {
 }
 
 struct CheckAttrVisitor<'tcx> {
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
 }
 
 impl CheckAttrVisitor<'tcx> {
@@ -347,7 +347,7 @@ fn is_c_like_enum(item: &hir::Item) -> bool {
     }
 }
 
-fn check_mod_attrs<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, module_def_id: DefId) {
+fn check_mod_attrs<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) {
     tcx.hir().visit_item_likes_in_module(
         module_def_id,
         &mut CheckAttrVisitor { tcx }.as_deep_visitor()
diff --git a/src/librustc/hir/def_id.rs b/src/librustc/hir/def_id.rs
index b3abe50a595..debed38361a 100644
--- a/src/librustc/hir/def_id.rs
+++ b/src/librustc/hir/def_id.rs
@@ -177,7 +177,7 @@ impl DefId {
         LocalDefId::from_def_id(self)
     }
 
-    pub fn describe_as_module(&self, tcx: TyCtxt<'_, '_>) -> String {
+    pub fn describe_as_module(&self, tcx: TyCtxt<'_>) -> String {
         if self.is_local() && self.index == CRATE_DEF_INDEX {
             format!("top-level module")
         } else {
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index b5e9f6bd3a6..5fa67fe4489 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -413,8 +413,8 @@ impl<'a> LoweringContext<'a> {
         /// needed from arbitrary locations in the crate,
         /// e.g., the number of lifetime generic parameters
         /// declared for every type and trait definition.
-        struct MiscCollector<'lcx, 'interner: 'lcx> {
-            lctx: &'lcx mut LoweringContext<'interner>,
+        struct MiscCollector<'tcx, 'interner: 'tcx> {
+            lctx: &'tcx mut LoweringContext<'interner>,
             hir_id_owner: Option<NodeId>,
         }
 
@@ -458,8 +458,8 @@ impl<'a> LoweringContext<'a> {
             }
         }
 
-        impl<'lcx, 'interner> Visitor<'lcx> for MiscCollector<'lcx, 'interner> {
-            fn visit_pat(&mut self, p: &'lcx Pat) {
+        impl<'tcx, 'interner> Visitor<'tcx> for MiscCollector<'tcx, 'interner> {
+            fn visit_pat(&mut self, p: &'tcx Pat) {
                 match p.node {
                     // Doesn't generate a HIR node
                     PatKind::Paren(..) => {},
@@ -473,7 +473,7 @@ impl<'a> LoweringContext<'a> {
                 visit::walk_pat(self, p)
             }
 
-            fn visit_item(&mut self, item: &'lcx Item) {
+            fn visit_item(&mut self, item: &'tcx Item) {
                 let hir_id = self.lctx.allocate_hir_id_counter(item.id);
 
                 match item.node {
@@ -505,7 +505,7 @@ impl<'a> LoweringContext<'a> {
                 });
             }
 
-            fn visit_trait_item(&mut self, item: &'lcx TraitItem) {
+            fn visit_trait_item(&mut self, item: &'tcx TraitItem) {
                 self.lctx.allocate_hir_id_counter(item.id);
 
                 match item.node {
@@ -521,21 +521,21 @@ impl<'a> LoweringContext<'a> {
                 }
             }
 
-            fn visit_impl_item(&mut self, item: &'lcx ImplItem) {
+            fn visit_impl_item(&mut self, item: &'tcx ImplItem) {
                 self.lctx.allocate_hir_id_counter(item.id);
                 self.with_hir_id_owner(Some(item.id), |this| {
                     visit::walk_impl_item(this, item);
                 });
             }
 
-            fn visit_foreign_item(&mut self, i: &'lcx ForeignItem) {
+            fn visit_foreign_item(&mut self, i: &'tcx ForeignItem) {
                 // Ignore patterns in foreign items
                 self.with_hir_id_owner(None, |this| {
                     visit::walk_foreign_item(this, i)
                 });
             }
 
-            fn visit_ty(&mut self, t: &'lcx Ty) {
+            fn visit_ty(&mut self, t: &'tcx Ty) {
                 match t.node {
                     // Mirrors the case in visit::walk_ty
                     TyKind::BareFn(ref f) => {
@@ -559,11 +559,11 @@ impl<'a> LoweringContext<'a> {
             }
         }
 
-        struct ItemLowerer<'lcx, 'interner: 'lcx> {
-            lctx: &'lcx mut LoweringContext<'interner>,
+        struct ItemLowerer<'tcx, 'interner: 'tcx> {
+            lctx: &'tcx mut LoweringContext<'interner>,
         }
 
-        impl<'lcx, 'interner> ItemLowerer<'lcx, 'interner> {
+        impl<'tcx, 'interner> ItemLowerer<'tcx, 'interner> {
             fn with_trait_impl_ref<F>(&mut self, trait_impl_ref: &Option<TraitRef>, f: F)
             where
                 F: FnOnce(&mut Self),
@@ -579,8 +579,8 @@ impl<'a> LoweringContext<'a> {
             }
         }
 
-        impl<'lcx, 'interner> Visitor<'lcx> for ItemLowerer<'lcx, 'interner> {
-            fn visit_mod(&mut self, m: &'lcx Mod, _s: Span, _attrs: &[Attribute], n: NodeId) {
+        impl<'tcx, 'interner> Visitor<'tcx> for ItemLowerer<'tcx, 'interner> {
+            fn visit_mod(&mut self, m: &'tcx Mod, _s: Span, _attrs: &[Attribute], n: NodeId) {
                 self.lctx.modules.insert(n, hir::ModuleItems {
                     items: BTreeSet::new(),
                     trait_items: BTreeSet::new(),
@@ -593,7 +593,7 @@ impl<'a> LoweringContext<'a> {
                 self.lctx.current_module = old;
             }
 
-            fn visit_item(&mut self, item: &'lcx Item) {
+            fn visit_item(&mut self, item: &'tcx Item) {
                 let mut item_hir_id = None;
                 self.lctx.with_hir_id_owner(item.id, |lctx| {
                     if let Some(hir_item) = lctx.lower_item(item) {
@@ -624,7 +624,7 @@ impl<'a> LoweringContext<'a> {
                 }
             }
 
-            fn visit_trait_item(&mut self, item: &'lcx TraitItem) {
+            fn visit_trait_item(&mut self, item: &'tcx TraitItem) {
                 self.lctx.with_hir_id_owner(item.id, |lctx| {
                     let hir_item = lctx.lower_trait_item(item);
                     let id = hir::TraitItemId { hir_id: hir_item.hir_id };
@@ -635,7 +635,7 @@ impl<'a> LoweringContext<'a> {
                 visit::walk_trait_item(self, item);
             }
 
-            fn visit_impl_item(&mut self, item: &'lcx ImplItem) {
+            fn visit_impl_item(&mut self, item: &'tcx ImplItem) {
                 self.lctx.with_hir_id_owner(item.id, |lctx| {
                     let hir_item = lctx.lower_impl_item(item);
                     let id = hir::ImplItemId { hir_id: hir_item.hir_id };
diff --git a/src/librustc/hir/upvars.rs b/src/librustc/hir/upvars.rs
index 332d15c3193..1a4fe35c530 100644
--- a/src/librustc/hir/upvars.rs
+++ b/src/librustc/hir/upvars.rs
@@ -55,7 +55,7 @@ impl Visitor<'tcx> for LocalCollector {
 }
 
 struct CaptureCollector<'a, 'tcx> {
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     locals: &'a FxHashSet<HirId>,
     upvars: FxIndexMap<HirId, hir::Upvar>,
 }
diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs
index 4b5b458b2af..4ef4d70ee1d 100644
--- a/src/librustc/ich/hcx.rs
+++ b/src/librustc/ich/hcx.rs
@@ -61,12 +61,12 @@ pub enum NodeIdHashingMode {
 /// We could also just store a plain reference to the hir::Crate but we want
 /// to avoid that the crate is used to get untracked access to all of the HIR.
 #[derive(Clone, Copy)]
-struct BodyResolver<'gcx>(&'gcx hir::Crate);
+struct BodyResolver<'tcx>(&'tcx hir::Crate);
 
-impl<'gcx> BodyResolver<'gcx> {
+impl<'tcx> BodyResolver<'tcx> {
     // Return a reference to the hir::Body with the given BodyId.
     // DOES NOT DO ANY TRACKING, use carefully.
-    fn body(self, id: hir::BodyId) -> &'gcx hir::Body {
+    fn body(self, id: hir::BodyId) -> &'tcx hir::Body {
         self.0.body(id)
     }
 }
@@ -205,8 +205,8 @@ for &'b mut T {
     }
 }
 
-impl StableHashingContextProvider<'lcx> for TyCtxt<'gcx, 'lcx> {
-    fn get_stable_hashing_context(&self) -> StableHashingContext<'lcx> {
+impl StableHashingContextProvider<'tcx> for TyCtxt<'tcx> {
+    fn get_stable_hashing_context(&self) -> StableHashingContext<'tcx> {
         (*self).create_stable_hashing_context()
     }
 }
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index e0c01277801..f72248701d1 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -508,9 +508,9 @@ fn stable_non_narrow_char(swc: ::syntax_pos::NonNarrowChar,
 
 
 
-impl<'gcx> HashStable<StableHashingContext<'gcx>> for feature_gate::Features {
+impl<'tcx> HashStable<StableHashingContext<'tcx>> for feature_gate::Features {
     fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'gcx>,
+                                          hcx: &mut StableHashingContext<'tcx>,
                                           hasher: &mut StableHasher<W>) {
         // Unfortunately we cannot exhaustively list fields here, since the
         // struct is macro generated.
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
index 89e79c56ca3..3a46a7e2afb 100644
--- a/src/librustc/ich/impls_ty.rs
+++ b/src/librustc/ich/impls_ty.rs
@@ -11,8 +11,8 @@ use crate::middle::region;
 use crate::ty;
 use crate::mir;
 
-impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>>
-for &'gcx ty::List<T>
+impl<'a, 'tcx, T> HashStable<StableHashingContext<'a>>
+for &'tcx ty::List<T>
     where T: HashStable<StableHashingContext<'a>> {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
@@ -40,7 +40,7 @@ for &'gcx ty::List<T>
     }
 }
 
-impl<'a, 'gcx, T> ToStableHashKey<StableHashingContext<'a>> for &'gcx ty::List<T>
+impl<'a, 'tcx, T> ToStableHashKey<StableHashingContext<'a>> for &'tcx ty::List<T>
     where T: HashStable<StableHashingContext<'a>>
 {
     type KeyType = Fingerprint;
@@ -54,7 +54,7 @@ impl<'a, 'gcx, T> ToStableHashKey<StableHashingContext<'a>> for &'gcx ty::List<T
     }
 }
 
-impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::subst::Kind<'gcx> {
+impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::subst::Kind<'tcx> {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
                                           hasher: &mut StableHasher<W>) {
@@ -117,19 +117,19 @@ impl<'a> HashStable<StableHashingContext<'a>> for ty::RegionVid {
     }
 }
 
-impl<'gcx, 'tcx> HashStable<StableHashingContext<'gcx>> for ty::ConstVid<'tcx> {
+impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::ConstVid<'tcx> {
     #[inline]
     fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'gcx>,
+                                          hcx: &mut StableHashingContext<'a>,
                                           hasher: &mut StableHasher<W>) {
         self.index.hash_stable(hcx, hasher);
     }
 }
 
-impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::BoundVar {
+impl<'tcx> HashStable<StableHashingContext<'tcx>> for ty::BoundVar {
     #[inline]
     fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'gcx>,
+                                          hcx: &mut StableHashingContext<'tcx>,
                                           hasher: &mut StableHasher<W>) {
         self.index().hash_stable(hcx, hasher);
     }
diff --git a/src/librustc/infer/at.rs b/src/librustc/infer/at.rs
index 57721108892..2d99e8a57e0 100644
--- a/src/librustc/infer/at.rs
+++ b/src/librustc/infer/at.rs
@@ -30,24 +30,24 @@ use super::*;
 use crate::ty::Const;
 use crate::ty::relate::{Relate, TypeRelation};
 
-pub struct At<'a, 'gcx: 'tcx, 'tcx: 'a> {
-    pub infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
+pub struct At<'a, 'tcx: 'a> {
+    pub infcx: &'a InferCtxt<'a, 'tcx>,
     pub cause: &'a ObligationCause<'tcx>,
     pub param_env: ty::ParamEnv<'tcx>,
 }
 
-pub struct Trace<'a, 'gcx: 'tcx, 'tcx: 'a> {
-    at: At<'a, 'gcx, 'tcx>,
+pub struct Trace<'a, 'tcx: 'a> {
+    at: At<'a, 'tcx>,
     a_is_expected: bool,
     trace: TypeTrace<'tcx>,
 }
 
-impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     #[inline]
     pub fn at(&'a self,
               cause: &'a ObligationCause<'tcx>,
               param_env: ty::ParamEnv<'tcx>)
-              -> At<'a, 'gcx, 'tcx>
+              -> At<'a, 'tcx>
     {
         At { infcx: self, cause, param_env }
     }
@@ -61,7 +61,7 @@ pub trait ToTrace<'tcx>: Relate<'tcx> + Copy {
                 -> TypeTrace<'tcx>;
 }
 
-impl<'a, 'gcx, 'tcx> At<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> At<'a, 'tcx> {
     /// Hacky routine for equating two impl headers in coherence.
     pub fn eq_impl_headers(self,
                            expected: &ty::ImplHeader<'tcx>,
@@ -189,7 +189,7 @@ impl<'a, 'gcx, 'tcx> At<'a, 'gcx, 'tcx> {
     pub fn trace<T>(self,
                     expected: T,
                     actual: T)
-                    -> Trace<'a, 'gcx, 'tcx>
+                    -> Trace<'a, 'tcx>
         where T: ToTrace<'tcx>
     {
         self.trace_exp(true, expected, actual)
@@ -202,7 +202,7 @@ impl<'a, 'gcx, 'tcx> At<'a, 'gcx, 'tcx> {
                         a_is_expected: bool,
                         a: T,
                         b: T)
-                        -> Trace<'a, 'gcx, 'tcx>
+                        -> Trace<'a, 'tcx>
         where T: ToTrace<'tcx>
     {
         let trace = ToTrace::to_trace(self.cause, a_is_expected, a, b);
@@ -210,7 +210,7 @@ impl<'a, 'gcx, 'tcx> At<'a, 'gcx, 'tcx> {
     }
 }
 
-impl<'a, 'gcx, 'tcx> Trace<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> Trace<'a, 'tcx> {
     /// Makes `a <: b` where `a` may or may not be expected (if
     /// `a_is_expected` is true, then `a` is expected).
     /// Makes `expected <: actual`.
diff --git a/src/librustc/infer/canonical/canonicalizer.rs b/src/librustc/infer/canonical/canonicalizer.rs
index dadac4b1e6b..b4779eec65f 100644
--- a/src/librustc/infer/canonical/canonicalizer.rs
+++ b/src/librustc/infer/canonical/canonicalizer.rs
@@ -21,7 +21,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::indexed_vec::Idx;
 use smallvec::SmallVec;
 
-impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
+impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
     /// Canonicalizes a query value `V`. When we canonicalize a query,
     /// we not only canonicalize unbound inference variables, but we
     /// *also* replace all free regions whatsoever. So for example a
@@ -41,9 +41,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
         &self,
         value: &V,
         query_state: &mut OriginalQueryValues<'tcx>,
-    ) -> Canonicalized<'gcx, V>
+    ) -> Canonicalized<'tcx, V>
     where
-        V: TypeFoldable<'tcx> + Lift<'gcx>,
+        V: TypeFoldable<'tcx> + Lift<'tcx>,
     {
         self.tcx
             .sess
@@ -85,9 +85,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
     /// out the [chapter in the rustc guide][c].
     ///
     /// [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html#canonicalizing-the-query-result
-    pub fn canonicalize_response<V>(&self, value: &V) -> Canonicalized<'gcx, V>
+    pub fn canonicalize_response<V>(&self, value: &V) -> Canonicalized<'tcx, V>
     where
-        V: TypeFoldable<'tcx> + Lift<'gcx>,
+        V: TypeFoldable<'tcx> + Lift<'tcx>,
     {
         let mut query_state = OriginalQueryValues::default();
         Canonicalizer::canonicalize(
@@ -99,9 +99,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
         )
     }
 
-    pub fn canonicalize_user_type_annotation<V>(&self, value: &V) -> Canonicalized<'gcx, V>
+    pub fn canonicalize_user_type_annotation<V>(&self, value: &V) -> Canonicalized<'tcx, V>
     where
-        V: TypeFoldable<'tcx> + Lift<'gcx>,
+        V: TypeFoldable<'tcx> + Lift<'tcx>,
     {
         let mut query_state = OriginalQueryValues::default();
         Canonicalizer::canonicalize(
@@ -130,9 +130,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
         &self,
         value: &V,
         query_state: &mut OriginalQueryValues<'tcx>,
-    ) -> Canonicalized<'gcx, V>
+    ) -> Canonicalized<'tcx, V>
     where
-        V: TypeFoldable<'tcx> + Lift<'gcx>,
+        V: TypeFoldable<'tcx> + Lift<'tcx>,
     {
         self.tcx
             .sess
@@ -160,7 +160,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
 trait CanonicalizeRegionMode {
     fn canonicalize_free_region(
         &self,
-        canonicalizer: &mut Canonicalizer<'_, '_, 'tcx>,
+        canonicalizer: &mut Canonicalizer<'_, 'tcx>,
         r: ty::Region<'tcx>,
     ) -> ty::Region<'tcx>;
 
@@ -172,7 +172,7 @@ struct CanonicalizeQueryResponse;
 impl CanonicalizeRegionMode for CanonicalizeQueryResponse {
     fn canonicalize_free_region(
         &self,
-        canonicalizer: &mut Canonicalizer<'_, '_, 'tcx>,
+        canonicalizer: &mut Canonicalizer<'_, 'tcx>,
         r: ty::Region<'tcx>,
     ) -> ty::Region<'tcx> {
         match r {
@@ -221,7 +221,7 @@ struct CanonicalizeUserTypeAnnotation;
 impl CanonicalizeRegionMode for CanonicalizeUserTypeAnnotation {
     fn canonicalize_free_region(
         &self,
-        canonicalizer: &mut Canonicalizer<'_, '_, 'tcx>,
+        canonicalizer: &mut Canonicalizer<'_, 'tcx>,
         r: ty::Region<'tcx>,
     ) -> ty::Region<'tcx> {
         match r {
@@ -244,7 +244,7 @@ struct CanonicalizeAllFreeRegions;
 impl CanonicalizeRegionMode for CanonicalizeAllFreeRegions {
     fn canonicalize_free_region(
         &self,
-        canonicalizer: &mut Canonicalizer<'_, '_, 'tcx>,
+        canonicalizer: &mut Canonicalizer<'_, 'tcx>,
         r: ty::Region<'tcx>,
     ) -> ty::Region<'tcx> {
         canonicalizer.canonical_var_for_region_in_root_universe(r)
@@ -260,7 +260,7 @@ struct CanonicalizeFreeRegionsOtherThanStatic;
 impl CanonicalizeRegionMode for CanonicalizeFreeRegionsOtherThanStatic {
     fn canonicalize_free_region(
         &self,
-        canonicalizer: &mut Canonicalizer<'_, '_, 'tcx>,
+        canonicalizer: &mut Canonicalizer<'_, 'tcx>,
         r: ty::Region<'tcx>,
     ) -> ty::Region<'tcx> {
         if let ty::ReStatic = r {
@@ -275,9 +275,9 @@ impl CanonicalizeRegionMode for CanonicalizeFreeRegionsOtherThanStatic {
     }
 }
 
-struct Canonicalizer<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
-    infcx: Option<&'cx InferCtxt<'cx, 'gcx, 'tcx>>,
-    tcx: TyCtxt<'gcx, 'tcx>,
+struct Canonicalizer<'cx, 'tcx: 'cx> {
+    infcx: Option<&'cx InferCtxt<'cx, 'tcx>>,
+    tcx: TyCtxt<'tcx>,
     variables: SmallVec<[CanonicalVarInfo; 8]>,
     query_state: &'cx mut OriginalQueryValues<'tcx>,
     // Note that indices is only used once `var_values` is big enough to be
@@ -289,8 +289,8 @@ struct Canonicalizer<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
     binder_index: ty::DebruijnIndex,
 }
 
-impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx> {
-    fn tcx<'b>(&'b self) -> TyCtxt<'gcx, 'tcx> {
+impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
+    fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
         self.tcx
     }
 
@@ -495,18 +495,18 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
     }
 }
 
-impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
+impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
     /// The main `canonicalize` method, shared impl of
     /// `canonicalize_query` and `canonicalize_response`.
     fn canonicalize<V>(
         value: &V,
-        infcx: Option<&InferCtxt<'_, 'gcx, 'tcx>>,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        infcx: Option<&InferCtxt<'_, 'tcx>>,
+        tcx: TyCtxt<'tcx>,
         canonicalize_region_mode: &dyn CanonicalizeRegionMode,
         query_state: &mut OriginalQueryValues<'tcx>,
-    ) -> Canonicalized<'gcx, V>
+    ) -> Canonicalized<'tcx, V>
     where
-        V: TypeFoldable<'tcx> + Lift<'gcx>,
+        V: TypeFoldable<'tcx> + Lift<'tcx>,
     {
         let needs_canonical_flags = if canonicalize_region_mode.any() {
             TypeFlags::KEEP_IN_LOCAL_TCX |
diff --git a/src/librustc/infer/canonical/mod.rs b/src/librustc/infer/canonical/mod.rs
index 85e784d0ca5..8b1c34a487f 100644
--- a/src/librustc/infer/canonical/mod.rs
+++ b/src/librustc/infer/canonical/mod.rs
@@ -44,15 +44,15 @@ mod substitute;
 /// variables have been rewritten to "canonical vars". These are
 /// numbered starting from 0 in order of first appearance.
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcDecodable, RustcEncodable, HashStable)]
-pub struct Canonical<'gcx, V> {
+pub struct Canonical<'tcx, V> {
     pub max_universe: ty::UniverseIndex,
-    pub variables: CanonicalVarInfos<'gcx>,
+    pub variables: CanonicalVarInfos<'tcx>,
     pub value: V,
 }
 
-pub type CanonicalVarInfos<'gcx> = &'gcx List<CanonicalVarInfo>;
+pub type CanonicalVarInfos<'tcx> = &'tcx List<CanonicalVarInfo>;
 
-impl<'gcx> UseSpecializedDecodable for CanonicalVarInfos<'gcx> {}
+impl<'tcx> UseSpecializedDecodable for CanonicalVarInfos<'tcx> {}
 
 /// A set of values corresponding to the canonical variables from some
 /// `Canonical`. You can give these values to
@@ -194,10 +194,10 @@ pub struct QueryResponse<'tcx, R> {
     pub value: R,
 }
 
-pub type Canonicalized<'gcx, V> = Canonical<'gcx, <V as Lift<'gcx>>::Lifted>;
+pub type Canonicalized<'tcx, V> = Canonical<'tcx, <V as Lift<'tcx>>::Lifted>;
 
-pub type CanonicalizedQueryResponse<'gcx, T> =
-    &'gcx Canonical<'gcx, QueryResponse<'gcx, <T as Lift<'gcx>>::Lifted>>;
+pub type CanonicalizedQueryResponse<'tcx, T> =
+    &'tcx Canonical<'tcx, QueryResponse<'tcx, <T as Lift<'tcx>>::Lifted>>;
 
 /// Indicates whether or not we were able to prove the query to be
 /// true.
@@ -254,7 +254,7 @@ impl<'tcx, R> Canonical<'tcx, QueryResponse<'tcx, R>> {
     }
 }
 
-impl<'gcx, V> Canonical<'gcx, V> {
+impl<'tcx, V> Canonical<'tcx, V> {
     /// Allows you to map the `value` of a canonical while keeping the
     /// same set of bound variables.
     ///
@@ -278,7 +278,7 @@ impl<'gcx, V> Canonical<'gcx, V> {
     /// let ty: Ty<'tcx> = ...;
     /// let b: Canonical<'tcx, (T, Ty<'tcx>)> = a.unchecked_map(|v| (v, ty));
     /// ```
-    pub fn unchecked_map<W>(self, map_op: impl FnOnce(V) -> W) -> Canonical<'gcx, W> {
+    pub fn unchecked_map<W>(self, map_op: impl FnOnce(V) -> W) -> Canonical<'tcx, W> {
         let Canonical {
             max_universe,
             variables,
@@ -294,7 +294,7 @@ impl<'gcx, V> Canonical<'gcx, V> {
 
 pub type QueryRegionConstraint<'tcx> = ty::Binder<ty::OutlivesPredicate<Kind<'tcx>, Region<'tcx>>>;
 
-impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
+impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
     /// Creates a substitution S for the canonical value with fresh
     /// inference variables and applies it to the canonical value.
     /// Returns both the instantiated result *and* the substitution S.
@@ -478,7 +478,7 @@ impl<'tcx> CanonicalVarValues<'tcx> {
     /// `self.var_values == [Type(u32), Lifetime('a), Type(u64)]`
     /// we'll return a substitution `subst` with:
     /// `subst.var_values == [Type(^0), Lifetime(^1), Type(^2)]`.
-    pub fn make_identity(&self, tcx: TyCtxt<'tcx, 'tcx>) -> Self {
+    pub fn make_identity(&self, tcx: TyCtxt<'tcx>) -> Self {
         use crate::ty::subst::UnpackedKind;
 
         CanonicalVarValues {
diff --git a/src/librustc/infer/canonical/query_response.rs b/src/librustc/infer/canonical/query_response.rs
index 345889ca441..59b46b41c8d 100644
--- a/src/librustc/infer/canonical/query_response.rs
+++ b/src/librustc/infer/canonical/query_response.rs
@@ -29,7 +29,7 @@ use crate::ty::subst::{Kind, UnpackedKind};
 use crate::ty::{self, BoundVar, InferConst, Lift, Ty, TyCtxt};
 use crate::util::captures::Captures;
 
-impl<'gcx, 'tcx> InferCtxtBuilder<'gcx, 'tcx> {
+impl<'tcx> InferCtxtBuilder<'tcx> {
     /// The "main method" for a canonicalized trait query. Given the
     /// canonical key `canonical_key`, this method will create a new
     /// inference context, instantiate the key, and run your operation
@@ -42,20 +42,20 @@ impl<'gcx, 'tcx> InferCtxtBuilder<'gcx, 'tcx> {
     ///
     /// (It might be mildly nicer to implement this on `TyCtxt`, and
     /// not `InferCtxtBuilder`, but that is a bit tricky right now.
-    /// In part because we would need a `for<'gcx: 'tcx>` sort of
+    /// In part because we would need a `for<'tcx>` sort of
     /// bound for the closure and in part because it is convenient to
     /// have `'tcx` be free on this function so that we can talk about
     /// `K: TypeFoldable<'tcx>`.)
     pub fn enter_canonical_trait_query<K, R>(
-        &'tcx mut self,
+        &mut self,
         canonical_key: &Canonical<'tcx, K>,
-        operation: impl FnOnce(&InferCtxt<'_, 'gcx, 'tcx>, &mut dyn TraitEngine<'tcx>, K)
+        operation: impl FnOnce(&InferCtxt<'_, 'tcx>, &mut dyn TraitEngine<'tcx>, K)
             -> Fallible<R>,
-    ) -> Fallible<CanonicalizedQueryResponse<'gcx, R>>
+    ) -> Fallible<CanonicalizedQueryResponse<'tcx, R>>
     where
         K: TypeFoldable<'tcx>,
-        R: Debug + Lift<'gcx> + TypeFoldable<'tcx>,
-        Canonical<'gcx, <QueryResponse<'gcx, R> as Lift<'gcx>>::Lifted>: ArenaAllocatable,
+        R: Debug + Lift<'tcx> + TypeFoldable<'tcx>,
+        Canonical<'tcx, <QueryResponse<'tcx, R> as Lift<'tcx>>::Lifted>: ArenaAllocatable,
     {
         self.enter_with_canonical(
             DUMMY_SP,
@@ -73,7 +73,7 @@ impl<'gcx, 'tcx> InferCtxtBuilder<'gcx, 'tcx> {
     }
 }
 
-impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
+impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
     /// This method is meant to be invoked as the final step of a canonical query
     /// implementation. It is given:
     ///
@@ -98,10 +98,10 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
         inference_vars: CanonicalVarValues<'tcx>,
         answer: T,
         fulfill_cx: &mut dyn TraitEngine<'tcx>,
-    ) -> Fallible<CanonicalizedQueryResponse<'gcx, T>>
+    ) -> Fallible<CanonicalizedQueryResponse<'tcx, T>>
     where
-        T: Debug + Lift<'gcx> + TypeFoldable<'tcx>,
-        Canonical<'gcx, <QueryResponse<'gcx, T> as Lift<'gcx>>::Lifted>: ArenaAllocatable,
+        T: Debug + Lift<'tcx> + TypeFoldable<'tcx>,
+        Canonical<'tcx, <QueryResponse<'tcx, T> as Lift<'tcx>>::Lifted>: ArenaAllocatable,
     {
         let query_response = self.make_query_response(inference_vars, answer, fulfill_cx)?;
         let canonical_result = self.canonicalize_response(&query_response);
@@ -127,9 +127,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
         &self,
         inference_vars: CanonicalVarValues<'tcx>,
         answer: T
-    ) -> Canonical<'gcx, QueryResponse<'gcx, <T as Lift<'gcx>>::Lifted>>
+    ) -> Canonical<'tcx, QueryResponse<'tcx, <T as Lift<'tcx>>::Lifted>>
     where
-        T: Debug + Lift<'gcx> + TypeFoldable<'tcx>,
+        T: Debug + Lift<'tcx> + TypeFoldable<'tcx>,
     {
         self.canonicalize_response(&QueryResponse {
             var_values: inference_vars,
@@ -148,7 +148,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
         fulfill_cx: &mut dyn TraitEngine<'tcx>,
     ) -> Result<QueryResponse<'tcx, T>, NoSolution>
     where
-        T: Debug + TypeFoldable<'tcx> + Lift<'gcx>,
+        T: Debug + TypeFoldable<'tcx> + Lift<'tcx>,
     {
         let tcx = self.tcx;
 
@@ -567,7 +567,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
         param_env: ty::ParamEnv<'tcx>,
         unsubstituted_region_constraints: &'a [QueryRegionConstraint<'tcx>],
         result_subst: &'a CanonicalVarValues<'tcx>,
-    ) -> impl Iterator<Item = PredicateObligation<'tcx>> + 'a + Captures<'gcx> {
+    ) -> impl Iterator<Item = PredicateObligation<'tcx>> + 'a + Captures<'tcx> {
         unsubstituted_region_constraints
             .iter()
             .map(move |constraint| {
@@ -647,7 +647,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
 /// Given the region obligations and constraints scraped from the infcx,
 /// creates query region constraints.
 pub fn make_query_outlives<'tcx>(
-    tcx: TyCtxt<'_, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     outlives_obligations: impl Iterator<Item = (Ty<'tcx>, ty::Region<'tcx>)>,
     region_constraints: &RegionConstraintData<'tcx>,
 ) -> Vec<QueryRegionConstraint<'tcx>> {
diff --git a/src/librustc/infer/canonical/substitute.rs b/src/librustc/infer/canonical/substitute.rs
index d1310771fb3..1234b96ab11 100644
--- a/src/librustc/infer/canonical/substitute.rs
+++ b/src/librustc/infer/canonical/substitute.rs
@@ -14,7 +14,7 @@ use crate::ty::{self, TyCtxt};
 impl<'tcx, V> Canonical<'tcx, V> {
     /// Instantiate the wrapped value, replacing each canonical value
     /// with the value given in `var_values`.
-    pub fn substitute(&self, tcx: TyCtxt<'_, 'tcx>, var_values: &CanonicalVarValues<'tcx>) -> V
+    pub fn substitute(&self, tcx: TyCtxt<'tcx>, var_values: &CanonicalVarValues<'tcx>) -> V
     where
         V: TypeFoldable<'tcx>,
     {
@@ -29,7 +29,7 @@ impl<'tcx, V> Canonical<'tcx, V> {
     /// V, replacing each of the canonical variables.
     pub fn substitute_projected<T>(
         &self,
-        tcx: TyCtxt<'_, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         var_values: &CanonicalVarValues<'tcx>,
         projection_fn: impl FnOnce(&V) -> &T,
     ) -> T
@@ -46,7 +46,7 @@ impl<'tcx, V> Canonical<'tcx, V> {
 /// must be values for the set of canonical variables that appear in
 /// `value`.
 pub(super) fn substitute_value<'a, 'tcx, T>(
-    tcx: TyCtxt<'_, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     var_values: &CanonicalVarValues<'tcx>,
     value: &'a T,
 ) -> T
diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs
index d886efd3391..23550569f7c 100644
--- a/src/librustc/infer/combine.rs
+++ b/src/librustc/infer/combine.rs
@@ -44,8 +44,8 @@ use syntax::ast;
 use syntax_pos::{Span, DUMMY_SP};
 
 #[derive(Clone)]
-pub struct CombineFields<'infcx, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
-    pub infcx: &'infcx InferCtxt<'infcx, 'gcx, 'tcx>,
+pub struct CombineFields<'infcx, 'tcx: 'infcx> {
+    pub infcx: &'infcx InferCtxt<'infcx, 'tcx>,
     pub trace: TypeTrace<'tcx>,
     pub cause: Option<ty::relate::Cause>,
     pub param_env: ty::ParamEnv<'tcx>,
@@ -57,7 +57,7 @@ pub enum RelationDir {
     SubtypeOf, SupertypeOf, EqTo
 }
 
-impl<'infcx, 'gcx, 'tcx> InferCtxt<'infcx, 'gcx, 'tcx> {
+impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> {
     pub fn super_combine_tys<R>(
         &self,
         relation: &mut R,
@@ -65,7 +65,7 @@ impl<'infcx, 'gcx, 'tcx> InferCtxt<'infcx, 'gcx, 'tcx> {
         b: Ty<'tcx>,
     ) -> RelateResult<'tcx, Ty<'tcx>>
     where
-        R: TypeRelation<'gcx, 'tcx>,
+        R: TypeRelation<'tcx>,
     {
         let a_is_expected = relation.a_is_expected();
 
@@ -125,7 +125,7 @@ impl<'infcx, 'gcx, 'tcx> InferCtxt<'infcx, 'gcx, 'tcx> {
         b: &'tcx ty::Const<'tcx>,
     ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>>
     where
-        R: TypeRelation<'gcx, 'tcx>,
+        R: TypeRelation<'tcx>,
     {
         let a_is_expected = relation.a_is_expected();
 
@@ -208,24 +208,24 @@ impl<'infcx, 'gcx, 'tcx> InferCtxt<'infcx, 'gcx, 'tcx> {
     }
 }
 
-impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
-    pub fn tcx(&self) -> TyCtxt<'gcx, 'tcx> {
+impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
+    pub fn tcx(&self) -> TyCtxt<'tcx> {
         self.infcx.tcx
     }
 
-    pub fn equate<'a>(&'a mut self, a_is_expected: bool) -> Equate<'a, 'infcx, 'gcx, 'tcx> {
+    pub fn equate<'a>(&'a mut self, a_is_expected: bool) -> Equate<'a, 'infcx, 'tcx> {
         Equate::new(self, a_is_expected)
     }
 
-    pub fn sub<'a>(&'a mut self, a_is_expected: bool) -> Sub<'a, 'infcx, 'gcx, 'tcx> {
+    pub fn sub<'a>(&'a mut self, a_is_expected: bool) -> Sub<'a, 'infcx, 'tcx> {
         Sub::new(self, a_is_expected)
     }
 
-    pub fn lub<'a>(&'a mut self, a_is_expected: bool) -> Lub<'a, 'infcx, 'gcx, 'tcx> {
+    pub fn lub<'a>(&'a mut self, a_is_expected: bool) -> Lub<'a, 'infcx, 'tcx> {
         Lub::new(self, a_is_expected)
     }
 
-    pub fn glb<'a>(&'a mut self, a_is_expected: bool) -> Glb<'a, 'infcx, 'gcx, 'tcx> {
+    pub fn glb<'a>(&'a mut self, a_is_expected: bool) -> Glb<'a, 'infcx, 'tcx> {
         Glb::new(self, a_is_expected)
     }
 
@@ -355,8 +355,8 @@ impl<'infcx, 'gcx, 'tcx> CombineFields<'infcx, 'gcx, 'tcx> {
     }
 }
 
-struct Generalizer<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
-    infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
+struct Generalizer<'cx, 'tcx: 'cx> {
+    infcx: &'cx InferCtxt<'cx, 'tcx>,
 
     /// The span, used when creating new type variables and things.
     span: Span,
@@ -415,8 +415,8 @@ struct Generalization<'tcx> {
     needs_wf: bool,
 }
 
-impl TypeRelation<'gcx, 'tcx> for Generalizer<'_, 'gcx, 'tcx> {
-    fn tcx(&self) -> TyCtxt<'gcx, 'tcx> {
+impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
+    fn tcx(&self) -> TyCtxt<'tcx> {
         self.infcx.tcx
     }
 
diff --git a/src/librustc/infer/equate.rs b/src/librustc/infer/equate.rs
index a9e0e3376a5..f9fdc66cf3d 100644
--- a/src/librustc/infer/equate.rs
+++ b/src/librustc/infer/equate.rs
@@ -11,23 +11,23 @@ use crate::mir::interpret::ConstValue;
 use crate::infer::unify_key::replace_if_possible;
 
 /// Ensures `a` is made equal to `b`. Returns `a` on success.
-pub struct Equate<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
-    fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>,
+pub struct Equate<'combine, 'infcx: 'combine, 'tcx: 'infcx> {
+    fields: &'combine mut CombineFields<'infcx, 'tcx>,
     a_is_expected: bool,
 }
 
-impl<'combine, 'infcx, 'gcx, 'tcx> Equate<'combine, 'infcx, 'gcx, 'tcx> {
-    pub fn new(fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>, a_is_expected: bool)
-        -> Equate<'combine, 'infcx, 'gcx, 'tcx>
+impl<'combine, 'infcx, 'tcx> Equate<'combine, 'infcx, 'tcx> {
+    pub fn new(fields: &'combine mut CombineFields<'infcx, 'tcx>, a_is_expected: bool)
+        -> Equate<'combine, 'infcx, 'tcx>
     {
         Equate { fields: fields, a_is_expected: a_is_expected }
     }
 }
 
-impl TypeRelation<'gcx, 'tcx> for Equate<'combine, 'infcx, 'gcx, 'tcx> {
+impl TypeRelation<'tcx> for Equate<'combine, 'infcx, 'tcx> {
     fn tag(&self) -> &'static str { "Equate" }
 
-    fn tcx(&self) -> TyCtxt<'gcx, 'tcx> { self.fields.tcx() }
+    fn tcx(&self) -> TyCtxt<'tcx> { self.fields.tcx() }
 
     fn a_is_expected(&self) -> bool { self.a_is_expected }
 
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index d50cb8e61a6..04d29a8db1c 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -67,7 +67,7 @@ mod need_type_info;
 
 pub mod nice_region_error;
 
-impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
+impl<'tcx> TyCtxt<'tcx> {
     pub fn note_and_explain_region(
         self,
         region_scope_tree: &region::ScopeTree,
@@ -282,7 +282,7 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
     }
 }
 
-impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     pub fn report_region_errors(
         &self,
         region_scope_tree: &region::ScopeTree,
@@ -445,13 +445,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         use ty::print::Printer;
         use ty::subst::Kind;
 
-        struct AbsolutePathPrinter<'gcx, 'tcx> {
-            tcx: TyCtxt<'gcx, 'tcx>,
+        struct AbsolutePathPrinter<'tcx> {
+            tcx: TyCtxt<'tcx>,
         }
 
         struct NonTrivialPath;
 
-        impl<'gcx, 'tcx> Printer<'gcx, 'tcx> for AbsolutePathPrinter<'gcx, 'tcx> {
+        impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
             type Error = NonTrivialPath;
 
             type Path = Vec<String>;
@@ -460,7 +460,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             type DynExistential = !;
             type Const = !;
 
-            fn tcx<'a>(&'a self) -> TyCtxt<'gcx, 'tcx> {
+            fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
                 self.tcx
             }
 
@@ -1546,7 +1546,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     }
 }
 
-impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     fn report_inference_failure(
         &self,
         var_origin: RegionVariableOrigin,
diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs
index 16b6792fde4..830d6adc1b8 100644
--- a/src/librustc/infer/error_reporting/need_type_info.rs
+++ b/src/librustc/infer/error_reporting/need_type_info.rs
@@ -9,16 +9,16 @@ use syntax::source_map::CompilerDesugaringKind;
 use syntax_pos::Span;
 use errors::DiagnosticBuilder;
 
-struct FindLocalByTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
-    infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
+struct FindLocalByTypeVisitor<'a, 'tcx> {
+    infcx: &'a InferCtxt<'a, 'tcx>,
     target_ty: Ty<'tcx>,
-    hir_map: &'a hir::map::Map<'gcx>,
-    found_local_pattern: Option<&'gcx Pat>,
-    found_arg_pattern: Option<&'gcx Pat>,
+    hir_map: &'a hir::map::Map<'tcx>,
+    found_local_pattern: Option<&'tcx Pat>,
+    found_arg_pattern: Option<&'tcx Pat>,
     found_ty: Option<Ty<'tcx>>,
 }
 
-impl<'a, 'gcx, 'tcx> FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> FindLocalByTypeVisitor<'a, 'tcx> {
     fn node_matches_type(&mut self, hir_id: HirId) -> Option<Ty<'tcx>> {
         let ty_opt = self.infcx.in_progress_tables.and_then(|tables| {
             tables.borrow().node_type_opt(hir_id)
@@ -47,12 +47,12 @@ impl<'a, 'gcx, 'tcx> FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
     }
 }
 
-impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
-    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
+impl<'a, 'tcx> Visitor<'tcx> for FindLocalByTypeVisitor<'a, 'tcx> {
+    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
         NestedVisitorMap::OnlyBodies(&self.hir_map)
     }
 
-    fn visit_local(&mut self, local: &'gcx Local) {
+    fn visit_local(&mut self, local: &'tcx Local) {
         if let (None, Some(ty)) = (self.found_local_pattern, self.node_matches_type(local.hir_id)) {
             self.found_local_pattern = Some(&*local.pat);
             self.found_ty = Some(ty);
@@ -60,7 +60,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
         intravisit::walk_local(self, local);
     }
 
-    fn visit_body(&mut self, body: &'gcx Body) {
+    fn visit_body(&mut self, body: &'tcx Body) {
         for argument in &body.arguments {
             if let (None, Some(ty)) = (
                 self.found_arg_pattern,
@@ -75,7 +75,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
 }
 
 
-impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     pub fn extract_type_name(
         &self,
         ty: Ty<'tcx>,
@@ -103,7 +103,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         body_id: Option<hir::BodyId>,
         span: Span,
         ty: Ty<'tcx>
-    ) -> DiagnosticBuilder<'gcx> {
+    ) -> DiagnosticBuilder<'tcx> {
         let ty = self.resolve_vars_if_possible(&ty);
         let name = self.extract_type_name(&ty, None);
 
@@ -230,7 +230,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         &self,
         span: Span,
         ty: Ty<'tcx>
-    ) -> DiagnosticBuilder<'gcx> {
+    ) -> DiagnosticBuilder<'tcx> {
         let ty = self.resolve_vars_if_possible(&ty);
         let name = self.extract_type_name(&ty, None);
 
diff --git a/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs b/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs
index ecdcb4bbf11..6bd2c04d512 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs
@@ -5,7 +5,7 @@ use crate::infer::error_reporting::nice_region_error::NiceRegionError;
 use crate::infer::error_reporting::nice_region_error::util::AnonymousArgInfo;
 use crate::util::common::ErrorReported;
 
-impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
     /// Print the error message for lifetime errors when both the concerned regions are anonymous.
     ///
     /// Consider a case where we have
diff --git a/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs b/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs
index 8dd415ec9af..fa95ea10132 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/find_anon_type.rs
@@ -5,7 +5,7 @@ use crate::middle::resolve_lifetime as rl;
 use crate::hir::intravisit::{self, NestedVisitorMap, Visitor};
 use crate::infer::error_reporting::nice_region_error::NiceRegionError;
 
-impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
     /// This function calls the `visit_ty` method for the parameters
     /// corresponding to the anonymous regions. The `nested_visitor.found_type`
     /// contains the anonymous type.
@@ -60,9 +60,9 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
     // to the anonymous region.
     fn find_component_for_bound_region(
         &self,
-        arg: &'gcx hir::Ty,
+        arg: &'tcx hir::Ty,
         br: &ty::BoundRegion,
-    ) -> Option<(&'gcx hir::Ty)> {
+    ) -> Option<(&'tcx hir::Ty)> {
         let mut nested_visitor = FindNestedTypeVisitor {
             tcx: self.tcx(),
             bound_region: *br,
@@ -81,23 +81,23 @@ impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
 // walk the types like &mut Vec<&u8> and &u8 looking for the HIR
 // where that lifetime appears. This allows us to highlight the
 // specific part of the type in the error message.
-struct FindNestedTypeVisitor<'gcx, 'tcx> {
-    tcx: TyCtxt<'gcx, 'tcx>,
+struct FindNestedTypeVisitor<'tcx> {
+    tcx: TyCtxt<'tcx>,
     // The bound_region corresponding to the Refree(freeregion)
     // associated with the anonymous region we are looking for.
     bound_region: ty::BoundRegion,
     // The type where the anonymous lifetime appears
     // for e.g., Vec<`&u8`> and <`&u8`>
-    found_type: Option<&'gcx hir::Ty>,
+    found_type: Option<&'tcx hir::Ty>,
     current_index: ty::DebruijnIndex,
 }
 
-impl Visitor<'gcx> for FindNestedTypeVisitor<'gcx, 'tcx> {
-    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
+impl Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
+    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
         NestedVisitorMap::OnlyBodies(&self.tcx.hir())
     }
 
-    fn visit_ty(&mut self, arg: &'gcx hir::Ty) {
+    fn visit_ty(&mut self, arg: &'tcx hir::Ty) {
         match arg.node {
             hir::TyKind::BareFn(_) => {
                 self.current_index.shift_in(1);
@@ -208,15 +208,15 @@ impl Visitor<'gcx> for FindNestedTypeVisitor<'gcx, 'tcx> {
 // and would walk the types like Vec<Ref> in the above example and Ref looking for the HIR
 // where that lifetime appears. This allows us to highlight the
 // specific part of the type in the error message.
-struct TyPathVisitor<'gcx, 'tcx> {
-    tcx: TyCtxt<'gcx, 'tcx>,
+struct TyPathVisitor<'tcx> {
+    tcx: TyCtxt<'tcx>,
     found_it: bool,
     bound_region: ty::BoundRegion,
     current_index: ty::DebruijnIndex,
 }
 
-impl Visitor<'gcx> for TyPathVisitor<'gcx, 'tcx> {
-    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
+impl Visitor<'tcx> for TyPathVisitor<'tcx> {
+    fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
         NestedVisitorMap::OnlyBodies(&self.tcx.hir())
     }
 
@@ -267,7 +267,7 @@ impl Visitor<'gcx> for TyPathVisitor<'gcx, 'tcx> {
         }
     }
 
-    fn visit_ty(&mut self, arg: &'gcx hir::Ty) {
+    fn visit_ty(&mut self, arg: &'tcx hir::Ty) {
         // ignore nested types
         //
         // If you have a type like `Foo<'a, &Ty>` we
diff --git a/src/librustc/infer/error_reporting/nice_region_error/mod.rs b/src/librustc/infer/error_reporting/nice_region_error/mod.rs
index dc9ec15cb24..541d9a96dbe 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/mod.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/mod.rs
@@ -14,7 +14,7 @@ mod outlives_closure;
 mod static_impl_trait;
 mod util;
 
-impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
+impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
     pub fn try_report_nice_region_error(&self, error: &RegionResolutionError<'tcx>) -> bool {
         match *error {
             ConcreteFailure(..) | SubSupConflict(..) => {}
@@ -30,16 +30,16 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
     }
 }
 
-pub struct NiceRegionError<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
-    infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
+pub struct NiceRegionError<'cx, 'tcx: 'cx> {
+    infcx: &'cx InferCtxt<'cx, 'tcx>,
     error: Option<RegionResolutionError<'tcx>>,
     regions: Option<(Span, ty::Region<'tcx>, ty::Region<'tcx>)>,
     tables: Option<&'cx ty::TypeckTables<'tcx>>,
 }
 
-impl<'cx, 'gcx, 'tcx> NiceRegionError<'cx, 'gcx, 'tcx> {
+impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> {
     pub fn new(
-        infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
+        infcx: &'cx InferCtxt<'cx, 'tcx>,
         error: RegionResolutionError<'tcx>,
         tables: Option<&'cx ty::TypeckTables<'tcx>>,
     ) -> Self {
@@ -47,7 +47,7 @@ impl<'cx, 'gcx, 'tcx> NiceRegionError<'cx, 'gcx, 'tcx> {
     }
 
     pub fn new_from_span(
-        infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
+        infcx: &'cx InferCtxt<'cx, 'tcx>,
         span: Span,
         sub: ty::Region<'tcx>,
         sup: ty::Region<'tcx>,
@@ -56,7 +56,7 @@ impl<'cx, 'gcx, 'tcx> NiceRegionError<'cx, 'gcx, 'tcx> {
         Self { infcx, error: None, regions: Some((span, sub, sup)), tables }
     }
 
-    fn tcx(&self) -> TyCtxt<'gcx, 'tcx> {
+    fn tcx(&self) -> TyCtxt<'tcx> {
         self.infcx.tcx
     }
 
diff --git a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs
index 0efc124e31f..51bee49b70f 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/named_anon_conflict.rs
@@ -5,7 +5,7 @@ use crate::hir::{FunctionRetTy, TyKind};
 use crate::ty;
 use errors::{Applicability, DiagnosticBuilder};
 
-impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
     /// When given a `ConcreteFailure` for a function with arguments containing a named region and
     /// an anonymous region, emit an descriptive diagnostic error.
     pub(super) fn try_report_named_anon_conflict(&self) -> Option<DiagnosticBuilder<'a>> {
diff --git a/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs b/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs
index af201886a00..0d98a024977 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/outlives_closure.rs
@@ -9,7 +9,7 @@ use crate::hir::Node;
 use crate::util::common::ErrorReported;
 use crate::infer::lexical_region_resolve::RegionResolutionError::SubSupConflict;
 
-impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
     /// Print the error message for lifetime errors when binding escapes a closure.
     ///
     /// Consider a case where we have
diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs
index 8631236c0e3..b4fb0189206 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs
@@ -13,7 +13,7 @@ use crate::ty::print::{Print, RegionHighlightMode, FmtPrinter};
 
 use std::fmt::{self, Write};
 
-impl NiceRegionError<'me, 'gcx, 'tcx> {
+impl NiceRegionError<'me, 'tcx> {
     /// When given a `ConcreteFailure` for a function with arguments containing a named region and
     /// an anonymous region, emit a descriptive diagnostic error.
     pub(super) fn try_report_placeholder_conflict(&self) -> Option<DiagnosticBuilder<'me>> {
@@ -321,14 +321,14 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
     ) {
         // HACK(eddyb) maybe move this in a more central location.
         #[derive(Copy, Clone)]
-        struct Highlighted<'gcx, 'tcx, T> {
-            tcx: TyCtxt<'gcx, 'tcx>,
+        struct Highlighted<'tcx, T> {
+            tcx: TyCtxt<'tcx>,
             highlight: RegionHighlightMode,
             value: T,
         }
 
-        impl<'gcx, 'tcx, T> Highlighted<'gcx, 'tcx, T> {
-            fn map<U>(self, f: impl FnOnce(T) -> U) -> Highlighted<'gcx, 'tcx, U> {
+        impl<'tcx, T> Highlighted<'tcx, T> {
+            fn map<U>(self, f: impl FnOnce(T) -> U) -> Highlighted<'tcx, U> {
                 Highlighted {
                     tcx: self.tcx,
                     highlight: self.highlight,
@@ -337,12 +337,11 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
             }
         }
 
-        impl<'gcx, 'tcx, T> fmt::Display for Highlighted<'gcx, 'tcx, T>
+        impl<'tcx, T> fmt::Display for Highlighted<'tcx, T>
         where
             T: for<'a, 'b, 'c> Print<
-                'gcx,
                 'tcx,
-                FmtPrinter<'a, 'gcx, 'tcx, &'b mut fmt::Formatter<'c>>,
+                FmtPrinter<'a, 'tcx, &'b mut fmt::Formatter<'c>>,
                 Error = fmt::Error,
             >,
         {
diff --git a/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs b/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs
index 23acaeb31f8..9d405d4ea40 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/static_impl_trait.rs
@@ -6,7 +6,7 @@ use crate::ty::{BoundRegion, FreeRegion, RegionKind};
 use crate::util::common::ErrorReported;
 use errors::Applicability;
 
-impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
     /// Print the error message for lifetime errors when the return type is a static impl Trait.
     pub(super) fn try_report_static_impl_trait(&self) -> Option<ErrorReported> {
         if let Some(ref error) = self.error {
diff --git a/src/librustc/infer/error_reporting/nice_region_error/util.rs b/src/librustc/infer/error_reporting/nice_region_error/util.rs
index feade7a8f56..017f36b0209 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/util.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/util.rs
@@ -24,7 +24,7 @@ pub(super) struct AnonymousArgInfo<'tcx> {
     pub is_first: bool,
 }
 
-impl<'a, 'gcx, 'tcx> NiceRegionError<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
     // This method walks the Type of the function body arguments using
     // `fold_regions()` function and returns the
     // &hir::Arg of the function argument corresponding to the anonymous
diff --git a/src/librustc/infer/error_reporting/note.rs b/src/librustc/infer/error_reporting/note.rs
index 9eb46aa3779..cc7c13cea7d 100644
--- a/src/librustc/infer/error_reporting/note.rs
+++ b/src/librustc/infer/error_reporting/note.rs
@@ -4,7 +4,7 @@ use crate::ty::{self, Region};
 use crate::ty::error::TypeError;
 use errors::DiagnosticBuilder;
 
-impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     pub(super) fn note_region_origin(&self,
                                      err: &mut DiagnosticBuilder<'_>,
                                      origin: &SubregionOrigin<'tcx>) {
diff --git a/src/librustc/infer/freshen.rs b/src/librustc/infer/freshen.rs
index 641e5b127e8..20331232dc7 100644
--- a/src/librustc/infer/freshen.rs
+++ b/src/librustc/infer/freshen.rs
@@ -41,17 +41,17 @@ use std::collections::hash_map::Entry;
 use super::InferCtxt;
 use super::unify_key::ToType;
 
-pub struct TypeFreshener<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
-    infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
+pub struct TypeFreshener<'a, 'tcx: 'a> {
+    infcx: &'a InferCtxt<'a, 'tcx>,
     ty_freshen_count: u32,
     const_freshen_count: u32,
     ty_freshen_map: FxHashMap<ty::InferTy, Ty<'tcx>>,
     const_freshen_map: FxHashMap<ty::InferConst<'tcx>, &'tcx ty::Const<'tcx>>,
 }
 
-impl<'a, 'gcx, 'tcx> TypeFreshener<'a, 'gcx, 'tcx> {
-    pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>)
-               -> TypeFreshener<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
+    pub fn new(infcx: &'a InferCtxt<'a, 'tcx>)
+               -> TypeFreshener<'a, 'tcx> {
         TypeFreshener {
             infcx,
             ty_freshen_count: 0,
@@ -113,8 +113,8 @@ impl<'a, 'gcx, 'tcx> TypeFreshener<'a, 'gcx, 'tcx> {
     }
 }
 
-impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
-    fn tcx<'b>(&'b self) -> TyCtxt<'gcx, 'tcx> {
+impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
+    fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
         self.infcx.tcx
     }
 
diff --git a/src/librustc/infer/fudge.rs b/src/librustc/infer/fudge.rs
index ef6ea20c6df..59364862c64 100644
--- a/src/librustc/infer/fudge.rs
+++ b/src/librustc/infer/fudge.rs
@@ -22,7 +22,7 @@ fn const_vars_since_snapshot<'tcx>(
     }).collect())
 }
 
-impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     /// This rather funky routine is used while processing expected
     /// types. What happens here is that we want to propagate a
     /// coercion through the return type of a fn to its
@@ -133,8 +133,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     }
 }
 
-pub struct InferenceFudger<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
-    infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
+pub struct InferenceFudger<'a, 'tcx: 'a> {
+    infcx: &'a InferCtxt<'a, 'tcx>,
     type_vars: (Range<TyVid>, Vec<TypeVariableOrigin>),
     int_vars: Range<IntVid>,
     float_vars: Range<FloatVid>,
@@ -142,8 +142,8 @@ pub struct InferenceFudger<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     const_vars: (Range<ConstVid<'tcx>>, Vec<ConstVariableOrigin>),
 }
 
-impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for InferenceFudger<'a, 'gcx, 'tcx> {
-    fn tcx<'b>(&'b self) -> TyCtxt<'gcx, 'tcx> {
+impl<'a, 'tcx> TypeFolder<'tcx> for InferenceFudger<'a, 'tcx> {
+    fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
         self.infcx.tcx
     }
 
diff --git a/src/librustc/infer/glb.rs b/src/librustc/infer/glb.rs
index 0b3c0904d17..8e4796dc83d 100644
--- a/src/librustc/infer/glb.rs
+++ b/src/librustc/infer/glb.rs
@@ -8,23 +8,23 @@ use crate::ty::{self, Ty, TyCtxt};
 use crate::ty::relate::{Relate, RelateResult, TypeRelation};
 
 /// "Greatest lower bound" (common subtype)
-pub struct Glb<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
-    fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>,
+pub struct Glb<'combine, 'infcx: 'combine, 'tcx: 'infcx> {
+    fields: &'combine mut CombineFields<'infcx, 'tcx>,
     a_is_expected: bool,
 }
 
-impl<'combine, 'infcx, 'gcx, 'tcx> Glb<'combine, 'infcx, 'gcx, 'tcx> {
-    pub fn new(fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>, a_is_expected: bool)
-        -> Glb<'combine, 'infcx, 'gcx, 'tcx>
+impl<'combine, 'infcx, 'tcx> Glb<'combine, 'infcx, 'tcx> {
+    pub fn new(fields: &'combine mut CombineFields<'infcx, 'tcx>, a_is_expected: bool)
+        -> Glb<'combine, 'infcx, 'tcx>
     {
         Glb { fields: fields, a_is_expected: a_is_expected }
     }
 }
 
-impl TypeRelation<'gcx, 'tcx> for Glb<'combine, 'infcx, 'gcx, 'tcx> {
+impl TypeRelation<'tcx> for Glb<'combine, 'infcx, 'tcx> {
     fn tag(&self) -> &'static str { "Glb" }
 
-    fn tcx(&self) -> TyCtxt<'gcx, 'tcx> { self.fields.tcx() }
+    fn tcx(&self) -> TyCtxt<'tcx> { self.fields.tcx() }
 
     fn a_is_expected(&self) -> bool { self.a_is_expected }
 
@@ -85,10 +85,10 @@ impl TypeRelation<'gcx, 'tcx> for Glb<'combine, 'infcx, 'gcx, 'tcx> {
     }
 }
 
-impl<'combine, 'infcx, 'gcx, 'tcx> LatticeDir<'infcx, 'gcx, 'tcx>
-    for Glb<'combine, 'infcx, 'gcx, 'tcx>
+impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx>
+    for Glb<'combine, 'infcx, 'tcx>
 {
-    fn infcx(&self) -> &'infcx InferCtxt<'infcx, 'gcx, 'tcx> {
+    fn infcx(&self) -> &'infcx InferCtxt<'infcx, 'tcx> {
         self.fields.infcx
     }
 
diff --git a/src/librustc/infer/higher_ranked/mod.rs b/src/librustc/infer/higher_ranked/mod.rs
index fcec820cbb9..542ac4931ec 100644
--- a/src/librustc/infer/higher_ranked/mod.rs
+++ b/src/librustc/infer/higher_ranked/mod.rs
@@ -9,7 +9,7 @@ use crate::ty::relate::{Relate, RelateResult, TypeRelation};
 use crate::ty::{self, Binder, TypeFoldable};
 use crate::mir::interpret::ConstValue;
 
-impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> CombineFields<'a, 'tcx> {
     pub fn higher_ranked_sub<T>(
         &mut self,
         a: &Binder<T>,
@@ -60,7 +60,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
     }
 }
 
-impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     /// Replaces all regions (resp. types) bound by `binder` with placeholder
     /// regions (resp. types) and return a map indicating which bound-region
     /// placeholder region. This is the first step of checking subtyping
diff --git a/src/librustc/infer/lattice.rs b/src/librustc/infer/lattice.rs
index 236ebc19340..18a30e259eb 100644
--- a/src/librustc/infer/lattice.rs
+++ b/src/librustc/infer/lattice.rs
@@ -27,8 +27,8 @@ use crate::ty::TyVar;
 use crate::ty::{self, Ty};
 use crate::ty::relate::{RelateResult, TypeRelation};
 
-pub trait LatticeDir<'f, 'gcx: 'f + 'tcx, 'tcx: 'f>: TypeRelation<'gcx, 'tcx> {
-    fn infcx(&self) -> &'f InferCtxt<'f, 'gcx, 'tcx>;
+pub trait LatticeDir<'f, 'tcx: 'f>: TypeRelation<'tcx> {
+    fn infcx(&self) -> &'f InferCtxt<'f, 'tcx>;
 
     fn cause(&self) -> &ObligationCause<'tcx>;
 
@@ -41,11 +41,11 @@ pub trait LatticeDir<'f, 'gcx: 'f + 'tcx, 'tcx: 'f>: TypeRelation<'gcx, 'tcx> {
     fn relate_bound(&mut self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()>;
 }
 
-pub fn super_lattice_tys<'a, 'gcx, 'tcx, L>(this: &mut L,
+pub fn super_lattice_tys<'a, 'tcx, L>(this: &mut L,
                                             a: Ty<'tcx>,
                                             b: Ty<'tcx>)
                                             -> RelateResult<'tcx, Ty<'tcx>>
-    where L: LatticeDir<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
+    where L: LatticeDir<'a, 'tcx>, 'tcx: 'a
 {
     debug!("{}.lattice_tys({:?}, {:?})",
            this.tag(),
diff --git a/src/librustc/infer/lexical_region_resolve/graphviz.rs b/src/librustc/infer/lexical_region_resolve/graphviz.rs
index 1878afd581d..758a01bc52b 100644
--- a/src/librustc/infer/lexical_region_resolve/graphviz.rs
+++ b/src/librustc/infer/lexical_region_resolve/graphviz.rs
@@ -44,9 +44,9 @@ graphs will be printed.                                                     \n\
 ");
 }
 
-pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>(
+pub fn maybe_print_constraints_for<'a, 'tcx>(
     region_data: &RegionConstraintData<'tcx>,
-    region_rels: &RegionRelations<'a, 'gcx, 'tcx>)
+    region_rels: &RegionRelations<'a, 'tcx>)
 {
     let tcx = region_rels.tcx;
     let context = region_rels.context;
@@ -107,9 +107,9 @@ pub fn maybe_print_constraints_for<'a, 'gcx, 'tcx>(
     }
 }
 
-struct ConstraintGraph<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
+struct ConstraintGraph<'a, 'tcx: 'a> {
     graph_name: String,
-    region_rels: &'a RegionRelations<'a, 'gcx, 'tcx>,
+    region_rels: &'a RegionRelations<'a, 'tcx>,
     map: &'a BTreeMap<Constraint<'tcx>, SubregionOrigin<'tcx>>,
     node_ids: FxHashMap<Node, usize>,
 }
@@ -126,11 +126,11 @@ enum Edge<'tcx> {
     EnclScope(region::Scope, region::Scope),
 }
 
-impl<'a, 'gcx, 'tcx> ConstraintGraph<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> ConstraintGraph<'a, 'tcx> {
     fn new(name: String,
-           region_rels: &'a RegionRelations<'a, 'gcx, 'tcx>,
+           region_rels: &'a RegionRelations<'a, 'tcx>,
            map: &'a ConstraintMap<'tcx>)
-           -> ConstraintGraph<'a, 'gcx, 'tcx> {
+           -> ConstraintGraph<'a, 'tcx> {
         let mut i = 0;
         let mut node_ids = FxHashMap::default();
         {
@@ -161,7 +161,7 @@ impl<'a, 'gcx, 'tcx> ConstraintGraph<'a, 'gcx, 'tcx> {
     }
 }
 
-impl<'a, 'gcx, 'tcx> dot::Labeller<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> dot::Labeller<'a> for ConstraintGraph<'a, 'tcx> {
     type Node = Node;
     type Edge = Edge<'tcx>;
     fn graph_id(&self) -> dot::Id<'_> {
@@ -215,7 +215,7 @@ fn edge_to_nodes(e: &Edge<'_>) -> (Node, Node) {
     }
 }
 
-impl<'a, 'gcx, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'tcx> {
     type Node = Node;
     type Edge = Edge<'tcx>;
     fn nodes(&self) -> dot::Nodes<'_, Node> {
@@ -246,7 +246,7 @@ impl<'a, 'gcx, 'tcx> dot::GraphWalk<'a> for ConstraintGraph<'a, 'gcx, 'tcx> {
 
 pub type ConstraintMap<'tcx> = BTreeMap<Constraint<'tcx>, SubregionOrigin<'tcx>>;
 
-fn dump_region_data_to<'a, 'gcx, 'tcx>(region_rels: &RegionRelations<'a, 'gcx, 'tcx>,
+fn dump_region_data_to<'a, 'tcx>(region_rels: &RegionRelations<'a, 'tcx>,
                                        map: &ConstraintMap<'tcx>,
                                        path: &str)
                                        -> io::Result<()> {
diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs
index 1612a2a54d1..944969e2214 100644
--- a/src/librustc/infer/lexical_region_resolve/mod.rs
+++ b/src/librustc/infer/lexical_region_resolve/mod.rs
@@ -30,7 +30,7 @@ mod graphviz;
 /// assuming such values can be found. It returns the final values of
 /// all the variables as well as a set of errors that must be reported.
 pub fn resolve<'tcx>(
-    region_rels: &RegionRelations<'_, '_, 'tcx>,
+    region_rels: &RegionRelations<'_, 'tcx>,
     var_infos: VarInfos,
     data: RegionConstraintData<'tcx>,
 ) -> (
@@ -96,14 +96,14 @@ struct RegionAndOrigin<'tcx> {
 
 type RegionGraph<'tcx> = Graph<(), Constraint<'tcx>>;
 
-struct LexicalResolver<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
-    region_rels: &'cx RegionRelations<'cx, 'gcx, 'tcx>,
+struct LexicalResolver<'cx, 'tcx: 'cx> {
+    region_rels: &'cx RegionRelations<'cx, 'tcx>,
     var_infos: VarInfos,
     data: RegionConstraintData<'tcx>,
 }
 
-impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> {
-    fn tcx(&self) -> TyCtxt<'gcx, 'tcx> {
+impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
+    fn tcx(&self) -> TyCtxt<'tcx> {
         self.region_rels.tcx
     }
 
@@ -136,14 +136,14 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> {
 
     /// Initially, the value for all variables is set to `'empty`, the
     /// empty region. The `expansion` phase will grow this larger.
-    fn construct_var_data(&self, tcx: TyCtxt<'_, 'tcx>) -> LexicalRegionResolutions<'tcx> {
+    fn construct_var_data(&self, tcx: TyCtxt<'tcx>) -> LexicalRegionResolutions<'tcx> {
         LexicalRegionResolutions {
             error_region: tcx.lifetimes.re_static,
             values: IndexVec::from_elem_n(VarValue::Value(tcx.lifetimes.re_empty), self.num_vars())
         }
     }
 
-    fn dump_constraints(&self, free_regions: &RegionRelations<'_, '_, 'tcx>) {
+    fn dump_constraints(&self, free_regions: &RegionRelations<'_, 'tcx>) {
         debug!(
             "----() Start constraint listing (context={:?}) ()----",
             free_regions.context
@@ -785,7 +785,7 @@ impl<'tcx> fmt::Debug for RegionAndOrigin<'tcx> {
 }
 
 impl<'tcx> LexicalRegionResolutions<'tcx> {
-    fn normalize<T>(&self, tcx: TyCtxt<'_, 'tcx>, value: T) -> T
+    fn normalize<T>(&self, tcx: TyCtxt<'tcx>, value: T) -> T
     where
         T: TypeFoldable<'tcx>,
     {
diff --git a/src/librustc/infer/lub.rs b/src/librustc/infer/lub.rs
index ab49968ce24..6e1ca9e7ed0 100644
--- a/src/librustc/infer/lub.rs
+++ b/src/librustc/infer/lub.rs
@@ -8,23 +8,23 @@ use crate::ty::{self, Ty, TyCtxt};
 use crate::ty::relate::{Relate, RelateResult, TypeRelation};
 
 /// "Least upper bound" (common supertype)
-pub struct Lub<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
-    fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>,
+pub struct Lub<'combine, 'infcx: 'combine, 'tcx: 'infcx> {
+    fields: &'combine mut CombineFields<'infcx, 'tcx>,
     a_is_expected: bool,
 }
 
-impl<'combine, 'infcx, 'gcx, 'tcx> Lub<'combine, 'infcx, 'gcx, 'tcx> {
-    pub fn new(fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>, a_is_expected: bool)
-        -> Lub<'combine, 'infcx, 'gcx, 'tcx>
+impl<'combine, 'infcx, 'tcx> Lub<'combine, 'infcx, 'tcx> {
+    pub fn new(fields: &'combine mut CombineFields<'infcx, 'tcx>, a_is_expected: bool)
+        -> Lub<'combine, 'infcx, 'tcx>
     {
         Lub { fields: fields, a_is_expected: a_is_expected }
     }
 }
 
-impl TypeRelation<'gcx, 'tcx> for Lub<'combine, 'infcx, 'gcx, 'tcx> {
+impl TypeRelation<'tcx> for Lub<'combine, 'infcx, 'tcx> {
     fn tag(&self) -> &'static str { "Lub" }
 
-    fn tcx(&self) -> TyCtxt<'gcx, 'tcx> { self.fields.tcx() }
+    fn tcx(&self) -> TyCtxt<'tcx> { self.fields.tcx() }
 
     fn a_is_expected(&self) -> bool { self.a_is_expected }
 
@@ -85,10 +85,10 @@ impl TypeRelation<'gcx, 'tcx> for Lub<'combine, 'infcx, 'gcx, 'tcx> {
     }
 }
 
-impl<'combine, 'infcx, 'gcx, 'tcx> LatticeDir<'infcx, 'gcx, 'tcx>
-    for Lub<'combine, 'infcx, 'gcx, 'tcx>
+impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx>
+    for Lub<'combine, 'infcx, 'tcx>
 {
-    fn infcx(&self) -> &'infcx InferCtxt<'infcx, 'gcx, 'tcx> {
+    fn infcx(&self) -> &'infcx InferCtxt<'infcx, 'tcx> {
         self.fields.infcx
     }
 
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index 538b76be7b0..47a276b2bcc 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -91,7 +91,7 @@ impl SuppressRegionErrors {
     /// Indicates that the MIR borrowck will repeat these region
     /// checks, so we should ignore errors if NLL is (unconditionally)
     /// enabled.
-    pub fn when_nll_is_enabled(tcx: TyCtxt<'_, '_>) -> Self {
+    pub fn when_nll_is_enabled(tcx: TyCtxt<'_>) -> Self {
         match tcx.borrowck_mode() {
             // If we're on Migrate mode, report AST region errors
             BorrowckMode::Migrate => SuppressRegionErrors { suppressed: false },
@@ -102,8 +102,8 @@ impl SuppressRegionErrors {
     }
 }
 
-pub struct InferCtxt<'a, 'gcx, 'tcx> {
-    pub tcx: TyCtxt<'gcx, 'tcx>,
+pub struct InferCtxt<'a, 'tcx> {
+    pub tcx: TyCtxt<'tcx>,
 
     /// During type-checking/inference of a body, `in_progress_tables`
     /// contains a reference to the tables being built up, which are
@@ -464,14 +464,14 @@ impl<'tcx> fmt::Display for FixupError<'tcx> {
 
 /// Helper type of a temporary returned by `tcx.infer_ctxt()`.
 /// Necessary because we can't write the following bound:
-/// `F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(InferCtxt<'b, 'gcx, 'tcx>)`.
-pub struct InferCtxtBuilder<'gcx: 'tcx, 'tcx> {
-    global_tcx: TyCtxt<'gcx, 'gcx>,
+/// `F: for<'b, 'tcx> where 'tcx FnOnce(InferCtxt<'b, 'tcx>)`.
+pub struct InferCtxtBuilder<'tcx> {
+    global_tcx: TyCtxt<'tcx>,
     fresh_tables: Option<RefCell<ty::TypeckTables<'tcx>>>,
 }
 
-impl TyCtxt<'gcx, 'gcx> {
-    pub fn infer_ctxt<'tcx>(self) -> InferCtxtBuilder<'gcx, 'tcx> {
+impl TyCtxt<'tcx> {
+    pub fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> {
         InferCtxtBuilder {
             global_tcx: self,
             fresh_tables: None,
@@ -479,7 +479,7 @@ impl TyCtxt<'gcx, 'gcx> {
     }
 }
 
-impl<'gcx, 'tcx> InferCtxtBuilder<'gcx, 'tcx> {
+impl<'tcx> InferCtxtBuilder<'tcx> {
     /// Used only by `rustc_typeck` during body type-checking/inference,
     /// will initialize `in_progress_tables` with fresh `TypeckTables`.
     pub fn with_fresh_in_progress_tables(mut self, table_owner: DefId) -> Self {
@@ -495,10 +495,10 @@ impl<'gcx, 'tcx> InferCtxtBuilder<'gcx, 'tcx> {
     /// the bound values in `C` to their instantiated values in `V`
     /// (in other words, `S(C) = V`).
     pub fn enter_with_canonical<T, R>(
-        &'tcx mut self,
+        &mut self,
         span: Span,
         canonical: &Canonical<'tcx, T>,
-        f: impl for<'a> FnOnce(InferCtxt<'a, 'gcx, 'tcx>, T, CanonicalVarValues<'tcx>) -> R,
+        f: impl for<'a> FnOnce(InferCtxt<'a, 'tcx>, T, CanonicalVarValues<'tcx>) -> R,
     ) -> R
     where
         T: TypeFoldable<'tcx>,
@@ -510,7 +510,7 @@ impl<'gcx, 'tcx> InferCtxtBuilder<'gcx, 'tcx> {
         })
     }
 
-    pub fn enter<R>(&mut self, f: impl for<'a> FnOnce(InferCtxt<'a, 'gcx, 'tcx>) -> R) -> R {
+    pub fn enter<R>(&mut self, f: impl for<'a> FnOnce(InferCtxt<'a, 'tcx>) -> R) -> R {
         let InferCtxtBuilder {
             global_tcx,
             ref fresh_tables,
@@ -567,7 +567,7 @@ impl<'tcx, T> InferOk<'tcx, T> {
     /// Extracts `value`, registering any obligations into `fulfill_cx`.
     pub fn into_value_registering_obligations(
         self,
-        infcx: &InferCtxt<'_, '_, 'tcx>,
+        infcx: &InferCtxt<'_, 'tcx>,
         fulfill_cx: &mut dyn TraitEngine<'tcx>,
     ) -> T {
         let InferOk { value, obligations } = self;
@@ -598,7 +598,7 @@ pub struct CombinedSnapshot<'a, 'tcx: 'a> {
     _in_progress_tables: Option<Ref<'a, ty::TypeckTables<'tcx>>>,
 }
 
-impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     pub fn is_in_snapshot(&self) -> bool {
         self.in_snapshot.get()
     }
@@ -614,7 +614,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         }
     }
 
-    pub fn freshener<'b>(&'b self) -> TypeFreshener<'b, 'gcx, 'tcx> {
+    pub fn freshener<'b>(&'b self) -> TypeFreshener<'b, 'tcx> {
         freshen::TypeFreshener::new(self)
     }
 
@@ -677,7 +677,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         &'a self,
         trace: TypeTrace<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
-    ) -> CombineFields<'a, 'gcx, 'tcx> {
+    ) -> CombineFields<'a, 'tcx> {
         CombineFields {
             infcx: self,
             trace,
@@ -1548,13 +1548,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     }
 }
 
-pub struct ShallowResolver<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
-    infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
+pub struct ShallowResolver<'a, 'tcx> {
+    infcx: &'a InferCtxt<'a, 'tcx>,
 }
 
-impl<'a, 'gcx, 'tcx> ShallowResolver<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> ShallowResolver<'a, 'tcx> {
     #[inline(always)]
-    pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>) -> Self {
+    pub fn new(infcx: &'a InferCtxt<'a, 'tcx>) -> Self {
         ShallowResolver { infcx }
     }
 
@@ -1599,8 +1599,8 @@ impl<'a, 'gcx, 'tcx> ShallowResolver<'a, 'gcx, 'tcx> {
     }
 }
 
-impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ShallowResolver<'a, 'gcx, 'tcx> {
-    fn tcx<'b>(&'b self) -> TyCtxt<'gcx, 'tcx> {
+impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> {
+    fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
         self.infcx.tcx
     }
 
@@ -1624,7 +1624,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ShallowResolver<'a, 'gcx, 'tcx>
     }
 }
 
-impl<'gcx, 'tcx> TypeTrace<'tcx> {
+impl<'tcx> TypeTrace<'tcx> {
     pub fn span(&self) -> Span {
         self.cause.span
     }
@@ -1641,7 +1641,7 @@ impl<'gcx, 'tcx> TypeTrace<'tcx> {
         }
     }
 
-    pub fn dummy(tcx: TyCtxt<'gcx, 'tcx>) -> TypeTrace<'tcx> {
+    pub fn dummy(tcx: TyCtxt<'tcx>) -> TypeTrace<'tcx> {
         TypeTrace {
             cause: ObligationCause::dummy(),
             values: Types(ExpectedFound {
diff --git a/src/librustc/infer/nll_relate/mod.rs b/src/librustc/infer/nll_relate/mod.rs
index f6ba13d2aa8..2c821d0ae15 100644
--- a/src/librustc/infer/nll_relate/mod.rs
+++ b/src/librustc/infer/nll_relate/mod.rs
@@ -38,11 +38,11 @@ pub enum NormalizationStrategy {
     Eager,
 }
 
-pub struct TypeRelating<'me, 'gcx: 'tcx, 'tcx: 'me, D>
+pub struct TypeRelating<'me, 'tcx: 'me, D>
 where
     D: TypeRelatingDelegate<'tcx>,
 {
-    infcx: &'me InferCtxt<'me, 'gcx, 'tcx>,
+    infcx: &'me InferCtxt<'me, 'tcx>,
 
     /// Callback to use when we deduce an outlives relationship
     delegate: D,
@@ -135,12 +135,12 @@ struct BoundRegionScope<'tcx> {
 #[derive(Copy, Clone)]
 struct UniversallyQuantified(bool);
 
-impl<'me, 'gcx, 'tcx, D> TypeRelating<'me, 'gcx, 'tcx, D>
+impl<'me, 'tcx, D> TypeRelating<'me, 'tcx, D>
 where
     D: TypeRelatingDelegate<'tcx>,
 {
     pub fn new(
-        infcx: &'me InferCtxt<'me, 'gcx, 'tcx>,
+        infcx: &'me InferCtxt<'me, 'tcx>,
         delegate: D,
         ambient_variance: ty::Variance,
     ) -> Self {
@@ -416,7 +416,7 @@ trait VidValuePair<'tcx>: Debug {
     /// for more details on why we want them.
     fn vid_scopes<D: TypeRelatingDelegate<'tcx>>(
         &self,
-        relate: &'r mut TypeRelating<'_, '_, 'tcx, D>,
+        relate: &'r mut TypeRelating<'_, 'tcx, D>,
     ) -> &'r mut Vec<BoundRegionScope<'tcx>>;
 
     /// Given a generalized type G that should replace the vid, relate
@@ -424,7 +424,7 @@ trait VidValuePair<'tcx>: Debug {
     /// appeared.
     fn relate_generalized_ty<D>(
         &self,
-        relate: &mut TypeRelating<'_, '_, 'tcx, D>,
+        relate: &mut TypeRelating<'_, 'tcx, D>,
         generalized_ty: Ty<'tcx>,
     ) -> RelateResult<'tcx, Ty<'tcx>>
     where
@@ -442,7 +442,7 @@ impl VidValuePair<'tcx> for (ty::TyVid, Ty<'tcx>) {
 
     fn vid_scopes<D>(
         &self,
-        relate: &'r mut TypeRelating<'_, '_, 'tcx, D>,
+        relate: &'r mut TypeRelating<'_, 'tcx, D>,
     ) -> &'r mut Vec<BoundRegionScope<'tcx>>
     where
         D: TypeRelatingDelegate<'tcx>,
@@ -452,7 +452,7 @@ impl VidValuePair<'tcx> for (ty::TyVid, Ty<'tcx>) {
 
     fn relate_generalized_ty<D>(
         &self,
-        relate: &mut TypeRelating<'_, '_, 'tcx, D>,
+        relate: &mut TypeRelating<'_, 'tcx, D>,
         generalized_ty: Ty<'tcx>,
     ) -> RelateResult<'tcx, Ty<'tcx>>
     where
@@ -474,7 +474,7 @@ impl VidValuePair<'tcx> for (Ty<'tcx>, ty::TyVid) {
 
     fn vid_scopes<D>(
         &self,
-        relate: &'r mut TypeRelating<'_, '_, 'tcx, D>,
+        relate: &'r mut TypeRelating<'_, 'tcx, D>,
     ) -> &'r mut Vec<BoundRegionScope<'tcx>>
     where
         D: TypeRelatingDelegate<'tcx>,
@@ -484,7 +484,7 @@ impl VidValuePair<'tcx> for (Ty<'tcx>, ty::TyVid) {
 
     fn relate_generalized_ty<D>(
         &self,
-        relate: &mut TypeRelating<'_, '_, 'tcx, D>,
+        relate: &mut TypeRelating<'_, 'tcx, D>,
         generalized_ty: Ty<'tcx>,
     ) -> RelateResult<'tcx, Ty<'tcx>>
     where
@@ -494,11 +494,11 @@ impl VidValuePair<'tcx> for (Ty<'tcx>, ty::TyVid) {
     }
 }
 
-impl<D> TypeRelation<'gcx, 'tcx> for TypeRelating<'me, 'gcx, 'tcx, D>
+impl<D> TypeRelation<'tcx> for TypeRelating<'me, 'tcx, D>
 where
     D: TypeRelatingDelegate<'tcx>,
 {
-    fn tcx(&self) -> TyCtxt<'gcx, 'tcx> {
+    fn tcx(&self) -> TyCtxt<'tcx> {
         self.infcx.tcx
     }
 
@@ -798,11 +798,11 @@ impl<'me, 'tcx> TypeVisitor<'tcx> for ScopeInstantiator<'me, 'tcx> {
 /// scopes.
 ///
 /// [blog post]: https://is.gd/0hKvIr
-struct TypeGeneralizer<'me, 'gcx: 'tcx, 'tcx: 'me, D>
+struct TypeGeneralizer<'me, 'tcx: 'me, D>
 where
     D: TypeRelatingDelegate<'tcx> + 'me,
 {
-    infcx: &'me InferCtxt<'me, 'gcx, 'tcx>,
+    infcx: &'me InferCtxt<'me, 'tcx>,
 
     delegate: &'me mut D,
 
@@ -823,11 +823,11 @@ where
     universe: ty::UniverseIndex,
 }
 
-impl<D> TypeRelation<'gcx, 'tcx> for TypeGeneralizer<'me, 'gcx, 'tcx, D>
+impl<D> TypeRelation<'tcx> for TypeGeneralizer<'me, 'tcx, D>
 where
     D: TypeRelatingDelegate<'tcx>,
 {
-    fn tcx(&self) -> TyCtxt<'gcx, 'tcx> {
+    fn tcx(&self) -> TyCtxt<'tcx> {
         self.infcx.tcx
     }
 
diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs
index 355d527e8ef..8e9af8b3938 100644
--- a/src/librustc/infer/opaque_types/mod.rs
+++ b/src/librustc/infer/opaque_types/mod.rs
@@ -73,7 +73,7 @@ pub struct OpaqueTypeDecl<'tcx> {
     pub origin: hir::ExistTyOrigin,
 }
 
-impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     /// Replaces all opaque types in `value` with fresh inference variables
     /// and creates appropriate obligations. For example, given the input:
     ///
@@ -430,8 +430,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         &self,
         def_id: DefId,
         opaque_defn: &OpaqueTypeDecl<'tcx>,
-        instantiated_ty: Ty<'gcx>,
-    ) -> Ty<'gcx> {
+        instantiated_ty: Ty<'tcx>,
+    ) -> Ty<'tcx> {
         debug!(
             "infer_opaque_definition_from_instantiation(def_id={:?}, instantiated_ty={:?})",
             def_id, instantiated_ty
@@ -446,7 +446,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         // `impl Trait` return type, resulting in the parameters
         // shifting.
         let id_substs = InternalSubsts::identity_for_item(gcx, def_id);
-        let map: FxHashMap<Kind<'tcx>, Kind<'gcx>> = opaque_defn
+        let map: FxHashMap<Kind<'tcx>, Kind<'tcx>> = opaque_defn
             .substs
             .iter()
             .enumerate()
@@ -470,7 +470,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         );
 
         // We can unwrap here because our reverse mapper always
-        // produces things with 'gcx lifetime, though the type folder
+        // produces things with 'tcx lifetime, though the type folder
         // obscures that.
         let definition_ty = gcx.lift(&definition_ty).unwrap();
 
@@ -491,14 +491,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
 //
 // We ignore any type parameters because impl trait values are assumed to
 // capture all the in-scope type parameters.
-struct OpaqueTypeOutlivesVisitor<'a, 'gcx, 'tcx> {
-    infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
+struct OpaqueTypeOutlivesVisitor<'a, 'tcx> {
+    infcx: &'a InferCtxt<'a, 'tcx>,
     least_region: ty::Region<'tcx>,
     span: Span,
 }
 
-impl<'tcx> TypeVisitor<'tcx> for OpaqueTypeOutlivesVisitor<'_, '_, 'tcx>
-{
+impl<'tcx> TypeVisitor<'tcx> for OpaqueTypeOutlivesVisitor<'_, 'tcx> {
     fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> bool {
         t.skip_binder().visit_with(self);
         false // keep visiting
@@ -552,27 +551,27 @@ impl<'tcx> TypeVisitor<'tcx> for OpaqueTypeOutlivesVisitor<'_, '_, 'tcx>
     }
 }
 
-struct ReverseMapper<'gcx, 'tcx> {
-    tcx: TyCtxt<'gcx, 'tcx>,
+struct ReverseMapper<'tcx> {
+    tcx: TyCtxt<'tcx>,
 
     /// If errors have already been reported in this fn, we suppress
     /// our own errors because they are sometimes derivative.
     tainted_by_errors: bool,
 
     opaque_type_def_id: DefId,
-    map: FxHashMap<Kind<'tcx>, Kind<'gcx>>,
+    map: FxHashMap<Kind<'tcx>, Kind<'tcx>>,
     map_missing_regions_to_empty: bool,
 
     /// initially `Some`, set to `None` once error has been reported
     hidden_ty: Option<Ty<'tcx>>,
 }
 
-impl ReverseMapper<'gcx, 'tcx> {
+impl ReverseMapper<'tcx> {
     fn new(
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         tainted_by_errors: bool,
         opaque_type_def_id: DefId,
-        map: FxHashMap<Kind<'tcx>, Kind<'gcx>>,
+        map: FxHashMap<Kind<'tcx>, Kind<'tcx>>,
         hidden_ty: Ty<'tcx>,
     ) -> Self {
         Self {
@@ -599,8 +598,8 @@ impl ReverseMapper<'gcx, 'tcx> {
     }
 }
 
-impl TypeFolder<'gcx, 'tcx> for ReverseMapper<'gcx, 'tcx> {
-    fn tcx(&self) -> TyCtxt<'gcx, 'tcx> {
+impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
+    fn tcx(&self) -> TyCtxt<'tcx> {
         self.tcx
     }
 
@@ -724,8 +723,8 @@ impl TypeFolder<'gcx, 'tcx> for ReverseMapper<'gcx, 'tcx> {
     }
 }
 
-struct Instantiator<'a, 'gcx: 'tcx, 'tcx: 'a> {
-    infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
+struct Instantiator<'a, 'tcx: 'a> {
+    infcx: &'a InferCtxt<'a, 'tcx>,
     parent_def_id: DefId,
     body_id: hir::HirId,
     param_env: ty::ParamEnv<'tcx>,
@@ -733,7 +732,7 @@ struct Instantiator<'a, 'gcx: 'tcx, 'tcx: 'a> {
     obligations: Vec<PredicateObligation<'tcx>>,
 }
 
-impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> Instantiator<'a, 'tcx> {
     fn instantiate_opaque_types_in_map<T: TypeFoldable<'tcx>>(&mut self, value: &T) -> T {
         debug!("instantiate_opaque_types_in_map(value={:?})", value);
         let tcx = self.infcx.tcx;
@@ -944,7 +943,7 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
 /// and `opaque_hir_id` is the `HirId` of the definition of the existential type `Baz`.
 /// For the above example, this function returns `true` for `f1` and `false` for `f2`.
 pub fn may_define_existential_type(
-    tcx: TyCtxt<'_, '_>,
+    tcx: TyCtxt<'_>,
     def_id: DefId,
     opaque_hir_id: hir::HirId,
 ) -> bool {
diff --git a/src/librustc/infer/outlives/env.rs b/src/librustc/infer/outlives/env.rs
index 3e626999200..ff27bbf7db2 100644
--- a/src/librustc/infer/outlives/env.rs
+++ b/src/librustc/infer/outlives/env.rs
@@ -67,7 +67,7 @@ pub struct OutlivesEnvironment<'tcx> {
 /// because of implied bounds.
 pub type RegionBoundPairs<'tcx> = Vec<(ty::Region<'tcx>, GenericKind<'tcx>)>;
 
-impl<'a, 'gcx: 'tcx, 'tcx: 'a> OutlivesEnvironment<'tcx> {
+impl<'a, 'tcx: 'a> OutlivesEnvironment<'tcx> {
     pub fn new(param_env: ty::ParamEnv<'tcx>) -> Self {
         let mut env = OutlivesEnvironment {
             param_env,
@@ -160,7 +160,7 @@ impl<'a, 'gcx: 'tcx, 'tcx: 'a> OutlivesEnvironment<'tcx> {
     /// Tests: `src/test/compile-fail/regions-free-region-ordering-*.rs`
     pub fn add_implied_bounds(
         &mut self,
-        infcx: &InferCtxt<'a, 'gcx, 'tcx>,
+        infcx: &InferCtxt<'a, 'tcx>,
         fn_sig_tys: &[Ty<'tcx>],
         body_id: hir::HirId,
         span: Span,
@@ -192,7 +192,7 @@ impl<'a, 'gcx: 'tcx, 'tcx: 'a> OutlivesEnvironment<'tcx> {
     /// `RegionConstraintData`.)
     fn add_outlives_bounds<I>(
         &mut self,
-        infcx: Option<&InferCtxt<'a, 'gcx, 'tcx>>,
+        infcx: Option<&InferCtxt<'a, 'tcx>>,
         outlives_bounds: I,
     ) where
         I: IntoIterator<Item = OutlivesBound<'tcx>>,
diff --git a/src/librustc/infer/outlives/free_region_map.rs b/src/librustc/infer/outlives/free_region_map.rs
index c2ae561fcd3..1250995a59c 100644
--- a/src/librustc/infer/outlives/free_region_map.rs
+++ b/src/librustc/infer/outlives/free_region_map.rs
@@ -28,9 +28,9 @@ impl<'tcx> FreeRegionMap<'tcx> {
     /// cases, this is more conservative than necessary, in order to
     /// avoid making arbitrary choices. See
     /// `TransitiveRelation::postdom_upper_bound` for more details.
-    pub fn lub_free_regions<'gcx>(
+    pub fn lub_free_regions(
         &self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         r_a: Region<'tcx>,
         r_b: Region<'tcx>,
     ) -> Region<'tcx> {
@@ -91,7 +91,7 @@ impl_stable_hash_for!(struct FreeRegionMap<'tcx> {
 
 impl<'a, 'tcx> Lift<'tcx> for FreeRegionMap<'a> {
     type Lifted = FreeRegionMap<'tcx>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<FreeRegionMap<'tcx>> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<FreeRegionMap<'tcx>> {
         self.relation.maybe_map(|&fr| tcx.lift(&fr))
                      .map(|relation| FreeRegionMap { relation })
     }
diff --git a/src/librustc/infer/outlives/obligations.rs b/src/librustc/infer/outlives/obligations.rs
index ddc1cd0ff3f..671718b1008 100644
--- a/src/librustc/infer/outlives/obligations.rs
+++ b/src/librustc/infer/outlives/obligations.rs
@@ -69,7 +69,7 @@ use crate::ty::outlives::Component;
 use crate::ty::{self, Region, Ty, TyCtxt, TypeFoldable};
 use crate::ty::subst::UnpackedKind;
 
-impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
+impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
     /// Registers that the given region obligation must be resolved
     /// from within the scope of `body_id`. These regions are enqueued
     /// and later processed by regionck, when full type information is
@@ -226,15 +226,15 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
 /// via a "delegate" of type `D` -- this is usually the `infcx`, which
 /// accrues them into the `region_obligations` code, but for NLL we
 /// use something else.
-pub struct TypeOutlives<'cx, 'gcx: 'tcx, 'tcx: 'cx, D>
+pub struct TypeOutlives<'cx, 'tcx: 'cx, D>
 where
     D: TypeOutlivesDelegate<'tcx>,
 {
     // See the comments on `process_registered_region_obligations` for the meaning
     // of these fields.
     delegate: D,
-    tcx: TyCtxt<'gcx, 'tcx>,
-    verify_bound: VerifyBoundCx<'cx, 'gcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
+    verify_bound: VerifyBoundCx<'cx, 'tcx>,
 }
 
 pub trait TypeOutlivesDelegate<'tcx> {
@@ -254,13 +254,13 @@ pub trait TypeOutlivesDelegate<'tcx> {
     );
 }
 
-impl<'cx, 'gcx, 'tcx, D> TypeOutlives<'cx, 'gcx, 'tcx, D>
+impl<'cx, 'tcx, D> TypeOutlives<'cx, 'tcx, D>
 where
     D: TypeOutlivesDelegate<'tcx>,
 {
     pub fn new(
         delegate: D,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         region_bound_pairs: &'cx RegionBoundPairs<'tcx>,
         implicit_region_bound: Option<ty::Region<'tcx>>,
         param_env: ty::ParamEnv<'tcx>,
@@ -487,7 +487,7 @@ where
     }
 }
 
-impl<'cx, 'gcx, 'tcx> TypeOutlivesDelegate<'tcx> for &'cx InferCtxt<'cx, 'gcx, 'tcx> {
+impl<'cx, 'tcx> TypeOutlivesDelegate<'tcx> for &'cx InferCtxt<'cx, 'tcx> {
     fn push_sub_region_constraint(
         &mut self,
         origin: SubregionOrigin<'tcx>,
diff --git a/src/librustc/infer/outlives/verify.rs b/src/librustc/infer/outlives/verify.rs
index 72079a6adc9..96335e1052e 100644
--- a/src/librustc/infer/outlives/verify.rs
+++ b/src/librustc/infer/outlives/verify.rs
@@ -12,16 +12,16 @@ use crate::util::captures::Captures;
 /// via a "delegate" of type `D` -- this is usually the `infcx`, which
 /// accrues them into the `region_obligations` code, but for NLL we
 /// use something else.
-pub struct VerifyBoundCx<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
-    tcx: TyCtxt<'gcx, 'tcx>,
+pub struct VerifyBoundCx<'cx, 'tcx: 'cx> {
+    tcx: TyCtxt<'tcx>,
     region_bound_pairs: &'cx RegionBoundPairs<'tcx>,
     implicit_region_bound: Option<ty::Region<'tcx>>,
     param_env: ty::ParamEnv<'tcx>,
 }
 
-impl<'cx, 'gcx, 'tcx> VerifyBoundCx<'cx, 'gcx, 'tcx> {
+impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
     pub fn new(
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         region_bound_pairs: &'cx RegionBoundPairs<'tcx>,
         implicit_region_bound: Option<ty::Region<'tcx>>,
         param_env: ty::ParamEnv<'tcx>,
@@ -102,7 +102,7 @@ impl<'cx, 'gcx, 'tcx> VerifyBoundCx<'cx, 'gcx, 'tcx> {
     pub fn projection_declared_bounds_from_trait(
         &self,
         projection_ty: ty::ProjectionTy<'tcx>,
-    ) -> impl Iterator<Item = ty::Region<'tcx>> + 'cx + Captures<'gcx> {
+    ) -> impl Iterator<Item = ty::Region<'tcx>> + 'cx + Captures<'tcx> {
         self.declared_projection_bounds_from_trait(projection_ty)
     }
 
@@ -244,7 +244,7 @@ impl<'cx, 'gcx, 'tcx> VerifyBoundCx<'cx, 'gcx, 'tcx> {
     fn declared_projection_bounds_from_trait(
         &self,
         projection_ty: ty::ProjectionTy<'tcx>,
-    ) -> impl Iterator<Item = ty::Region<'tcx>> + 'cx + Captures<'gcx> {
+    ) -> impl Iterator<Item = ty::Region<'tcx>> + 'cx + Captures<'tcx> {
         debug!("projection_bounds(projection_ty={:?})", projection_ty);
         let tcx = self.tcx;
         self.region_bounds_declared_on_associated_item(projection_ty.item_def_id)
@@ -284,7 +284,7 @@ impl<'cx, 'gcx, 'tcx> VerifyBoundCx<'cx, 'gcx, 'tcx> {
     fn region_bounds_declared_on_associated_item(
         &self,
         assoc_item_def_id: DefId,
-    ) -> impl Iterator<Item = ty::Region<'tcx>> + 'cx + Captures<'gcx> {
+    ) -> impl Iterator<Item = ty::Region<'tcx>> + 'cx + Captures<'tcx> {
         let tcx = self.tcx;
         let assoc_item = tcx.associated_item(assoc_item_def_id);
         let trait_def_id = assoc_item.container.assert_trait();
diff --git a/src/librustc/infer/region_constraints/leak_check.rs b/src/librustc/infer/region_constraints/leak_check.rs
index 5fc6523feba..30f6137289a 100644
--- a/src/librustc/infer/region_constraints/leak_check.rs
+++ b/src/librustc/infer/region_constraints/leak_check.rs
@@ -22,7 +22,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
     /// refactor the constraint set.
     pub fn leak_check(
         &mut self,
-        tcx: TyCtxt<'_, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         overly_polymorphic: bool,
         placeholder_map: &PlaceholderMap<'tcx>,
         _snapshot: &CombinedSnapshot<'_, 'tcx>,
@@ -109,7 +109,7 @@ impl<'tcx> TaintSet<'tcx> {
 
     fn fixed_point(
         &mut self,
-        tcx: TyCtxt<'_, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         undo_log: &[UndoLog<'tcx>],
         verifys: &[Verify<'tcx>],
     ) {
diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs
index cab102907f6..f2235fe8d6d 100644
--- a/src/librustc/infer/region_constraints/mod.rs
+++ b/src/librustc/infer/region_constraints/mod.rs
@@ -700,7 +700,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
 
     pub fn lub_regions(
         &mut self,
-        tcx: TyCtxt<'_, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         origin: SubregionOrigin<'tcx>,
         a: Region<'tcx>,
         b: Region<'tcx>,
@@ -722,7 +722,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
 
     pub fn glb_regions(
         &mut self,
-        tcx: TyCtxt<'_, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         origin: SubregionOrigin<'tcx>,
         a: Region<'tcx>,
         b: Region<'tcx>,
@@ -744,7 +744,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
 
     pub fn opportunistic_resolve_var(
         &mut self,
-        tcx: TyCtxt<'_, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         rid: RegionVid,
     ) -> ty::Region<'tcx> {
         let vid = self.unification_table.probe_value(rid).min_vid;
@@ -760,7 +760,7 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
 
     fn combine_vars(
         &mut self,
-        tcx: TyCtxt<'_, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         t: CombineMapType,
         a: Region<'tcx>,
         b: Region<'tcx>,
@@ -849,8 +849,8 @@ impl<'tcx> fmt::Display for GenericKind<'tcx> {
     }
 }
 
-impl<'gcx, 'tcx> GenericKind<'tcx> {
-    pub fn to_ty(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Ty<'tcx> {
+impl<'tcx> GenericKind<'tcx> {
+    pub fn to_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         match *self {
             GenericKind::Param(ref p) => p.to_ty(tcx),
             GenericKind::Projection(ref p) => tcx.mk_projection(p.item_def_id, p.substs),
diff --git a/src/librustc/infer/resolve.rs b/src/librustc/infer/resolve.rs
index 774ebdcdd25..5ca79bfa7bc 100644
--- a/src/librustc/infer/resolve.rs
+++ b/src/librustc/infer/resolve.rs
@@ -12,19 +12,19 @@ use crate::ty::fold::{TypeFolder, TypeVisitor};
 /// been unified with (similar to `shallow_resolve`, but deep). This is
 /// useful for printing messages etc but also required at various
 /// points for correctness.
-pub struct OpportunisticVarResolver<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
-    infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
+pub struct OpportunisticVarResolver<'a, 'tcx: 'a> {
+    infcx: &'a InferCtxt<'a, 'tcx>,
 }
 
-impl<'a, 'gcx, 'tcx> OpportunisticVarResolver<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> OpportunisticVarResolver<'a, 'tcx> {
     #[inline]
-    pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>) -> Self {
+    pub fn new(infcx: &'a InferCtxt<'a, 'tcx>) -> Self {
         OpportunisticVarResolver { infcx }
     }
 }
 
-impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticVarResolver<'a, 'gcx, 'tcx> {
-    fn tcx<'b>(&'b self) -> TyCtxt<'gcx, 'tcx> {
+impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticVarResolver<'a, 'tcx> {
+    fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
         self.infcx.tcx
     }
 
@@ -50,18 +50,18 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticVarResolver<'a, 'gc
 /// The opportunistic type and region resolver is similar to the
 /// opportunistic type resolver, but also opportunistically resolves
 /// regions. It is useful for canonicalization.
-pub struct OpportunisticTypeAndRegionResolver<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
-    infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
+pub struct OpportunisticTypeAndRegionResolver<'a, 'tcx: 'a> {
+    infcx: &'a InferCtxt<'a, 'tcx>,
 }
 
-impl<'a, 'gcx, 'tcx> OpportunisticTypeAndRegionResolver<'a, 'gcx, 'tcx> {
-    pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>) -> Self {
+impl<'a, 'tcx> OpportunisticTypeAndRegionResolver<'a, 'tcx> {
+    pub fn new(infcx: &'a InferCtxt<'a, 'tcx>) -> Self {
         OpportunisticTypeAndRegionResolver { infcx }
     }
 }
 
-impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticTypeAndRegionResolver<'a, 'gcx, 'tcx> {
-    fn tcx<'b>(&'b self) -> TyCtxt<'gcx, 'tcx> {
+impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticTypeAndRegionResolver<'a, 'tcx> {
+    fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
         self.infcx.tcx
     }
 
@@ -101,20 +101,20 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticTypeAndRegionResolv
 /// type variables that don't yet have a value. The first unresolved type is stored.
 /// It does not construct the fully resolved type (which might
 /// involve some hashing and so forth).
-pub struct UnresolvedTypeFinder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
-    infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
+pub struct UnresolvedTypeFinder<'a, 'tcx: 'a> {
+    infcx: &'a InferCtxt<'a, 'tcx>,
 
     /// Used to find the type parameter name and location for error reporting.
     pub first_unresolved: Option<(Ty<'tcx>,Option<Span>)>,
 }
 
-impl<'a, 'gcx, 'tcx> UnresolvedTypeFinder<'a, 'gcx, 'tcx> {
-    pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>) -> Self {
+impl<'a, 'tcx> UnresolvedTypeFinder<'a, 'tcx> {
+    pub fn new(infcx: &'a InferCtxt<'a, 'tcx>) -> Self {
         UnresolvedTypeFinder { infcx, first_unresolved: None }
     }
 }
 
-impl<'a, 'gcx, 'tcx> TypeVisitor<'tcx> for UnresolvedTypeFinder<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> TypeVisitor<'tcx> for UnresolvedTypeFinder<'a, 'tcx> {
     fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
         let t = self.infcx.shallow_resolve(t);
         if t.has_infer_types() {
@@ -157,7 +157,7 @@ impl<'a, 'gcx, 'tcx> TypeVisitor<'tcx> for UnresolvedTypeFinder<'a, 'gcx, 'tcx>
 /// Full type resolution replaces all type and region variables with
 /// their concrete results. If any variable cannot be replaced (never unified, etc)
 /// then an `Err` result is returned.
-pub fn fully_resolve<'a, 'gcx, 'tcx, T>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
+pub fn fully_resolve<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
                                         value: &T) -> FixupResult<'tcx, T>
     where T : TypeFoldable<'tcx>
 {
@@ -171,13 +171,13 @@ pub fn fully_resolve<'a, 'gcx, 'tcx, T>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
 
 // N.B. This type is not public because the protocol around checking the
 // `err` field is not enforcable otherwise.
-struct FullTypeResolver<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
-    infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
+struct FullTypeResolver<'a, 'tcx: 'a> {
+    infcx: &'a InferCtxt<'a, 'tcx>,
     err: Option<FixupError<'tcx>>,
 }
 
-impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for FullTypeResolver<'a, 'gcx, 'tcx> {
-    fn tcx<'b>(&'b self) -> TyCtxt<'gcx, 'tcx> {
+impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
+    fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
         self.infcx.tcx
     }
 
diff --git a/src/librustc/infer/sub.rs b/src/librustc/infer/sub.rs
index e17da50d7be..0284e087b7e 100644
--- a/src/librustc/infer/sub.rs
+++ b/src/librustc/infer/sub.rs
@@ -11,14 +11,14 @@ use crate::mir::interpret::ConstValue;
 use std::mem;
 
 /// Ensures `a` is made a subtype of `b`. Returns `a` on success.
-pub struct Sub<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
-    fields: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>,
+pub struct Sub<'combine, 'infcx: 'combine, 'tcx: 'infcx> {
+    fields: &'combine mut CombineFields<'infcx, 'tcx>,
     a_is_expected: bool,
 }
 
-impl<'combine, 'infcx, 'gcx, 'tcx> Sub<'combine, 'infcx, 'gcx, 'tcx> {
-    pub fn new(f: &'combine mut CombineFields<'infcx, 'gcx, 'tcx>, a_is_expected: bool)
-        -> Sub<'combine, 'infcx, 'gcx, 'tcx>
+impl<'combine, 'infcx, 'tcx> Sub<'combine, 'infcx, 'tcx> {
+    pub fn new(f: &'combine mut CombineFields<'infcx, 'tcx>, a_is_expected: bool)
+        -> Sub<'combine, 'infcx, 'tcx>
     {
         Sub { fields: f, a_is_expected: a_is_expected }
     }
@@ -31,9 +31,9 @@ impl<'combine, 'infcx, 'gcx, 'tcx> Sub<'combine, 'infcx, 'gcx, 'tcx> {
     }
 }
 
-impl TypeRelation<'gcx, 'tcx> for Sub<'combine, 'infcx, 'gcx, 'tcx> {
+impl TypeRelation<'tcx> for Sub<'combine, 'infcx, 'tcx> {
     fn tag(&self) -> &'static str { "Sub" }
-    fn tcx(&self) -> TyCtxt<'gcx, 'tcx> { self.fields.infcx.tcx }
+    fn tcx(&self) -> TyCtxt<'tcx> { self.fields.infcx.tcx }
     fn a_is_expected(&self) -> bool { self.a_is_expected }
 
     fn with_cause<F,R>(&mut self, cause: Cause, f: F) -> R
diff --git a/src/librustc/infer/unify_key.rs b/src/librustc/infer/unify_key.rs
index 7f9880031f3..846611db054 100644
--- a/src/librustc/infer/unify_key.rs
+++ b/src/librustc/infer/unify_key.rs
@@ -10,7 +10,7 @@ use std::marker::PhantomData;
 use std::cell::RefMut;
 
 pub trait ToType {
-    fn to_type<'gcx, 'tcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Ty<'tcx>;
+    fn to_type<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx>;
 }
 
 impl UnifyKey for ty::IntVid {
@@ -52,7 +52,7 @@ impl UnifyKey for ty::RegionVid {
 }
 
 impl ToType for IntVarValue {
-    fn to_type<'gcx, 'tcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Ty<'tcx> {
+    fn to_type<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         match *self {
             ty::IntType(i) => tcx.mk_mach_int(i),
             ty::UintType(i) => tcx.mk_mach_uint(i),
@@ -72,7 +72,7 @@ impl UnifyKey for ty::FloatVid {
 impl EqUnifyValue for FloatVarValue {}
 
 impl ToType for FloatVarValue {
-    fn to_type<'gcx, 'tcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Ty<'tcx> {
+    fn to_type<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         tcx.mk_mach_float(self.0)
     }
 }
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index c6a77a314be..c4a37d83866 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -509,7 +509,7 @@ impl LintStore {
 /// Context for lint checking after type checking.
 pub struct LateContext<'a, 'tcx: 'a> {
     /// Type context we're checking in.
-    pub tcx: TyCtxt<'tcx, 'tcx>,
+    pub tcx: TyCtxt<'tcx>,
 
     /// Side-tables for the body we are in.
     // FIXME: Make this lazy to avoid running the TypeckTables query?
@@ -781,10 +781,10 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> {
     /// ```
     pub fn get_def_path(&self, def_id: DefId) -> Vec<Symbol> {
         pub struct AbsolutePathPrinter<'tcx> {
-            pub tcx: TyCtxt<'tcx, 'tcx>,
+            pub tcx: TyCtxt<'tcx>,
         }
 
-        impl<'tcx> Printer<'tcx, 'tcx> for AbsolutePathPrinter<'tcx> {
+        impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
             type Error = !;
 
             type Path = Vec<Symbol>;
@@ -793,7 +793,7 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> {
             type DynExistential = ();
             type Const = ();
 
-            fn tcx(&self) -> TyCtxt<'tcx, 'tcx> {
+            fn tcx(&self) -> TyCtxt<'tcx> {
                 self.tcx
             }
 
@@ -1372,7 +1372,7 @@ macro_rules! late_lint_pass_impl {
 late_lint_methods!(late_lint_pass_impl, [], ['tcx]);
 
 fn late_lint_mod_pass<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     module_def_id: DefId,
     pass: T,
 ) {
@@ -1404,7 +1404,7 @@ fn late_lint_mod_pass<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(
 }
 
 pub fn late_lint_mod<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     module_def_id: DefId,
     builtin_lints: T,
 ) {
@@ -1423,7 +1423,7 @@ pub fn late_lint_mod<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(
     }
 }
 
-fn late_lint_pass_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tcx, 'tcx>, pass: T) {
+fn late_lint_pass_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tcx>, pass: T) {
     let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);
 
     let krate = tcx.hir().krate();
@@ -1457,7 +1457,7 @@ fn late_lint_pass_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tc
 }
 
 fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     builtin_lints: T,
 ) {
     let mut passes = tcx.sess.lint_store.borrow().late_passes.lock().take().unwrap();
@@ -1491,7 +1491,7 @@ fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(
 
 /// Performs lint checking on a crate.
 pub fn check_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     builtin_lints: impl FnOnce() -> T + Send,
 ) {
     join(|| {
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 5a17eee173d..70c0e83517a 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -761,12 +761,12 @@ pub fn struct_lint_level<'a>(sess: &'a Session,
     return err
 }
 
-pub fn maybe_lint_level_root(tcx: TyCtxt<'_, '_>, id: hir::HirId) -> bool {
+pub fn maybe_lint_level_root(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
     let attrs = tcx.hir().attrs_by_hir_id(id);
     attrs.iter().any(|attr| Level::from_symbol(attr.name_or_empty()).is_some())
 }
 
-fn lint_levels<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, cnum: CrateNum) -> &'tcx LintLevelMap {
+fn lint_levels<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> &'tcx LintLevelMap {
     assert_eq!(cnum, LOCAL_CRATE);
     let mut builder = LintLevelMapBuilder {
         levels: LintLevelSets::builder(tcx.sess),
@@ -787,7 +787,7 @@ fn lint_levels<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, cnum: CrateNum) -> &'tcx LintLevel
 
 struct LintLevelMapBuilder<'tcx> {
     levels: levels::LintLevelsBuilder<'tcx>,
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
 }
 
 impl LintLevelMapBuilder<'tcx> {
diff --git a/src/librustc/macros.rs b/src/librustc/macros.rs
index aeacd3722b4..09fa924efc7 100644
--- a/src/librustc/macros.rs
+++ b/src/librustc/macros.rs
@@ -195,7 +195,7 @@ macro_rules! CloneLiftImpls {
         $(
             impl<$tcx> $crate::ty::Lift<$tcx> for $ty {
                 type Lifted = Self;
-                fn lift_to_tcx<'gcx>(&self, _: $crate::ty::TyCtxt<'gcx, $tcx>) -> Option<Self> {
+                fn lift_to_tcx(&self, _: $crate::ty::TyCtxt<$tcx>) -> Option<Self> {
                     Some(Clone::clone(self))
                 }
             }
@@ -218,7 +218,7 @@ macro_rules! CloneTypeFoldableImpls {
     (for <$tcx:lifetime> { $($ty:ty,)+ }) => {
         $(
             impl<$tcx> $crate::ty::fold::TypeFoldable<$tcx> for $ty {
-                fn super_fold_with<'gcx: $tcx, F: $crate::ty::fold::TypeFolder<'gcx, $tcx>>(
+                fn super_fold_with<F: $crate::ty::fold::TypeFolder<$tcx>>(
                     &self,
                     _: &mut F
                 ) -> $ty {
@@ -264,7 +264,7 @@ macro_rules! BraceStructLiftImpl {
         {
             type Lifted = $lifted;
 
-            fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<$lifted> {
+            fn lift_to_tcx(&self, tcx: TyCtxt<$tcx>) -> Option<$lifted> {
                 $(let $field = tcx.lift(&self.$field)?;)*
                 Some(Self::Lifted { $($field),* })
             }
@@ -283,7 +283,7 @@ macro_rules! EnumLiftImpl {
         {
             type Lifted = $lifted;
 
-            fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<$lifted> {
+            fn lift_to_tcx(&self, tcx: TyCtxt<$tcx>) -> Option<$lifted> {
                 EnumLiftImpl!(@Variants(self, tcx) input($($variants)*) output())
             }
         }
@@ -332,7 +332,7 @@ macro_rules! BraceStructTypeFoldableImpl {
         impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s
             $(where $($wc)*)*
         {
-            fn super_fold_with<'gcx: $tcx, V: $crate::ty::fold::TypeFolder<'gcx, $tcx>>(
+            fn super_fold_with<V: $crate::ty::fold::TypeFolder<$tcx>>(
                 &self,
                 folder: &mut V,
             ) -> Self {
@@ -359,7 +359,7 @@ macro_rules! TupleStructTypeFoldableImpl {
         impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s
             $(where $($wc)*)*
         {
-            fn super_fold_with<'gcx: $tcx, V: $crate::ty::fold::TypeFolder<'gcx, $tcx>>(
+            fn super_fold_with<V: $crate::ty::fold::TypeFolder<$tcx>>(
                 &self,
                 folder: &mut V,
             ) -> Self {
@@ -386,7 +386,7 @@ macro_rules! EnumTypeFoldableImpl {
         impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s
             $(where $($wc)*)*
         {
-            fn super_fold_with<'gcx: $tcx, V: $crate::ty::fold::TypeFolder<'gcx, $tcx>>(
+            fn super_fold_with<V: $crate::ty::fold::TypeFolder<$tcx>>(
                 &self,
                 folder: &mut V,
             ) -> Self {
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index f258f06b87d..2e9e1ac582f 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -211,7 +211,7 @@ pub trait CrateStore {
     fn crates_untracked(&self) -> Vec<CrateNum>;
 
     // utility functions
-    fn encode_metadata<'tcx>(&self, tcx: TyCtxt<'tcx, 'tcx>) -> EncodedMetadata;
+    fn encode_metadata<'tcx>(&self, tcx: TyCtxt<'tcx>) -> EncodedMetadata;
     fn metadata_encoding_version(&self) -> &[u8];
 }
 
@@ -226,7 +226,7 @@ pub type CrateStoreDyn = dyn CrateStore + sync::Sync;
 // In order to get this left-to-right dependency ordering, we perform a
 // topological sort of all crates putting the leaves at the right-most
 // positions.
-pub fn used_crates(tcx: TyCtxt<'_, '_>, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)> {
+pub fn used_crates(tcx: TyCtxt<'_>, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)> {
     let mut libs = tcx.crates()
         .iter()
         .cloned()
diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 18e19e802e8..0356e7e1072 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -26,7 +26,7 @@ use syntax_pos;
 // explored. For example, if it's a live Node::Item that is a
 // function, then we should explore its block to check for codes that
 // may need to be marked as live.
-fn should_explore<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, hir_id: hir::HirId) -> bool {
+fn should_explore<'tcx>(tcx: TyCtxt<'tcx>, hir_id: hir::HirId) -> bool {
     match tcx.hir().find_by_hir_id(hir_id) {
         Some(Node::Item(..)) |
         Some(Node::ImplItem(..)) |
@@ -40,7 +40,7 @@ fn should_explore<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, hir_id: hir::HirId) -> bool {
 
 struct MarkSymbolVisitor<'a, 'tcx: 'a> {
     worklist: Vec<hir::HirId>,
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     tables: &'a ty::TypeckTables<'tcx>,
     live_symbols: FxHashSet<hir::HirId>,
     repr_has_repr_c: bool,
@@ -302,7 +302,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
 }
 
 fn has_allow_dead_code_or_lang_attr(
-    tcx: TyCtxt<'_, '_>,
+    tcx: TyCtxt<'_>,
     id: hir::HirId,
     attrs: &[ast::Attribute],
 ) -> bool {
@@ -354,7 +354,7 @@ fn has_allow_dead_code_or_lang_attr(
 struct LifeSeeder<'k, 'tcx: 'k> {
     worklist: Vec<hir::HirId>,
     krate: &'k hir::Crate,
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     // see `MarkSymbolVisitor::struct_constructors`
     struct_constructors: FxHashMap<hir::HirId, hir::HirId>,
 }
@@ -425,7 +425,7 @@ impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> {
 }
 
 fn create_and_seed_worklist<'tcx>(
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     access_levels: &privacy::AccessLevels,
     krate: &hir::Crate,
 ) -> (Vec<hir::HirId>, FxHashMap<hir::HirId, hir::HirId>) {
@@ -453,7 +453,7 @@ fn create_and_seed_worklist<'tcx>(
 }
 
 fn find_live<'tcx>(
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     access_levels: &privacy::AccessLevels,
     krate: &hir::Crate,
 ) -> FxHashSet<hir::HirId> {
@@ -474,7 +474,7 @@ fn find_live<'tcx>(
 }
 
 struct DeadVisitor<'tcx> {
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     live_symbols: FxHashSet<hir::HirId>,
 }
 
@@ -662,7 +662,7 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> {
     }
 }
 
-pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx, 'tcx>) {
+pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>) {
     let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);
     let krate = tcx.hir().krate();
     let live_symbols = find_live(tcx, access_levels, krate);
diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs
index 2f6a3f2f027..879da6413e2 100644
--- a/src/librustc/middle/dependency_format.rs
+++ b/src/librustc/middle/dependency_format.rs
@@ -81,7 +81,7 @@ pub enum Linkage {
     Dynamic,
 }
 
-pub fn calculate<'tcx>(tcx: TyCtxt<'tcx, 'tcx>) {
+pub fn calculate<'tcx>(tcx: TyCtxt<'tcx>) {
     let sess = &tcx.sess;
     let fmts = sess.crate_types.borrow().iter().map(|&ty| {
         let linkage = calculate_type(tcx, ty);
@@ -92,7 +92,7 @@ pub fn calculate<'tcx>(tcx: TyCtxt<'tcx, 'tcx>) {
     sess.dependency_formats.set(fmts);
 }
 
-fn calculate_type<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, ty: config::CrateType) -> DependencyList {
+fn calculate_type<'tcx>(tcx: TyCtxt<'tcx>, ty: config::CrateType) -> DependencyList {
     let sess = &tcx.sess;
 
     if !sess.opts.output_types.should_codegen() {
@@ -241,7 +241,7 @@ fn calculate_type<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, ty: config::CrateType) -> Depen
 }
 
 fn add_library(
-    tcx: TyCtxt<'_, '_>,
+    tcx: TyCtxt<'_>,
     cnum: CrateNum,
     link: LinkagePreference,
     m: &mut FxHashMap<CrateNum, LinkagePreference>,
@@ -267,7 +267,7 @@ fn add_library(
     }
 }
 
-fn attempt_static<'tcx>(tcx: TyCtxt<'tcx, 'tcx>) -> Option<DependencyList> {
+fn attempt_static<'tcx>(tcx: TyCtxt<'tcx>) -> Option<DependencyList> {
     let sess = &tcx.sess;
     let crates = cstore::used_crates(tcx, RequireStatic);
     if !crates.iter().by_ref().all(|&(_, ref p)| p.is_some()) {
@@ -324,7 +324,7 @@ fn activate_injected_dep(injected: Option<CrateNum>,
 
 // After the linkage for a crate has been determined we need to verify that
 // there's only going to be one allocator in the output.
-fn verify_ok<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, list: &[Linkage]) {
+fn verify_ok<'tcx>(tcx: TyCtxt<'tcx>, list: &[Linkage]) {
     let sess = &tcx.sess;
     if list.len() == 0 {
         return
diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs
index 024196e3564..704be9600fa 100644
--- a/src/librustc/middle/entry.rs
+++ b/src/librustc/middle/entry.rs
@@ -47,7 +47,7 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for EntryContext<'a, 'tcx> {
     }
 }
 
-fn entry_fn(tcx: TyCtxt<'_, '_>, cnum: CrateNum) -> Option<(DefId, EntryFnType)> {
+fn entry_fn(tcx: TyCtxt<'_>, cnum: CrateNum) -> Option<(DefId, EntryFnType)> {
     assert_eq!(cnum, LOCAL_CRATE);
 
     let any_exe = tcx.sess.crate_types.borrow().iter().any(|ty| {
@@ -141,7 +141,7 @@ fn find_item(item: &Item, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
 }
 
 fn configure_main(
-    tcx: TyCtxt<'_, '_>,
+    tcx: TyCtxt<'_>,
     visitor: &EntryContext<'_, '_>,
 ) -> Option<(DefId, EntryFnType)> {
     if let Some((hir_id, _)) = visitor.start_fn {
@@ -179,7 +179,7 @@ fn configure_main(
     }
 }
 
-pub fn find_entry_point(tcx: TyCtxt<'_, '_>) -> Option<(DefId, EntryFnType)> {
+pub fn find_entry_point(tcx: TyCtxt<'_>) -> Option<(DefId, EntryFnType)> {
     tcx.entry_fn(LOCAL_CRATE)
 }
 
diff --git a/src/librustc/middle/exported_symbols.rs b/src/librustc/middle/exported_symbols.rs
index 9e7af280408..78a3e3ff268 100644
--- a/src/librustc/middle/exported_symbols.rs
+++ b/src/librustc/middle/exported_symbols.rs
@@ -38,7 +38,7 @@ pub enum ExportedSymbol<'tcx> {
 }
 
 impl<'tcx> ExportedSymbol<'tcx> {
-    pub fn symbol_name(&self, tcx: TyCtxt<'tcx, '_>) -> ty::SymbolName {
+    pub fn symbol_name(&self, tcx: TyCtxt<'tcx>) -> ty::SymbolName {
         match *self {
             ExportedSymbol::NonGeneric(def_id) => {
                 tcx.symbol_name(ty::Instance::mono(tcx, def_id))
@@ -54,7 +54,7 @@ impl<'tcx> ExportedSymbol<'tcx> {
 
     pub fn compare_stable(
         &self,
-        tcx: TyCtxt<'tcx, '_>,
+        tcx: TyCtxt<'tcx>,
         other: &ExportedSymbol<'tcx>,
     ) -> cmp::Ordering {
         match *self {
@@ -91,13 +91,13 @@ impl<'tcx> ExportedSymbol<'tcx> {
     }
 }
 
-pub fn metadata_symbol_name(tcx: TyCtxt<'_, '_>) -> String {
+pub fn metadata_symbol_name(tcx: TyCtxt<'_>) -> String {
     format!("rust_metadata_{}_{}",
             tcx.original_crate_name(LOCAL_CRATE),
             tcx.crate_disambiguator(LOCAL_CRATE).to_fingerprint().to_hex())
 }
 
-impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ExportedSymbol<'gcx> {
+impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ExportedSymbol<'tcx> {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
                                           hasher: &mut StableHasher<W>) {
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index 3ed926d7582..80c26c132f6 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -202,7 +202,7 @@ enum OverloadedCallType {
 }
 
 impl OverloadedCallType {
-    fn from_trait_id(tcx: TyCtxt<'_, '_>, trait_id: DefId) -> OverloadedCallType {
+    fn from_trait_id(tcx: TyCtxt<'_>, trait_id: DefId) -> OverloadedCallType {
         for &(maybe_function_trait, overloaded_call_type) in &[
             (tcx.lang_items().fn_once_trait(), FnOnceOverloadedCall),
             (tcx.lang_items().fn_mut_trait(), FnMutOverloadedCall),
@@ -219,7 +219,7 @@ impl OverloadedCallType {
         bug!("overloaded call didn't map to known function trait")
     }
 
-    fn from_method_id(tcx: TyCtxt<'_, '_>, method_id: DefId) -> OverloadedCallType {
+    fn from_method_id(tcx: TyCtxt<'_>, method_id: DefId) -> OverloadedCallType {
         let method = tcx.associated_item(method_id);
         OverloadedCallType::from_trait_id(tcx, method.container.id())
     }
@@ -229,8 +229,8 @@ impl OverloadedCallType {
 // The ExprUseVisitor type
 //
 // This is the code that actually walks the tree.
-pub struct ExprUseVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
-    mc: mc::MemCategorizationContext<'a, 'gcx, 'tcx>,
+pub struct ExprUseVisitor<'a, 'tcx: 'a> {
+    mc: mc::MemCategorizationContext<'a, 'tcx>,
     delegate: &'a mut dyn Delegate<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
 }
@@ -254,7 +254,7 @@ macro_rules! return_if_err {
     )
 }
 
-impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx, 'tcx> {
+impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
     /// Creates the ExprUseVisitor, configuring it with the various options provided:
     ///
     /// - `delegate` -- who receives the callbacks
@@ -268,7 +268,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx, 'tcx> {
     /// See also `with_infer`, which is used *during* typeck.
     pub fn new(
         delegate: &'a mut (dyn Delegate<'tcx> + 'a),
-        tcx: TyCtxt<'tcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         body_owner: DefId,
         param_env: ty::ParamEnv<'tcx>,
         region_scope_tree: &'a region::ScopeTree,
@@ -287,9 +287,9 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx, 'tcx> {
     }
 }
 
-impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
     pub fn with_infer(delegate: &'a mut (dyn Delegate<'tcx>+'a),
-                      infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
+                      infcx: &'a InferCtxt<'a, 'tcx>,
                       body_owner: DefId,
                       param_env: ty::ParamEnv<'tcx>,
                       region_scope_tree: &'a region::ScopeTree,
@@ -333,7 +333,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
         self.consume_expr(&body.value);
     }
 
-    fn tcx(&self) -> TyCtxt<'gcx, 'tcx> {
+    fn tcx(&self) -> TyCtxt<'tcx> {
         self.mc.tcx
     }
 
@@ -974,7 +974,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
     }
 }
 
-fn copy_or_move<'a, 'gcx, 'tcx>(mc: &mc::MemCategorizationContext<'a, 'gcx, 'tcx>,
+fn copy_or_move<'a, 'tcx>(mc: &mc::MemCategorizationContext<'a, 'tcx>,
                                 param_env: ty::ParamEnv<'tcx>,
                                 cmt: &mc::cmt_<'tcx>,
                                 move_reason: MoveReason)
diff --git a/src/librustc/middle/free_region.rs b/src/librustc/middle/free_region.rs
index 74c50cabab0..a8a7df08469 100644
--- a/src/librustc/middle/free_region.rs
+++ b/src/librustc/middle/free_region.rs
@@ -15,8 +15,8 @@ use crate::ty::{self, TyCtxt, Region};
 ///
 /// This stuff is a bit convoluted and should be refactored, but as we
 /// transition to NLL, it'll all go away anyhow.
-pub struct RegionRelations<'a, 'gcx: 'tcx, 'tcx: 'a> {
-    pub tcx: TyCtxt<'gcx, 'tcx>,
+pub struct RegionRelations<'a, 'tcx: 'a> {
+    pub tcx: TyCtxt<'tcx>,
 
     /// The context used to fetch the region maps.
     pub context: DefId,
@@ -28,9 +28,9 @@ pub struct RegionRelations<'a, 'gcx: 'tcx, 'tcx: 'a> {
     pub free_regions: &'a FreeRegionMap<'tcx>,
 }
 
-impl<'a, 'gcx, 'tcx> RegionRelations<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> RegionRelations<'a, 'tcx> {
     pub fn new(
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         context: DefId,
         region_scope_tree: &'a region::ScopeTree,
         free_regions: &'a FreeRegionMap<'tcx>,
diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs
index d3ed818c4be..e8d68e0b7a7 100644
--- a/src/librustc/middle/intrinsicck.rs
+++ b/src/librustc/middle/intrinsicck.rs
@@ -10,7 +10,7 @@ use syntax_pos::{Span, sym};
 use crate::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use crate::hir;
 
-fn check_mod_intrinsics<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, module_def_id: DefId) {
+fn check_mod_intrinsics<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) {
     tcx.hir().visit_item_likes_in_module(
         module_def_id,
         &mut ItemVisitor { tcx }.as_deep_visitor()
@@ -25,18 +25,18 @@ pub fn provide(providers: &mut Providers<'_>) {
 }
 
 struct ItemVisitor<'tcx> {
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
 }
 
 struct ExprVisitor<'tcx> {
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     tables: &'tcx ty::TypeckTables<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
 }
 
 /// If the type is `Option<T>`, it will return `T`, otherwise
 /// the type itself. Works on most `Option`-like types.
-fn unpack_option_like<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
+fn unpack_option_like<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
     let (def, substs) = match ty.sty {
         ty::Adt(def, substs) => (def, substs),
         _ => return ty
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 02163409b32..d7abdb8ecbe 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -106,7 +106,7 @@ impl LanguageItems {
 
 struct LanguageItemCollector<'tcx> {
     items: LanguageItems,
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     /// A mapping from the name of the lang item to its order and the form it must be of.
     item_refs: FxHashMap<&'static str, (usize, Target)>,
 }
@@ -160,7 +160,7 @@ impl ItemLikeVisitor<'v> for LanguageItemCollector<'tcx> {
 }
 
 impl LanguageItemCollector<'tcx> {
-    fn new(tcx: TyCtxt<'tcx, 'tcx>) -> LanguageItemCollector<'tcx> {
+    fn new(tcx: TyCtxt<'tcx>) -> LanguageItemCollector<'tcx> {
         let mut item_refs = FxHashMap::default();
 
         $( item_refs.insert($name, ($variant as usize, $target)); )*
@@ -217,7 +217,7 @@ pub fn extract(attrs: &[ast::Attribute]) -> Option<(Symbol, Span)> {
 }
 
 /// Traverse and collect all the lang items in all crates.
-pub fn collect<'tcx>(tcx: TyCtxt<'tcx, 'tcx>) -> LanguageItems {
+pub fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> LanguageItems {
     // Initialize the collector.
     let mut collector = LanguageItemCollector::new(tcx);
 
@@ -402,7 +402,7 @@ language_item_table! {
     Rc,                          "rc",                 rc,                      Target::Struct;
 }
 
-impl<'tcx, 'gcx> TyCtxt<'tcx, 'gcx> {
+impl<'tcx> TyCtxt<'tcx> {
     /// Returns the `DefId` for a given `LangItem`.
     /// If not found, fatally abort compilation.
     pub fn require_lang_item(&self, lang_item: LangItem) -> DefId {
diff --git a/src/librustc/middle/lib_features.rs b/src/librustc/middle/lib_features.rs
index b05ede53d1c..9c131ce6342 100644
--- a/src/librustc/middle/lib_features.rs
+++ b/src/librustc/middle/lib_features.rs
@@ -38,12 +38,12 @@ impl LibFeatures {
 }
 
 pub struct LibFeatureCollector<'tcx> {
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     lib_features: LibFeatures,
 }
 
 impl LibFeatureCollector<'tcx> {
-    fn new(tcx: TyCtxt<'tcx, 'tcx>) -> LibFeatureCollector<'tcx> {
+    fn new(tcx: TyCtxt<'tcx>) -> LibFeatureCollector<'tcx> {
         LibFeatureCollector {
             tcx,
             lib_features: LibFeatures::new(),
@@ -142,7 +142,7 @@ impl Visitor<'tcx> for LibFeatureCollector<'tcx> {
     }
 }
 
-pub fn collect<'tcx>(tcx: TyCtxt<'tcx, 'tcx>) -> LibFeatures {
+pub fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> LibFeatures {
     let mut collector = LibFeatureCollector::new(tcx);
     intravisit::walk_crate(&mut collector, tcx.hir().krate());
     collector.lib_features
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 92cb407f67d..260935a38d6 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -150,7 +150,7 @@ enum LiveNodeKind {
     ExitNode
 }
 
-fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: TyCtxt<'_, '_>) -> String {
+fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: TyCtxt<'_>) -> String {
     let cm = tcx.sess.source_map();
     match lnk {
         UpvarNode(s) => {
@@ -181,7 +181,7 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> {
     fn visit_arm(&mut self, a: &'tcx hir::Arm) { visit_arm(self, a); }
 }
 
-fn check_mod_liveness<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, module_def_id: DefId) {
+fn check_mod_liveness<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) {
     tcx.hir().visit_item_likes_in_module(
         module_def_id,
         &mut IrMaps::new(tcx, module_def_id).as_deep_visitor(),
@@ -257,7 +257,7 @@ enum VarKind {
 }
 
 struct IrMaps<'tcx> {
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     body_owner: DefId,
     num_live_nodes: usize,
     num_vars: usize,
@@ -269,7 +269,7 @@ struct IrMaps<'tcx> {
 }
 
 impl IrMaps<'tcx> {
-    fn new(tcx: TyCtxt<'tcx, 'tcx>, body_owner: DefId) -> IrMaps<'tcx> {
+    fn new(tcx: TyCtxt<'tcx>, body_owner: DefId) -> IrMaps<'tcx> {
         IrMaps {
             tcx,
             body_owner,
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 4b5b901f470..bc87aa8f872 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -287,14 +287,14 @@ impl HirNode for hir::Pat {
 }
 
 #[derive(Clone)]
-pub struct MemCategorizationContext<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
-    pub tcx: TyCtxt<'gcx, 'tcx>,
+pub struct MemCategorizationContext<'a, 'tcx> {
+    pub tcx: TyCtxt<'tcx>,
     pub body_owner: DefId,
     pub upvars: Option<&'tcx FxIndexMap<hir::HirId, hir::Upvar>>,
     pub region_scope_tree: &'a region::ScopeTree,
     pub tables: &'a ty::TypeckTables<'tcx>,
     rvalue_promotable_map: Option<&'tcx ItemLocalSet>,
-    infcx: Option<&'a InferCtxt<'a, 'gcx, 'tcx>>,
+    infcx: Option<&'a InferCtxt<'a, 'tcx>>,
 }
 
 pub type McResult<T> = Result<T, ()>;
@@ -340,7 +340,7 @@ impl MutabilityCategory {
     }
 
     fn from_local(
-        tcx: TyCtxt<'_, '_>,
+        tcx: TyCtxt<'_>,
         tables: &ty::TypeckTables<'_>,
         id: ast::NodeId,
     ) -> MutabilityCategory {
@@ -402,14 +402,14 @@ impl MutabilityCategory {
     }
 }
 
-impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx, 'tcx> {
+impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
     pub fn new(
-        tcx: TyCtxt<'tcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         body_owner: DefId,
         region_scope_tree: &'a region::ScopeTree,
         tables: &'a ty::TypeckTables<'tcx>,
         rvalue_promotable_map: Option<&'tcx ItemLocalSet>,
-    ) -> MemCategorizationContext<'a, 'tcx, 'tcx> {
+    ) -> MemCategorizationContext<'a, 'tcx> {
         MemCategorizationContext {
             tcx,
             body_owner,
@@ -422,7 +422,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx, 'tcx> {
     }
 }
 
-impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
     /// Creates a `MemCategorizationContext` during type inference.
     /// This is used during upvar analysis and a few other places.
     /// Because the typeck tables are not yet complete, the results
@@ -432,11 +432,11 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
     ///   temporaries may be overly conservative;
     /// - similarly, as the results of upvar analysis are not yet
     ///   known, the results around upvar accesses may be incorrect.
-    pub fn with_infer(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
+    pub fn with_infer(infcx: &'a InferCtxt<'a, 'tcx>,
                       body_owner: DefId,
                       region_scope_tree: &'a region::ScopeTree,
                       tables: &'a ty::TypeckTables<'tcx>)
-                      -> MemCategorizationContext<'a, 'gcx, 'tcx> {
+                      -> MemCategorizationContext<'a, 'tcx> {
         let tcx = infcx.tcx;
 
         // Subtle: we can't do rvalue promotion analysis until the
@@ -586,7 +586,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
     pub fn cat_expr(&self, expr: &hir::Expr) -> McResult<cmt_<'tcx>> {
         // This recursion helper avoids going through *too many*
         // adjustments, since *only* non-overloaded deref recurses.
-        fn helper<'a, 'gcx, 'tcx>(mc: &MemCategorizationContext<'a, 'gcx, 'tcx>,
+        fn helper<'a, 'tcx>(mc: &MemCategorizationContext<'a, 'tcx>,
                                   expr: &hir::Expr,
                                   adjustments: &[adjustment::Adjustment<'tcx>])
                                   -> McResult<cmt_<'tcx>> {
@@ -1518,7 +1518,7 @@ impl<'tcx> cmt_<'tcx> {
         }
     }
 
-    pub fn descriptive_string(&self, tcx: TyCtxt<'_, '_>) -> Cow<'static, str> {
+    pub fn descriptive_string(&self, tcx: TyCtxt<'_>) -> Cow<'static, str> {
         match self.cat {
             Categorization::StaticItem => {
                 "static item".into()
diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs
index b0068a191da..363ccd74c08 100644
--- a/src/librustc/middle/reachable.rs
+++ b/src/librustc/middle/reachable.rs
@@ -27,7 +27,7 @@ use crate::hir::intravisit;
 // Returns true if the given item must be inlined because it may be
 // monomorphized or it was marked with `#[inline]`. This will only return
 // true for functions.
-fn item_might_be_inlined(tcx: TyCtxt<'tcx, 'tcx>, item: &hir::Item, attrs: CodegenFnAttrs) -> bool {
+fn item_might_be_inlined(tcx: TyCtxt<'tcx>, item: &hir::Item, attrs: CodegenFnAttrs) -> bool {
     if attrs.requests_inline() {
         return true
     }
@@ -43,7 +43,7 @@ fn item_might_be_inlined(tcx: TyCtxt<'tcx, 'tcx>, item: &hir::Item, attrs: Codeg
 }
 
 fn method_might_be_inlined<'tcx>(
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     impl_item: &hir::ImplItem,
     impl_src: DefId,
 ) -> bool {
@@ -67,7 +67,7 @@ fn method_might_be_inlined<'tcx>(
 // Information needed while computing reachability.
 struct ReachableContext<'a, 'tcx: 'a> {
     // The type context.
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     tables: &'a ty::TypeckTables<'tcx>,
     // The set of items which must be exported in the linkage sense.
     reachable_symbols: HirIdSet,
@@ -335,7 +335,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
 // trait items are used from inlinable code through method call syntax or UFCS, or their
 // trait is a lang item.
 struct CollectPrivateImplItemsVisitor<'a, 'tcx: 'a> {
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     access_levels: &'a privacy::AccessLevels,
     worklist: &'a mut Vec<hir::HirId>,
 }
@@ -391,7 +391,7 @@ impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a,
 #[derive(Clone, HashStable)]
 pub struct ReachableSet(pub Lrc<HirIdSet>);
 
-fn reachable_set<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, crate_num: CrateNum) -> ReachableSet {
+fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> ReachableSet {
     debug_assert!(crate_num == LOCAL_CRATE);
 
     let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index 5968933721d..546d51e9124 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -169,7 +169,7 @@ impl Scope {
         self.id
     }
 
-    pub fn node_id(&self, tcx: TyCtxt<'_, '_>, scope_tree: &ScopeTree) -> ast::NodeId {
+    pub fn node_id(&self, tcx: TyCtxt<'_>, scope_tree: &ScopeTree) -> ast::NodeId {
         match scope_tree.root_body {
             Some(hir_id) => {
                 tcx.hir().hir_to_node_id(hir::HirId {
@@ -184,7 +184,7 @@ impl Scope {
     /// Returns the span of this `Scope`. Note that in general the
     /// returned span may not correspond to the span of any `NodeId` in
     /// the AST.
-    pub fn span(&self, tcx: TyCtxt<'_, '_>, scope_tree: &ScopeTree) -> Span {
+    pub fn span(&self, tcx: TyCtxt<'_>, scope_tree: &ScopeTree) -> Span {
         let node_id = self.node_id(tcx, scope_tree);
         if node_id == ast::DUMMY_NODE_ID {
             return DUMMY_SP;
@@ -359,7 +359,7 @@ pub struct Context {
 }
 
 struct RegionResolutionVisitor<'tcx> {
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
 
     // The number of expressions and patterns visited in the current body
     expr_and_pat_count: usize,
@@ -646,9 +646,9 @@ impl<'tcx> ScopeTree {
 
     /// Assuming that the provided region was defined within this `ScopeTree`,
     /// returns the outermost `Scope` that the region outlives.
-    pub fn early_free_scope<'gcx>(
+    pub fn early_free_scope(
         &self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         br: &ty::EarlyBoundRegion,
     ) -> Scope {
         let param_owner = tcx.parent(br.def_id).unwrap();
@@ -679,7 +679,7 @@ impl<'tcx> ScopeTree {
 
     /// Assuming that the provided region was defined within this `ScopeTree`,
     /// returns the outermost `Scope` that the region outlives.
-    pub fn free_scope<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>, fr: &ty::FreeRegion) -> Scope {
+    pub fn free_scope(&self, tcx: TyCtxt<'tcx>, fr: &ty::FreeRegion) -> Scope {
         let param_owner = match fr.bound_region {
             ty::BoundRegion::BrNamed(def_id, _) => {
                 tcx.parent(def_id).unwrap()
@@ -1334,7 +1334,7 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
     }
 }
 
-fn region_scope_tree<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, def_id: DefId) -> &'tcx ScopeTree {
+fn region_scope_tree<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx ScopeTree {
     let closure_base_def_id = tcx.closure_base_def_id(def_id);
     if closure_base_def_id != def_id {
         return tcx.region_scope_tree(closure_base_def_id);
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index edd5cb4541a..e187a3ced3f 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -218,7 +218,7 @@ impl_stable_hash_for!(struct crate::middle::resolve_lifetime::ResolveLifetimes {
 });
 
 struct LifetimeContext<'a, 'tcx: 'a> {
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     map: &'a mut NamedRegionMap,
     scope: ScopeRef<'a>,
 
@@ -368,7 +368,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
 /// entire crate. You should not read the result of this query
 /// directly, but rather use `named_region_map`, `is_late_bound_map`,
 /// etc.
-fn resolve_lifetimes<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, for_krate: CrateNum) -> &'tcx ResolveLifetimes {
+fn resolve_lifetimes<'tcx>(tcx: TyCtxt<'tcx>, for_krate: CrateNum) -> &'tcx ResolveLifetimes {
     assert_eq!(for_krate, LOCAL_CRATE);
 
     let named_region_map = krate(tcx);
@@ -395,7 +395,7 @@ fn resolve_lifetimes<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, for_krate: CrateNum) -> &'tc
     tcx.arena.alloc(rl)
 }
 
-fn krate<'tcx>(tcx: TyCtxt<'tcx, 'tcx>) -> NamedRegionMap {
+fn krate<'tcx>(tcx: TyCtxt<'tcx>) -> NamedRegionMap {
     let krate = tcx.hir().krate();
     let mut map = NamedRegionMap {
         defs: Default::default(),
@@ -1098,7 +1098,7 @@ impl ShadowKind {
     }
 }
 
-fn check_mixed_explicit_and_in_band_defs(tcx: TyCtxt<'_, '_>, params: &P<[hir::GenericParam]>) {
+fn check_mixed_explicit_and_in_band_defs(tcx: TyCtxt<'_>, params: &P<[hir::GenericParam]>) {
     let lifetime_params: Vec<_> = params
         .iter()
         .filter_map(|param| match param.kind {
@@ -1126,7 +1126,7 @@ fn check_mixed_explicit_and_in_band_defs(tcx: TyCtxt<'_, '_>, params: &P<[hir::G
 }
 
 fn signal_shadowing_problem(
-    tcx: TyCtxt<'_, '_>,
+    tcx: TyCtxt<'_>,
     name: ast::Name,
     orig: Original,
     shadower: Shadower,
@@ -1166,7 +1166,7 @@ fn signal_shadowing_problem(
 // if one of the label shadows a lifetime or another label.
 fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body) {
     struct GatherLabels<'a, 'tcx: 'a> {
-        tcx: TyCtxt<'tcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         scope: ScopeRef<'a>,
         labels_in_fn: &'a mut Vec<ast::Ident>,
     }
@@ -1215,7 +1215,7 @@ fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body) {
     }
 
     fn check_if_label_shadows_lifetime(
-        tcx: TyCtxt<'_, '_>,
+        tcx: TyCtxt<'_>,
         mut scope: ScopeRef<'_>,
         label: ast::Ident,
     ) {
@@ -1253,7 +1253,7 @@ fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body) {
     }
 }
 
-fn compute_object_lifetime_defaults(tcx: TyCtxt<'_, '_>) -> HirIdMap<Vec<ObjectLifetimeDefault>> {
+fn compute_object_lifetime_defaults(tcx: TyCtxt<'_>) -> HirIdMap<Vec<ObjectLifetimeDefault>> {
     let mut map = HirIdMap::default();
     for item in tcx.hir().krate().items.values() {
         match item.node {
@@ -1310,7 +1310,7 @@ fn compute_object_lifetime_defaults(tcx: TyCtxt<'_, '_>) -> HirIdMap<Vec<ObjectL
 /// of the form `T:'a` so as to determine the `ObjectLifetimeDefault`
 /// for each type parameter.
 fn object_lifetime_defaults_for_item(
-    tcx: TyCtxt<'_, '_>,
+    tcx: TyCtxt<'_>,
     generics: &hir::Generics,
 ) -> Vec<ObjectLifetimeDefault> {
     fn add_bounds(set: &mut Set1<hir::LifetimeName>, bounds: &[hir::GenericBound]) {
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index dbd008256b0..19d127a565f 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -106,7 +106,7 @@ impl_stable_hash_for!(struct self::Index<'tcx> {
 
 // A private tree-walker for producing an Index.
 struct Annotator<'a, 'tcx: 'a> {
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     index: &'a mut Index<'tcx>,
     parent_stab: Option<&'tcx Stability>,
     parent_depr: Option<DeprecationEntry>,
@@ -317,7 +317,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
 }
 
 struct MissingStabilityAnnotations<'a, 'tcx: 'a> {
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     access_levels: &'a AccessLevels,
 }
 
@@ -390,7 +390,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'a, 'tcx> {
 }
 
 impl<'tcx> Index<'tcx> {
-    pub fn new(tcx: TyCtxt<'tcx, 'tcx>) -> Index<'tcx> {
+    pub fn new(tcx: TyCtxt<'tcx>) -> Index<'tcx> {
         let is_staged_api =
             tcx.sess.opts.debugging_opts.force_unstable_if_unmarked ||
             tcx.features().staged_api;
@@ -466,7 +466,7 @@ impl<'tcx> Index<'tcx> {
 
 /// Cross-references the feature names of unstable APIs with enabled
 /// features and possibly prints errors.
-fn check_mod_unstable_api_usage<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, module_def_id: DefId) {
+fn check_mod_unstable_api_usage<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) {
     tcx.hir().visit_item_likes_in_module(module_def_id, &mut Checker { tcx }.as_deep_visitor());
 }
 
@@ -502,7 +502,7 @@ pub fn deprecation_in_effect(since: &str) -> bool {
 }
 
 struct Checker<'tcx> {
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
 }
 
 /// Result of `TyCtxt::eval_stability`.
@@ -521,7 +521,7 @@ pub enum EvalResult {
     Unmarked,
 }
 
-impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
+impl<'tcx> TyCtxt<'tcx> {
     // See issue #38412.
     fn skip_stability_check_due_to_privacy(self, mut def_id: DefId) -> bool {
         // Check if `def_id` is a trait method.
@@ -827,7 +827,7 @@ impl Visitor<'tcx> for Checker<'tcx> {
     }
 }
 
-impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
+impl<'tcx> TyCtxt<'tcx> {
     pub fn lookup_deprecation(self, id: DefId) -> Option<Deprecation> {
         self.lookup_deprecation_entry(id).map(|depr| depr.attr)
     }
@@ -836,7 +836,7 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
 /// Given the list of enabled features that were not language features (i.e., that
 /// were expected to be library features), and the list of features used from
 /// libraries, identify activated features that don't exist and error about them.
-pub fn check_unused_or_stable_features<'tcx>(tcx: TyCtxt<'tcx, 'tcx>) {
+pub fn check_unused_or_stable_features<'tcx>(tcx: TyCtxt<'tcx>) {
     let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);
 
     if tcx.stability().staged_api[&LOCAL_CRATE] {
@@ -921,7 +921,7 @@ pub fn check_unused_or_stable_features<'tcx>(tcx: TyCtxt<'tcx, 'tcx>) {
 }
 
 fn unnecessary_stable_feature_lint<'tcx>(
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     span: Span,
     feature: Symbol,
     since: Symbol,
diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs
index 45d405df950..422ff3f2fd3 100644
--- a/src/librustc/middle/weak_lang_items.rs
+++ b/src/librustc/middle/weak_lang_items.rs
@@ -18,13 +18,13 @@ macro_rules! weak_lang_items {
     ($($name:ident, $item:ident, $sym:ident;)*) => (
 
 struct Context<'a, 'tcx: 'a> {
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     items: &'a mut lang_items::LanguageItems,
 }
 
 /// Checks the crate for usage of weak lang items, returning a vector of all the
 /// language items required by this crate, but not defined yet.
-pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx, 'tcx>,
+pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>,
                              items: &mut lang_items::LanguageItems) {
     // These are never called by user code, they're generated by the compiler.
     // They will never implicitly be added to the `missing` array unless we do
@@ -60,7 +60,7 @@ pub fn link_name(attrs: &[ast::Attribute]) -> Option<Symbol> {
 /// Not all lang items are always required for each compilation, particularly in
 /// the case of panic=abort. In these situations some lang items are injected by
 /// crates and don't actually need to be defined in libstd.
-pub fn whitelisted(tcx: TyCtxt<'_, '_>, lang_item: lang_items::LangItem) -> bool {
+pub fn whitelisted(tcx: TyCtxt<'_>, lang_item: lang_items::LangItem) -> bool {
     // If we're not compiling with unwinding, we won't actually need these
     // symbols. Other panic runtimes ensure that the relevant symbols are
     // available to link things together, but they're never exercised.
@@ -72,7 +72,7 @@ pub fn whitelisted(tcx: TyCtxt<'_, '_>, lang_item: lang_items::LangItem) -> bool
     false
 }
 
-fn verify<'tcx>(tcx: TyCtxt<'tcx, 'tcx>,
+fn verify<'tcx>(tcx: TyCtxt<'tcx>,
                     items: &lang_items::LanguageItems) {
     // We only need to check for the presence of weak lang items if we're
     // emitting something that's not an rlib.
@@ -142,7 +142,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
     }
 }
 
-impl<'tcx, 'gcx> TyCtxt<'tcx, 'gcx> {
+impl<'tcx> TyCtxt<'tcx> {
     pub fn is_weak_lang_item(&self, item_def_id: DefId) -> bool {
         let lang_items = self.lang_items();
         let did = Some(item_def_id);
diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs
index 009cab3bd03..e8113b4516c 100644
--- a/src/librustc/mir/interpret/error.rs
+++ b/src/librustc/mir/interpret/error.rs
@@ -74,16 +74,16 @@ impl<'tcx> fmt::Display for FrameInfo<'tcx> {
     }
 }
 
-impl<'gcx, 'tcx> ConstEvalErr<'tcx> {
+impl<'tcx> ConstEvalErr<'tcx> {
     pub fn struct_error(
         &self,
-        tcx: TyCtxtAt<'gcx, 'tcx>,
+        tcx: TyCtxtAt<'tcx>,
         message: &str,
     ) -> Result<DiagnosticBuilder<'tcx>, ErrorHandled> {
         self.struct_generic(tcx, message, None)
     }
 
-    pub fn report_as_error(&self, tcx: TyCtxtAt<'gcx, 'tcx>, message: &str) -> ErrorHandled {
+    pub fn report_as_error(&self, tcx: TyCtxtAt<'tcx>, message: &str) -> ErrorHandled {
         let err = self.struct_error(tcx, message);
         match err {
             Ok(mut err) => {
@@ -96,7 +96,7 @@ impl<'gcx, 'tcx> ConstEvalErr<'tcx> {
 
     pub fn report_as_lint(
         &self,
-        tcx: TyCtxtAt<'gcx, 'tcx>,
+        tcx: TyCtxtAt<'tcx>,
         message: &str,
         lint_root: hir::HirId,
         span: Option<Span>,
@@ -129,7 +129,7 @@ impl<'gcx, 'tcx> ConstEvalErr<'tcx> {
 
     fn struct_generic(
         &self,
-        tcx: TyCtxtAt<'gcx, 'tcx>,
+        tcx: TyCtxtAt<'tcx>,
         message: &str,
         lint_root: Option<hir::HirId>,
     ) -> Result<DiagnosticBuilder<'tcx>, ErrorHandled> {
@@ -170,7 +170,7 @@ impl<'gcx, 'tcx> ConstEvalErr<'tcx> {
     }
 }
 
-pub fn struct_error<'gcx, 'tcx>(tcx: TyCtxtAt<'gcx, 'tcx>, msg: &str) -> DiagnosticBuilder<'tcx> {
+pub fn struct_error<'tcx>(tcx: TyCtxtAt<'tcx>, msg: &str) -> DiagnosticBuilder<'tcx> {
     struct_span_err!(tcx.sess, tcx.span, E0080, "{}", msg)
 }
 
diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs
index f68385ec267..a36c7880229 100644
--- a/src/librustc/mir/interpret/mod.rs
+++ b/src/librustc/mir/interpret/mod.rs
@@ -66,7 +66,7 @@ enum AllocDiscriminant {
 
 pub fn specialized_encode_alloc_id<'tcx, E: Encoder>(
     encoder: &mut E,
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     alloc_id: AllocId,
 ) -> Result<(), E::Error> {
     let alloc: GlobalAlloc<'tcx> =
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index e73023d9a8c..008a57bddfe 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -1240,8 +1240,8 @@ impl<'tcx> Terminator<'tcx> {
 }
 
 impl<'tcx> TerminatorKind<'tcx> {
-    pub fn if_<'gcx>(
-        tcx: TyCtxt<'gcx, 'tcx>,
+    pub fn if_(
+        tcx: TyCtxt<'tcx>,
         cond: Operand<'tcx>,
         t: BasicBlock,
         f: BasicBlock,
@@ -2324,7 +2324,7 @@ impl<'tcx> Operand<'tcx> {
     /// with given `DefId` and substs. Since this is used to synthesize
     /// MIR, assumes `user_ty` is None.
     pub fn function_handle(
-        tcx: TyCtxt<'tcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         def_id: DefId,
         substs: SubstsRef<'tcx>,
         span: Span,
@@ -2795,7 +2795,7 @@ impl UserTypeProjection {
 CloneTypeFoldableAndLiftImpls! { ProjectionKind, }
 
 impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         use crate::mir::ProjectionElem::*;
 
         let base = self.base.fold_with(folder);
@@ -3012,8 +3012,8 @@ pub struct GeneratorLayout<'tcx> {
 }
 
 #[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
-pub struct BorrowCheckResult<'gcx> {
-    pub closure_requirements: Option<ClosureRegionRequirements<'gcx>>,
+pub struct BorrowCheckResult<'tcx> {
+    pub closure_requirements: Option<ClosureRegionRequirements<'tcx>>,
     pub used_mut_upvars: SmallVec<[Field; 8]>,
 }
 
@@ -3068,7 +3068,7 @@ pub struct BorrowCheckResult<'gcx> {
 /// TyCtxt, and hence we cannot use `ReVar` (which is what we use
 /// internally within the rest of the NLL code).
 #[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
-pub struct ClosureRegionRequirements<'gcx> {
+pub struct ClosureRegionRequirements<'tcx> {
     /// The number of external regions defined on the closure. In our
     /// example above, it would be 3 -- one for `'static`, then `'1`
     /// and `'2`. This is just used for a sanity check later on, to
@@ -3078,7 +3078,7 @@ pub struct ClosureRegionRequirements<'gcx> {
 
     /// Requirements between the various free regions defined in
     /// indices.
-    pub outlives_requirements: Vec<ClosureOutlivesRequirement<'gcx>>,
+    pub outlives_requirements: Vec<ClosureOutlivesRequirement<'tcx>>,
 }
 
 /// Indicates an outlives constraint between a type or between two
@@ -3262,7 +3262,7 @@ EnumTypeFoldableImpl! {
 }
 
 impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         use crate::mir::TerminatorKind::*;
 
         let kind = match self.kind {
@@ -3430,7 +3430,7 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
 }
 
 impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         match self {
             &Place::Projection(ref p) => Place::Projection(p.fold_with(folder)),
             _ => self.clone(),
@@ -3447,7 +3447,7 @@ impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> {
 }
 
 impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         use crate::mir::Rvalue::*;
         match *self {
             Use(ref op) => Use(op.fold_with(folder)),
@@ -3519,7 +3519,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
 }
 
 impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         match *self {
             Operand::Copy(ref place) => Operand::Copy(place.fold_with(folder)),
             Operand::Move(ref place) => Operand::Move(place.fold_with(folder)),
@@ -3536,7 +3536,7 @@ impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
 }
 
 impl<'tcx> TypeFoldable<'tcx> for Projection<'tcx> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         use crate::mir::ProjectionElem::*;
 
         let base = self.base.fold_with(folder);
@@ -3562,7 +3562,7 @@ impl<'tcx> TypeFoldable<'tcx> for Projection<'tcx> {
 }
 
 impl<'tcx> TypeFoldable<'tcx> for Field {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self {
         *self
     }
     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
@@ -3571,7 +3571,7 @@ impl<'tcx> TypeFoldable<'tcx> for Field {
 }
 
 impl<'tcx> TypeFoldable<'tcx> for GeneratorSavedLocal {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self {
         *self
     }
     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
@@ -3580,7 +3580,7 @@ impl<'tcx> TypeFoldable<'tcx> for GeneratorSavedLocal {
 }
 
 impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix<R, C> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self {
         self.clone()
     }
     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
@@ -3589,7 +3589,7 @@ impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix<R, C> {
 }
 
 impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         Constant {
             span: self.span.clone(),
             ty: self.ty.fold_with(folder),
diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs
index cf1126efc0f..39ae48b303a 100644
--- a/src/librustc/mir/mono.rs
+++ b/src/librustc/mir/mono.rs
@@ -48,7 +48,7 @@ pub enum MonoItem<'tcx> {
 }
 
 impl<'tcx> MonoItem<'tcx> {
-    pub fn size_estimate(&self, tcx: TyCtxt<'tcx, 'tcx>) -> usize {
+    pub fn size_estimate(&self, tcx: TyCtxt<'tcx>) -> usize {
         match *self {
             MonoItem::Fn(instance) => {
                 // Estimate the size of a function based on how many statements
@@ -72,7 +72,7 @@ impl<'tcx> MonoItem<'tcx> {
         }
     }
 
-    pub fn symbol_name(&self, tcx: TyCtxt<'tcx, 'tcx>) -> SymbolName {
+    pub fn symbol_name(&self, tcx: TyCtxt<'tcx>) -> SymbolName {
         match *self {
             MonoItem::Fn(instance) => tcx.symbol_name(instance),
             MonoItem::Static(def_id) => {
@@ -87,7 +87,7 @@ impl<'tcx> MonoItem<'tcx> {
         }
     }
 
-    pub fn instantiation_mode(&self, tcx: TyCtxt<'tcx, 'tcx>) -> InstantiationMode {
+    pub fn instantiation_mode(&self, tcx: TyCtxt<'tcx>) -> InstantiationMode {
         let inline_in_all_cgus =
             tcx.sess.opts.debugging_opts.inline_in_all_cgus.unwrap_or_else(|| {
                 tcx.sess.opts.optimize != OptLevel::No
@@ -131,7 +131,7 @@ impl<'tcx> MonoItem<'tcx> {
         }
     }
 
-    pub fn explicit_linkage(&self, tcx: TyCtxt<'tcx, 'tcx>) -> Option<Linkage> {
+    pub fn explicit_linkage(&self, tcx: TyCtxt<'tcx>) -> Option<Linkage> {
         let def_id = match *self {
             MonoItem::Fn(ref instance) => instance.def_id(),
             MonoItem::Static(def_id) => def_id,
@@ -167,7 +167,7 @@ impl<'tcx> MonoItem<'tcx> {
     /// Similarly, if a vtable method has such a signature, and therefore can't
     /// be used, we can just not emit it and have a placeholder (a null pointer,
     /// which will never be accessed) in its place.
-    pub fn is_instantiable(&self, tcx: TyCtxt<'tcx, 'tcx>) -> bool {
+    pub fn is_instantiable(&self, tcx: TyCtxt<'tcx>) -> bool {
         debug!("is_instantiable({:?})", self);
         let (def_id, substs) = match *self {
             MonoItem::Fn(ref instance) => (instance.def_id(), instance.substs),
@@ -179,7 +179,7 @@ impl<'tcx> MonoItem<'tcx> {
         tcx.substitute_normalize_and_test_predicates((def_id, &substs))
     }
 
-    pub fn to_string(&self, tcx: TyCtxt<'tcx, 'tcx>, debug: bool) -> String {
+    pub fn to_string(&self, tcx: TyCtxt<'tcx>, debug: bool) -> String {
         return match *self {
             MonoItem::Fn(instance) => {
                 to_string_internal(tcx, "fn ", instance, debug)
@@ -194,7 +194,7 @@ impl<'tcx> MonoItem<'tcx> {
         };
 
         fn to_string_internal<'tcx>(
-            tcx: TyCtxt<'tcx, 'tcx>,
+            tcx: TyCtxt<'tcx>,
             prefix: &str,
             instance: Instance<'tcx>,
             debug: bool,
@@ -207,7 +207,7 @@ impl<'tcx> MonoItem<'tcx> {
         }
     }
 
-    pub fn local_span(&self, tcx: TyCtxt<'tcx, 'tcx>) -> Option<Span> {
+    pub fn local_span(&self, tcx: TyCtxt<'tcx>) -> Option<Span> {
         match *self {
             MonoItem::Fn(Instance { def, .. }) => {
                 tcx.hir().as_local_hir_id(def.def_id())
@@ -333,7 +333,7 @@ impl<'tcx> CodegenUnit<'tcx> {
         base_n::encode(hash, base_n::CASE_INSENSITIVE)
     }
 
-    pub fn estimate_size(&mut self, tcx: TyCtxt<'tcx, 'tcx>) {
+    pub fn estimate_size(&mut self, tcx: TyCtxt<'tcx>) {
         // Estimate the size of a codegen unit as (approximately) the number of MIR
         // statements it corresponds to.
         self.size_estimate = Some(self.items.keys().map(|mi| mi.size_estimate(tcx)).sum());
@@ -359,7 +359,7 @@ impl<'tcx> CodegenUnit<'tcx> {
         WorkProductId::from_cgu_name(&self.name().as_str())
     }
 
-    pub fn work_product(&self, tcx: TyCtxt<'_, '_>) -> WorkProduct {
+    pub fn work_product(&self, tcx: TyCtxt<'_>) -> WorkProduct {
         let work_product_id = self.work_product_id();
         tcx.dep_graph
            .previous_work_product(&work_product_id)
@@ -370,14 +370,14 @@ impl<'tcx> CodegenUnit<'tcx> {
 
     pub fn items_in_deterministic_order(
         &self,
-        tcx: TyCtxt<'tcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
     ) -> Vec<(MonoItem<'tcx>, (Linkage, Visibility))> {
         // The codegen tests rely on items being process in the same order as
         // they appear in the file, so for local items, we sort by node_id first
         #[derive(PartialEq, Eq, PartialOrd, Ord)]
         pub struct ItemSortKey(Option<HirId>, SymbolName);
 
-        fn item_sort_key<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, item: MonoItem<'tcx>) -> ItemSortKey {
+        fn item_sort_key<'tcx>(tcx: TyCtxt<'tcx>, item: MonoItem<'tcx>) -> ItemSortKey {
             ItemSortKey(match item {
                 MonoItem::Fn(ref instance) => {
                     match instance.def {
@@ -413,7 +413,7 @@ impl<'tcx> CodegenUnit<'tcx> {
         items
     }
 
-    pub fn codegen_dep_node(&self, tcx: TyCtxt<'tcx, 'tcx>) -> DepNode {
+    pub fn codegen_dep_node(&self, tcx: TyCtxt<'tcx>) -> DepNode {
         DepNode::new(tcx, DepConstructor::CompileCodegenUnit(self.name().clone()))
     }
 }
@@ -443,13 +443,13 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for CodegenUnit<'tcx> {
     }
 }
 
-pub struct CodegenUnitNameBuilder<'gcx, 'tcx> {
-    tcx: TyCtxt<'gcx, 'tcx>,
+pub struct CodegenUnitNameBuilder<'tcx> {
+    tcx: TyCtxt<'tcx>,
     cache: FxHashMap<CrateNum, String>,
 }
 
-impl CodegenUnitNameBuilder<'gcx, 'tcx> {
-    pub fn new(tcx: TyCtxt<'gcx, 'tcx>) -> Self {
+impl CodegenUnitNameBuilder<'tcx> {
+    pub fn new(tcx: TyCtxt<'tcx>) -> Self {
         CodegenUnitNameBuilder {
             tcx,
             cache: Default::default(),
diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs
index 76d7d98b902..4a8f503b14f 100644
--- a/src/librustc/mir/tcx.rs
+++ b/src/librustc/mir/tcx.rs
@@ -21,7 +21,7 @@ pub struct PlaceTy<'tcx> {
 #[cfg(target_arch = "x86_64")]
 static_assert_size!(PlaceTy<'_>, 16);
 
-impl<'gcx, 'tcx> PlaceTy<'tcx> {
+impl<'tcx> PlaceTy<'tcx> {
     pub fn from_ty(ty: Ty<'tcx>) -> PlaceTy<'tcx> {
         PlaceTy { ty, variant_index: None }
     }
@@ -33,7 +33,7 @@ impl<'gcx, 'tcx> PlaceTy<'tcx> {
     /// not carry a `Ty` for `T`.)
     ///
     /// Note that the resulting type has not been normalized.
-    pub fn field_ty(self, tcx: TyCtxt<'gcx, 'tcx>, f: &Field) -> Ty<'tcx> {
+    pub fn field_ty(self, tcx: TyCtxt<'tcx>, f: &Field) -> Ty<'tcx> {
         let answer = match self.ty.sty {
             ty::Adt(adt_def, substs) => {
                 let variant_def = match self.variant_index {
@@ -56,7 +56,7 @@ impl<'gcx, 'tcx> PlaceTy<'tcx> {
     /// Convenience wrapper around `projection_ty_core` for
     /// `PlaceElem`, where we can just use the `Ty` that is already
     /// stored inline on field projection elems.
-    pub fn projection_ty(self, tcx: TyCtxt<'gcx, 'tcx>, elem: &PlaceElem<'tcx>) -> PlaceTy<'tcx> {
+    pub fn projection_ty(self, tcx: TyCtxt<'tcx>, elem: &PlaceElem<'tcx>) -> PlaceTy<'tcx> {
         self.projection_ty_core(tcx, elem, |_, _, ty| ty)
     }
 
@@ -67,7 +67,7 @@ impl<'gcx, 'tcx> PlaceTy<'tcx> {
     /// (which should be trivial when `T` = `Ty`).
     pub fn projection_ty_core<V, T>(
         self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         elem: &ProjectionElem<V, T>,
         mut handle_field: impl FnMut(&Self, &Field, &T) -> Ty<'tcx>,
     ) -> PlaceTy<'tcx>
@@ -118,7 +118,7 @@ BraceStructTypeFoldableImpl! {
 }
 
 impl<'tcx> Place<'tcx> {
-    pub fn ty<'gcx, D>(&self, local_decls: &D, tcx: TyCtxt<'gcx, 'tcx>) -> PlaceTy<'tcx>
+    pub fn ty<D>(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> PlaceTy<'tcx>
     where
         D: HasLocalDecls<'tcx>,
     {
@@ -139,7 +139,7 @@ pub enum RvalueInitializationState {
 }
 
 impl<'tcx> Rvalue<'tcx> {
-    pub fn ty<'gcx, D>(&self, local_decls: &D, tcx: TyCtxt<'gcx, 'tcx>) -> Ty<'tcx>
+    pub fn ty<D>(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> Ty<'tcx>
     where
         D: HasLocalDecls<'tcx>,
     {
@@ -221,7 +221,7 @@ impl<'tcx> Rvalue<'tcx> {
 }
 
 impl<'tcx> Operand<'tcx> {
-    pub fn ty<'gcx, D>(&self, local_decls: &D, tcx: TyCtxt<'gcx, 'tcx>) -> Ty<'tcx>
+    pub fn ty<D>(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> Ty<'tcx>
     where
         D: HasLocalDecls<'tcx>,
     {
@@ -234,9 +234,9 @@ impl<'tcx> Operand<'tcx> {
 }
 
 impl<'tcx> BinOp {
-    pub fn ty<'gcx>(
+    pub fn ty(
         &self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         lhs_ty: Ty<'tcx>,
         rhs_ty: Ty<'tcx>,
     ) -> Ty<'tcx> {
diff --git a/src/librustc/traits/auto_trait.rs b/src/librustc/traits/auto_trait.rs
index 00a162a31fa..d89cf8eb3e8 100644
--- a/src/librustc/traits/auto_trait.rs
+++ b/src/librustc/traits/auto_trait.rs
@@ -48,11 +48,11 @@ pub struct AutoTraitInfo<'cx> {
 }
 
 pub struct AutoTraitFinder<'tcx> {
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
 }
 
 impl<'tcx> AutoTraitFinder<'tcx> {
-    pub fn new(tcx: TyCtxt<'tcx, 'tcx>) -> Self {
+    pub fn new(tcx: TyCtxt<'tcx>) -> Self {
         AutoTraitFinder { tcx }
     }
 
@@ -79,7 +79,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
         ty: Ty<'tcx>,
         orig_env: ty::ParamEnv<'tcx>,
         trait_did: DefId,
-        auto_trait_callback: impl for<'i> Fn(&InferCtxt<'_, 'tcx, 'i>, AutoTraitInfo<'i>) -> A,
+        auto_trait_callback: impl Fn(&InferCtxt<'_, 'tcx>, AutoTraitInfo<'tcx>) -> A,
     ) -> AutoTraitResult<A> {
         let tcx = self.tcx;
 
@@ -270,16 +270,16 @@ impl AutoTraitFinder<'tcx> {
     // the final synthesized generics: we don't want our generated docs page to contain something
     // like 'T: Copy + Clone', as that's redundant. Therefore, we keep track of a separate
     // 'user_env', which only holds the predicates that will actually be displayed to the user.
-    fn evaluate_predicates<'b, 'c>(
+    fn evaluate_predicates(
         &self,
-        infcx: &InferCtxt<'b, 'tcx, 'c>,
+        infcx: &InferCtxt<'_, 'tcx>,
         trait_did: DefId,
-        ty: Ty<'c>,
-        param_env: ty::ParamEnv<'c>,
-        user_env: ty::ParamEnv<'c>,
-        fresh_preds: &mut FxHashSet<ty::Predicate<'c>>,
+        ty: Ty<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
+        user_env: ty::ParamEnv<'tcx>,
+        fresh_preds: &mut FxHashSet<ty::Predicate<'tcx>>,
         only_projections: bool,
-    ) -> Option<(ty::ParamEnv<'c>, ty::ParamEnv<'c>)> {
+    ) -> Option<(ty::ParamEnv<'tcx>, ty::ParamEnv<'tcx>)> {
         let tcx = infcx.tcx;
 
         let mut select = SelectionContext::with_negative(&infcx, true);
@@ -617,20 +617,14 @@ impl AutoTraitFinder<'tcx> {
         }
     }
 
-    fn evaluate_nested_obligations<
-        'b,
-        'c,
-        'd,
-        'cx,
-        T: Iterator<Item = Obligation<'cx, ty::Predicate<'cx>>>,
-    >(
+    fn evaluate_nested_obligations(
         &self,
         ty: Ty<'_>,
-        nested: T,
-        computed_preds: &'b mut FxHashSet<ty::Predicate<'cx>>,
-        fresh_preds: &'b mut FxHashSet<ty::Predicate<'cx>>,
-        predicates: &'b mut VecDeque<ty::PolyTraitPredicate<'cx>>,
-        select: &mut SelectionContext<'c, 'd, 'cx>,
+        nested: impl Iterator<Item = Obligation<'tcx, ty::Predicate<'tcx>>>,
+        computed_preds: &mut FxHashSet<ty::Predicate<'tcx>>,
+        fresh_preds: &mut FxHashSet<ty::Predicate<'tcx>>,
+        predicates: &mut VecDeque<ty::PolyTraitPredicate<'tcx>>,
+        select: &mut SelectionContext<'_, 'tcx>,
         only_projections: bool,
     ) -> bool {
         let dummy_cause = ObligationCause::misc(DUMMY_SP, hir::DUMMY_HIR_ID);
@@ -822,23 +816,23 @@ impl AutoTraitFinder<'tcx> {
         return true;
     }
 
-    pub fn clean_pred<'c, 'd, 'cx>(
+    pub fn clean_pred(
         &self,
-        infcx: &InferCtxt<'c, 'd, 'cx>,
-        p: ty::Predicate<'cx>,
-    ) -> ty::Predicate<'cx> {
+        infcx: &InferCtxt<'_, 'tcx>,
+        p: ty::Predicate<'tcx>,
+    ) -> ty::Predicate<'tcx> {
         infcx.freshen(p)
     }
 }
 
 // Replaces all ReVars in a type with ty::Region's, using the provided map
-pub struct RegionReplacer<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
+pub struct RegionReplacer<'a, 'tcx> {
     vid_to_region: &'a FxHashMap<ty::RegionVid, ty::Region<'tcx>>,
-    tcx: TyCtxt<'gcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
 }
 
-impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionReplacer<'a, 'gcx, 'tcx> {
-    fn tcx<'b>(&'b self) -> TyCtxt<'gcx, 'tcx> {
+impl<'a, 'tcx> TypeFolder<'tcx> for RegionReplacer<'a, 'tcx> {
+    fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
         self.tcx
     }
 
diff --git a/src/librustc/traits/chalk_fulfill.rs b/src/librustc/traits/chalk_fulfill.rs
index a7b5e6cf41b..b1941b876d7 100644
--- a/src/librustc/traits/chalk_fulfill.rs
+++ b/src/librustc/traits/chalk_fulfill.rs
@@ -29,7 +29,7 @@ impl FulfillmentContext<'tcx> {
 }
 
 fn in_environment(
-    infcx: &InferCtxt<'_, 'gcx, 'tcx>,
+    infcx: &InferCtxt<'_, 'tcx>,
     obligation: PredicateObligation<'tcx>
 ) -> InEnvironment<'tcx, PredicateObligation<'tcx>> {
     assert!(!infcx.is_in_snapshot());
@@ -52,7 +52,7 @@ fn in_environment(
 impl TraitEngine<'tcx> for FulfillmentContext<'tcx> {
     fn normalize_projection_type(
         &mut self,
-        infcx: &InferCtxt<'_, 'gcx, 'tcx>,
+        infcx: &InferCtxt<'_, 'tcx>,
         _param_env: ty::ParamEnv<'tcx>,
         projection_ty: ty::ProjectionTy<'tcx>,
         _cause: ObligationCause<'tcx>,
@@ -62,7 +62,7 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> {
 
     fn register_predicate_obligation(
         &mut self,
-        infcx: &InferCtxt<'_, 'gcx, 'tcx>,
+        infcx: &InferCtxt<'_, 'tcx>,
         obligation: PredicateObligation<'tcx>,
     ) {
         self.obligations.insert(in_environment(infcx, obligation));
@@ -70,7 +70,7 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> {
 
     fn select_all_or_error(
         &mut self,
-        infcx: &InferCtxt<'_, 'gcx, 'tcx>,
+        infcx: &InferCtxt<'_, 'tcx>,
     ) -> Result<(), Vec<FulfillmentError<'tcx>>> {
         self.select_where_possible(infcx)?;
 
@@ -89,7 +89,7 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> {
 
     fn select_where_possible(
         &mut self,
-        infcx: &InferCtxt<'_, 'gcx, 'tcx>,
+        infcx: &InferCtxt<'_, 'tcx>,
     ) -> Result<(), Vec<FulfillmentError<'tcx>>> {
         let mut errors = Vec::new();
         let mut next_round = FxHashSet::default();
diff --git a/src/librustc/traits/codegen/mod.rs b/src/librustc/traits/codegen/mod.rs
index f2c17323076..a5d44f5f263 100644
--- a/src/librustc/traits/codegen/mod.rs
+++ b/src/librustc/traits/codegen/mod.rs
@@ -19,7 +19,7 @@ use crate::ty::fold::TypeFoldable;
 /// obligations *could be* resolved if we wanted to.
 /// Assumes that this is run after the entire crate has been successfully type-checked.
 pub fn codegen_fulfill_obligation<'tcx>(
-    ty: TyCtxt<'tcx, 'tcx>,
+    ty: TyCtxt<'tcx>,
     (param_env, trait_ref): (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>),
 ) -> Vtable<'tcx, ()> {
     // Remove any references to regions; this helps improve caching.
@@ -73,7 +73,7 @@ pub fn codegen_fulfill_obligation<'tcx>(
     })
 }
 
-impl<'tcx> TyCtxt<'tcx, 'tcx> {
+impl<'tcx> TyCtxt<'tcx> {
     /// Monomorphizes a type from the AST by first applying the
     /// in-scope substitutions and then normalizing any associated
     /// types.
@@ -115,19 +115,19 @@ impl<'tcx> DepTrackingMapConfig for TraitSelectionCache<'tcx> {
 
 // # Global Cache
 
-pub struct ProjectionCache<'gcx> {
-    data: PhantomData<&'gcx ()>
+pub struct ProjectionCache<'tcx> {
+    data: PhantomData<&'tcx ()>
 }
 
-impl<'gcx> DepTrackingMapConfig for ProjectionCache<'gcx> {
-    type Key = Ty<'gcx>;
-    type Value = Ty<'gcx>;
+impl<'tcx> DepTrackingMapConfig for ProjectionCache<'tcx> {
+    type Key = Ty<'tcx>;
+    type Value = Ty<'tcx>;
     fn to_dep_kind() -> DepKind {
         DepKind::TraitSelect
     }
 }
 
-impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     /// 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
@@ -141,7 +141,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                                         fulfill_cx: &mut FulfillmentContext<'tcx>,
                                         result: &T)
                                         -> T::Lifted
-        where T: TypeFoldable<'tcx> + ty::Lift<'gcx>
+        where T: TypeFoldable<'tcx> + ty::Lift<'tcx>
     {
         debug!("drain_fulfillment_cx_or_panic()");
 
diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs
index 83f97963641..949cc62f62c 100644
--- a/src/librustc/traits/coherence.rs
+++ b/src/librustc/traits/coherence.rs
@@ -48,8 +48,8 @@ pub fn add_placeholder_note(err: &mut errors::DiagnosticBuilder<'_>) {
 /// If there are types that satisfy both impls, invokes `on_overlap`
 /// with a suitably-freshened `ImplHeader` with those types
 /// substituted. Otherwise, invokes `no_overlap`.
-pub fn overlapping_impls<'gcx, F1, F2, R>(
-    tcx: TyCtxt<'gcx, 'gcx>,
+pub fn overlapping_impls<'tcx, F1, F2, R>(
+    tcx: TyCtxt<'tcx>,
     impl1_def_id: DefId,
     impl2_def_id: DefId,
     intercrate_mode: IntercrateMode,
@@ -87,7 +87,7 @@ where
     })
 }
 
-fn with_fresh_ty_vars<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
+fn with_fresh_ty_vars<'cx, 'tcx>(selcx: &mut SelectionContext<'cx, 'tcx>,
                                        param_env: ty::ParamEnv<'tcx>,
                                        impl_def_id: DefId)
                                        -> ty::ImplHeader<'tcx>
@@ -111,8 +111,8 @@ fn with_fresh_ty_vars<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, '
 
 /// Can both impl `a` and impl `b` be satisfied by a common type (including
 /// where-clauses)? If so, returns an `ImplHeader` that unifies the two impls.
-fn overlap<'cx, 'gcx, 'tcx>(
-    selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
+fn overlap<'cx, 'tcx>(
+    selcx: &mut SelectionContext<'cx, 'tcx>,
     a_def_id: DefId,
     b_def_id: DefId,
 ) -> Option<OverlapResult<'tcx>> {
@@ -122,7 +122,7 @@ fn overlap<'cx, 'gcx, 'tcx>(
 }
 
 fn overlap_within_probe(
-    selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
+    selcx: &mut SelectionContext<'cx, 'tcx>,
     a_def_id: DefId,
     b_def_id: DefId,
     snapshot: &CombinedSnapshot<'_, 'tcx>,
@@ -183,8 +183,8 @@ fn overlap_within_probe(
     Some(OverlapResult { impl_header, intercrate_ambiguity_causes, involves_placeholder })
 }
 
-pub fn trait_ref_is_knowable<'gcx, 'tcx>(
-    tcx: TyCtxt<'gcx, 'tcx>,
+pub fn trait_ref_is_knowable<'tcx>(
+    tcx: TyCtxt<'tcx>,
     trait_ref: ty::TraitRef<'tcx>,
 ) -> Option<Conflict> {
     debug!("trait_ref_is_knowable(trait_ref={:?})", trait_ref);
@@ -229,8 +229,8 @@ pub fn trait_ref_is_knowable<'gcx, 'tcx>(
     }
 }
 
-pub fn trait_ref_is_local_or_fundamental<'gcx, 'tcx>(
-    tcx: TyCtxt<'gcx, 'tcx>,
+pub fn trait_ref_is_local_or_fundamental<'tcx>(
+    tcx: TyCtxt<'tcx>,
     trait_ref: ty::TraitRef<'tcx>,
 ) -> bool {
     trait_ref.def_id.krate == LOCAL_CRATE || tcx.has_attr(trait_ref.def_id, sym::fundamental)
@@ -247,8 +247,8 @@ pub enum OrphanCheckErr<'tcx> {
 ///
 /// 1. All type parameters in `Self` must be "covered" by some local type constructor.
 /// 2. Some local type must appear in `Self`.
-pub fn orphan_check<'gcx, 'tcx>(
-    tcx: TyCtxt<'gcx, 'tcx>,
+pub fn orphan_check<'tcx>(
+    tcx: TyCtxt<'tcx>,
     impl_def_id: DefId,
 ) -> Result<(), OrphanCheckErr<'tcx>> {
     debug!("orphan_check({:?})", impl_def_id);
@@ -355,7 +355,7 @@ pub fn orphan_check<'gcx, 'tcx>(
 /// Note that this function is never called for types that have both type
 /// parameters and inference variables.
 fn orphan_check_trait_ref<'tcx>(
-    tcx: TyCtxt<'_, '_>,
+    tcx: TyCtxt<'_>,
     trait_ref: ty::TraitRef<'tcx>,
     in_crate: InCrate,
 ) -> Result<(), OrphanCheckErr<'tcx>> {
@@ -431,7 +431,7 @@ fn orphan_check_trait_ref<'tcx>(
     }
 }
 
-fn uncovered_tys<'tcx>(tcx: TyCtxt<'_, '_>, ty: Ty<'tcx>, in_crate: InCrate) -> Vec<Ty<'tcx>> {
+fn uncovered_tys<'tcx>(tcx: TyCtxt<'_>, ty: Ty<'tcx>, in_crate: InCrate) -> Vec<Ty<'tcx>> {
     if ty_is_local_constructor(ty, in_crate) {
         vec![]
     } else if fundamental_ty(ty) {
@@ -450,7 +450,7 @@ fn is_possibly_remote_type(ty: Ty<'_>, _in_crate: InCrate) -> bool {
     }
 }
 
-fn ty_is_local(tcx: TyCtxt<'_, '_>, ty: Ty<'_>, in_crate: InCrate) -> bool {
+fn ty_is_local(tcx: TyCtxt<'_>, ty: Ty<'_>, in_crate: InCrate) -> bool {
     ty_is_local_constructor(ty, in_crate) ||
         fundamental_ty(ty) && ty.walk_shallow().any(|t| ty_is_local(tcx, t, in_crate))
 }
diff --git a/src/librustc/traits/engine.rs b/src/librustc/traits/engine.rs
index e43ca8e7e0a..b96126c7b67 100644
--- a/src/librustc/traits/engine.rs
+++ b/src/librustc/traits/engine.rs
@@ -9,7 +9,7 @@ use super::{ObligationCause, PredicateObligation};
 pub trait TraitEngine<'tcx>: 'tcx {
     fn normalize_projection_type(
         &mut self,
-        infcx: &InferCtxt<'_, 'gcx, 'tcx>,
+        infcx: &InferCtxt<'_, 'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         projection_ty: ty::ProjectionTy<'tcx>,
         cause: ObligationCause<'tcx>,
@@ -20,7 +20,7 @@ pub trait TraitEngine<'tcx>: 'tcx {
     /// parameters (except for `Self`).
     fn register_bound(
         &mut self,
-        infcx: &InferCtxt<'_, 'gcx, 'tcx>,
+        infcx: &InferCtxt<'_, 'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         ty: Ty<'tcx>,
         def_id: DefId,
@@ -40,18 +40,18 @@ pub trait TraitEngine<'tcx>: 'tcx {
 
     fn register_predicate_obligation(
         &mut self,
-        infcx: &InferCtxt<'_, 'gcx, 'tcx>,
+        infcx: &InferCtxt<'_, 'tcx>,
         obligation: PredicateObligation<'tcx>,
     );
 
     fn select_all_or_error(
         &mut self,
-        infcx: &InferCtxt<'_, 'gcx, 'tcx>,
+        infcx: &InferCtxt<'_, 'tcx>,
     ) -> Result<(), Vec<FulfillmentError<'tcx>>>;
 
     fn select_where_possible(
         &mut self,
-        infcx: &InferCtxt<'_, 'gcx, 'tcx>,
+        infcx: &InferCtxt<'_, 'tcx>,
     ) -> Result<(), Vec<FulfillmentError<'tcx>>>;
 
     fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>>;
@@ -60,7 +60,7 @@ pub trait TraitEngine<'tcx>: 'tcx {
 pub trait TraitEngineExt<'tcx> {
     fn register_predicate_obligations(
         &mut self,
-        infcx: &InferCtxt<'_, 'gcx, 'tcx>,
+        infcx: &InferCtxt<'_, 'tcx>,
         obligations: impl IntoIterator<Item = PredicateObligation<'tcx>>,
     );
 }
@@ -68,7 +68,7 @@ pub trait TraitEngineExt<'tcx> {
 impl<T: ?Sized + TraitEngine<'tcx>> TraitEngineExt<'tcx> for T {
     fn register_predicate_obligations(
         &mut self,
-        infcx: &InferCtxt<'_, 'gcx, 'tcx>,
+        infcx: &InferCtxt<'_, 'tcx>,
         obligations: impl IntoIterator<Item = PredicateObligation<'tcx>>,
     ) {
         for obligation in obligations {
@@ -78,7 +78,7 @@ impl<T: ?Sized + TraitEngine<'tcx>> TraitEngineExt<'tcx> for T {
 }
 
 impl dyn TraitEngine<'tcx> {
-    pub fn new(tcx: TyCtxt<'_, 'tcx>) -> Box<Self> {
+    pub fn new(tcx: TyCtxt<'tcx>) -> Box<Self> {
         if tcx.sess.opts.debugging_opts.chalk {
             Box::new(ChalkFulfillmentContext::new())
         } else {
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 1fb325ae056..99ced254dca 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -38,7 +38,7 @@ use syntax::ast;
 use syntax::symbol::sym;
 use syntax_pos::{DUMMY_SP, Span, ExpnInfo, ExpnFormat};
 
-impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     pub fn report_fulfillment_errors(&self,
                                      errors: &[FulfillmentError<'tcx>],
                                      body_id: Option<hir::BodyId>,
@@ -1249,8 +1249,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         expected_ref: ty::PolyTraitRef<'tcx>,
         found: ty::PolyTraitRef<'tcx>,
     ) -> DiagnosticBuilder<'tcx> {
-        fn build_fn_sig_string<'gcx, 'tcx>(
-            tcx: TyCtxt<'gcx, 'tcx>,
+        fn build_fn_sig_string<'tcx>(
+            tcx: TyCtxt<'tcx>,
             trait_ref: &ty::TraitRef<'tcx>,
         ) -> String {
             let inputs = trait_ref.substs.type_at(1);
@@ -1296,7 +1296,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     }
 }
 
-impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
+impl<'tcx> TyCtxt<'tcx> {
     pub fn recursive_type_with_infinite_size_error(self,
                                                    type_def_id: DefId)
                                                    -> DiagnosticBuilder<'tcx>
@@ -1342,7 +1342,7 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
     }
 }
 
-impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>,
                               body_id: Option<hir::BodyId>) {
         // Unable to successfully determine, probably means
@@ -1454,13 +1454,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         param_env: ty::ParamEnv<'tcx>,
         pred: ty::PolyTraitRef<'tcx>,
     ) -> bool {
-        struct ParamToVarFolder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
-            infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
+        struct ParamToVarFolder<'a, 'tcx: 'a> {
+            infcx: &'a InferCtxt<'a, 'tcx>,
             var_map: FxHashMap<Ty<'tcx>, Ty<'tcx>>
         }
 
-        impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for ParamToVarFolder<'a, 'gcx, 'tcx> {
-            fn tcx<'b>(&'b self) -> TyCtxt<'gcx, 'tcx> { self.infcx.tcx }
+        impl<'a, 'tcx> TypeFolder<'tcx> for ParamToVarFolder<'a, 'tcx> {
+            fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.infcx.tcx }
 
             fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
                 if let ty::Param(ty::ParamTy {name, .. }) = ty.sty {
diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs
index c7943d16885..eaad696ba39 100644
--- a/src/librustc/traits/fulfill.rs
+++ b/src/librustc/traits/fulfill.rs
@@ -68,7 +68,7 @@ pub struct PendingPredicateObligation<'tcx> {
     pub stalled_on: Vec<Ty<'tcx>>,
 }
 
-impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
+impl<'a, 'tcx> FulfillmentContext<'tcx> {
     /// Creates a new fulfillment context.
     pub fn new() -> FulfillmentContext<'tcx> {
         FulfillmentContext {
@@ -95,7 +95,7 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
     }
 
     /// Attempts to select obligations using `selcx`.
-    fn select(&mut self, selcx: &mut SelectionContext<'a, 'gcx, 'tcx>)
+    fn select(&mut self, selcx: &mut SelectionContext<'a, 'tcx>)
               -> Result<(), Vec<FulfillmentError<'tcx>>> {
         debug!("select(obligation-forest-size={})", self.predicates.len());
 
@@ -143,8 +143,8 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
     /// `SomeTrait` or a where-clause that lets us unify `$0` with
     /// something concrete. If this fails, we'll unify `$0` with
     /// `projection_ty` again.
-    fn normalize_projection_type<'a, 'gcx>(&mut self,
-                                 infcx: &InferCtxt<'a, 'gcx, 'tcx>,
+    fn normalize_projection_type(&mut self,
+                                 infcx: &InferCtxt<'_, 'tcx>,
                                  param_env: ty::ParamEnv<'tcx>,
                                  projection_ty: ty::ProjectionTy<'tcx>,
                                  cause: ObligationCause<'tcx>)
@@ -172,8 +172,8 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
         normalized_ty
     }
 
-    fn register_predicate_obligation<'a, 'gcx>(&mut self,
-                                     infcx: &InferCtxt<'a, 'gcx, 'tcx>,
+    fn register_predicate_obligation(&mut self,
+                                     infcx: &InferCtxt<'_, 'tcx>,
                                      obligation: PredicateObligation<'tcx>)
     {
         // this helps to reduce duplicate errors, as well as making
@@ -190,9 +190,9 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
         });
     }
 
-    fn select_all_or_error<'a, 'gcx>(
+    fn select_all_or_error(
         &mut self,
-        infcx: &InferCtxt<'a, 'gcx, 'tcx>
+        infcx: &InferCtxt<'_, 'tcx>
     ) -> Result<(),Vec<FulfillmentError<'tcx>>>
     {
         self.select_where_possible(infcx)?;
@@ -209,8 +209,8 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
         }
     }
 
-    fn select_where_possible<'a, 'gcx>(&mut self,
-                             infcx: &InferCtxt<'a, 'gcx, 'tcx>)
+    fn select_where_possible(&mut self,
+                             infcx: &InferCtxt<'_, 'tcx>)
                              -> Result<(),Vec<FulfillmentError<'tcx>>>
     {
         let mut selcx = SelectionContext::new(infcx);
@@ -222,8 +222,8 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
     }
 }
 
-struct FulfillProcessor<'a, 'b: 'a, 'gcx: 'tcx, 'tcx: 'b> {
-    selcx: &'a mut SelectionContext<'b, 'gcx, 'tcx>,
+struct FulfillProcessor<'a, 'b: 'a, 'tcx: 'b> {
+    selcx: &'a mut SelectionContext<'b, 'tcx>,
     register_region_obligations: bool
 }
 
@@ -234,7 +234,7 @@ fn mk_pending(os: Vec<PredicateObligation<'tcx>>) -> Vec<PendingPredicateObligat
     }).collect()
 }
 
-impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx, 'tcx> {
+impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
     type Obligation = PendingPredicateObligation<'tcx>;
     type Error = FulfillmentErrorCode<'tcx>;
 
@@ -514,7 +514,7 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx,
 }
 
 /// Returns the set of type variables contained in a trait ref
-fn trait_ref_type_vars<'a, 'gcx, 'tcx>(selcx: &mut SelectionContext<'a, 'gcx, 'tcx>,
+fn trait_ref_type_vars<'a, 'tcx>(selcx: &mut SelectionContext<'a, 'tcx>,
                                        t: ty::PolyTraitRef<'tcx>) -> Vec<Ty<'tcx>>
 {
     t.skip_binder() // ok b/c this check doesn't care about regions
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index 01be8de172c..83162a1e12c 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -140,7 +140,7 @@ pub struct ObligationCause<'tcx> {
 }
 
 impl<'tcx> ObligationCause<'tcx> {
-    pub fn span<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Span {
+    pub fn span(&self, tcx: TyCtxt<'tcx>) -> Span {
         match self.code {
             ObligationCauseCode::CompareImplMethodObligation { .. } |
             ObligationCauseCode::MainFunctionType |
@@ -363,9 +363,9 @@ impl<'tcx> DomainGoal<'tcx> {
 }
 
 impl<'tcx> GoalKind<'tcx> {
-    pub fn from_poly_domain_goal<'gcx>(
+    pub fn from_poly_domain_goal(
         domain_goal: PolyDomainGoal<'tcx>,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
     ) -> GoalKind<'tcx> {
         match domain_goal.no_bound_vars() {
             Some(p) => p.into_goal(),
@@ -643,8 +643,8 @@ pub fn predicates_for_generics<'tcx>(cause: ObligationCause<'tcx>,
 /// `bound` or is not known to meet bound (note that this is
 /// conservative towards *no impl*, which is the opposite of the
 /// `evaluate` methods).
-pub fn type_known_to_meet_bound_modulo_regions<'a, 'gcx, 'tcx>(
-    infcx: &InferCtxt<'a, 'gcx, 'tcx>,
+pub fn type_known_to_meet_bound_modulo_regions<'a, 'tcx>(
+    infcx: &InferCtxt<'a, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     ty: Ty<'tcx>,
     def_id: DefId,
@@ -711,7 +711,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'gcx, 'tcx>(
 }
 
 fn do_normalize_predicates<'tcx>(
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     region_context: DefId,
     cause: ObligationCause<'tcx>,
     elaborated_env: ty::ParamEnv<'tcx>,
@@ -796,7 +796,7 @@ fn do_normalize_predicates<'tcx>(
 // FIXME: this is gonna need to be removed ...
 /// Normalizes the parameter environment, reporting errors if they occur.
 pub fn normalize_param_env_or_error<'tcx>(
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     region_context: DefId,
     unnormalized_env: ty::ParamEnv<'tcx>,
     cause: ObligationCause<'tcx>,
@@ -904,8 +904,8 @@ pub fn normalize_param_env_or_error<'tcx>(
     )
 }
 
-pub fn fully_normalize<'a, 'gcx, 'tcx, T>(
-    infcx: &InferCtxt<'a, 'gcx, 'tcx>,
+pub fn fully_normalize<'a, 'tcx, T>(
+    infcx: &InferCtxt<'a, 'tcx>,
     mut fulfill_cx: FulfillmentContext<'tcx>,
     cause: ObligationCause<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
@@ -937,7 +937,7 @@ pub fn fully_normalize<'a, 'gcx, 'tcx, T>(
 /// encountered an error or one of the predicates did not hold. Used
 /// when creating vtables to check for unsatisfiable methods.
 fn normalize_and_test_predicates<'tcx>(
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     predicates: Vec<ty::Predicate<'tcx>>,
 ) -> bool {
     debug!("normalize_and_test_predicates(predicates={:?})",
@@ -966,7 +966,7 @@ fn normalize_and_test_predicates<'tcx>(
 }
 
 fn substitute_normalize_and_test_predicates<'tcx>(
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     key: (DefId, SubstsRef<'tcx>),
 ) -> bool {
     debug!("substitute_normalize_and_test_predicates(key={:?})",
@@ -984,7 +984,7 @@ fn substitute_normalize_and_test_predicates<'tcx>(
 /// that come from `trait_ref`, including its supertraits.
 #[inline] // FIXME(#35870): avoid closures being unexported due to `impl Trait`.
 fn vtable_methods<'tcx>(
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     trait_ref: ty::PolyTraitRef<'tcx>,
 ) -> &'tcx [Option<(DefId, SubstsRef<'tcx>)>] {
     debug!("vtable_methods({:?})", trait_ref);
@@ -1185,7 +1185,7 @@ pub trait ExClauseFold<'tcx>
 where
     Self: chalk_engine::context::Context + Clone,
 {
-    fn fold_ex_clause_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(
+    fn fold_ex_clause_with<F: TypeFolder<'tcx>>(
         ex_clause: &chalk_engine::ExClause<Self>,
         folder: &mut F,
     ) -> chalk_engine::ExClause<Self>;
@@ -1204,18 +1204,18 @@ where
     type LiftedDelayedLiteral: Debug + 'tcx;
     type LiftedLiteral: Debug + 'tcx;
 
-    fn lift_ex_clause_to_tcx<'gcx>(
+    fn lift_ex_clause_to_tcx(
         ex_clause: &chalk_engine::ExClause<Self>,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
     ) -> Option<Self::LiftedExClause>;
 
-    fn lift_delayed_literal_to_tcx<'gcx>(
+    fn lift_delayed_literal_to_tcx(
         ex_clause: &chalk_engine::DelayedLiteral<Self>,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
     ) -> Option<Self::LiftedDelayedLiteral>;
 
-    fn lift_literal_to_tcx<'gcx>(
+    fn lift_literal_to_tcx(
         ex_clause: &chalk_engine::Literal<Self>,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
     ) -> Option<Self::LiftedLiteral>;
 }
diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs
index 01b81b182af..cfd5cfa897d 100644
--- a/src/librustc/traits/object_safety.rs
+++ b/src/librustc/traits/object_safety.rs
@@ -83,7 +83,7 @@ pub enum MethodViolationCode {
     UndispatchableReceiver,
 }
 
-impl<'tcx> TyCtxt<'tcx, 'tcx> {
+impl<'tcx> TyCtxt<'tcx> {
     /// Returns the object safety violations that affect
     /// astconv -- currently, `Self` in supertraits. This is needed
     /// because `object_safety_violations` can't be used during
@@ -702,6 +702,6 @@ impl<'tcx> TyCtxt<'tcx, 'tcx> {
     }
 }
 
-pub(super) fn is_object_safe_provider<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, trait_def_id: DefId) -> bool {
+pub(super) fn is_object_safe_provider<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId) -> bool {
     tcx.object_safety_violations(trait_def_id).is_empty()
 }
diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs
index fe190db5fdb..0a42b6b46f2 100644
--- a/src/librustc/traits/on_unimplemented.rs
+++ b/src/librustc/traits/on_unimplemented.rs
@@ -36,7 +36,7 @@ impl OnUnimplementedNote {
 }
 
 fn parse_error(
-    tcx: TyCtxt<'_, '_>,
+    tcx: TyCtxt<'_>,
     span: Span,
     message: &str,
     label: &str,
@@ -52,9 +52,9 @@ fn parse_error(
     ErrorReported
 }
 
-impl<'gcx, 'tcx> OnUnimplementedDirective {
+impl<'tcx> OnUnimplementedDirective {
     fn parse(
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         trait_def_id: DefId,
         items: &[NestedMetaItem],
         span: Span,
@@ -134,7 +134,7 @@ impl<'gcx, 'tcx> OnUnimplementedDirective {
     }
 
     pub fn of_item(
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         trait_def_id: DefId,
         impl_def_id: DefId,
     ) -> Result<Option<Self>, ErrorReported> {
@@ -166,7 +166,7 @@ impl<'gcx, 'tcx> OnUnimplementedDirective {
 
     pub fn evaluate(
         &self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         trait_ref: ty::TraitRef<'tcx>,
         options: &[(Symbol, Option<String>)],
     ) -> OnUnimplementedNote {
@@ -214,9 +214,9 @@ impl<'gcx, 'tcx> OnUnimplementedDirective {
     }
 }
 
-impl<'gcx, 'tcx> OnUnimplementedFormatString {
+impl<'tcx> OnUnimplementedFormatString {
     fn try_parse(
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         trait_def_id: DefId,
         from: LocalInternedString,
         err_sp: Span,
@@ -228,7 +228,7 @@ impl<'gcx, 'tcx> OnUnimplementedFormatString {
 
     fn verify(
         &self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         trait_def_id: DefId,
         span: Span,
     ) -> Result<(), ErrorReported> {
@@ -274,7 +274,7 @@ impl<'gcx, 'tcx> OnUnimplementedFormatString {
 
     pub fn format(
         &self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         trait_ref: ty::TraitRef<'tcx>,
         options: &FxHashMap<Symbol, String>,
     ) -> String {
diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs
index e997e4d9c31..75dd4d53b36 100644
--- a/src/librustc/traits/project.rs
+++ b/src/librustc/traits/project.rs
@@ -183,8 +183,8 @@ impl<'tcx> ProjectionTyCandidateSet<'tcx> {
 ///
 /// If successful, this may result in additional obligations. Also returns
 /// the projection cache key used to track these additional obligations.
-pub fn poly_project_and_unify_type<'cx, 'gcx, 'tcx>(
-    selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
+pub fn poly_project_and_unify_type<'cx, 'tcx>(
+    selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &PolyProjectionObligation<'tcx>)
     -> Result<Option<Vec<PredicateObligation<'tcx>>>,
               MismatchedProjectionTypes<'tcx>>
@@ -210,8 +210,8 @@ pub fn poly_project_and_unify_type<'cx, 'gcx, 'tcx>(
 ///     <T as Trait>::U == V
 ///
 /// If successful, this may result in additional obligations.
-fn project_and_unify_type<'cx, 'gcx, 'tcx>(
-    selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
+fn project_and_unify_type<'cx, 'tcx>(
+    selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &ProjectionObligation<'tcx>)
     -> Result<Option<Vec<PredicateObligation<'tcx>>>,
               MismatchedProjectionTypes<'tcx>>
@@ -253,7 +253,7 @@ fn project_and_unify_type<'cx, 'gcx, 'tcx>(
 /// them with a fully resolved type where possible. The return value
 /// combines the normalized result and any additional obligations that
 /// were incurred as result.
-pub fn normalize<'a, 'b, 'gcx, 'tcx, T>(selcx: &'a mut SelectionContext<'b, 'gcx, 'tcx>,
+pub fn normalize<'a, 'b, 'tcx, T>(selcx: &'a mut SelectionContext<'b, 'tcx>,
                                         param_env: ty::ParamEnv<'tcx>,
                                         cause: ObligationCause<'tcx>,
                                         value: &T)
@@ -264,8 +264,8 @@ pub fn normalize<'a, 'b, 'gcx, 'tcx, T>(selcx: &'a mut SelectionContext<'b, 'gcx
 }
 
 /// As `normalize`, but with a custom depth.
-pub fn normalize_with_depth<'a, 'b, 'gcx, 'tcx, T>(
-    selcx: &'a mut SelectionContext<'b, 'gcx, 'tcx>,
+pub fn normalize_with_depth<'a, 'b, 'tcx, T>(
+    selcx: &'a mut SelectionContext<'b, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     cause: ObligationCause<'tcx>,
     depth: usize,
@@ -287,20 +287,20 @@ pub fn normalize_with_depth<'a, 'b, 'gcx, 'tcx, T>(
     }
 }
 
-struct AssocTypeNormalizer<'a, 'b: 'a, 'gcx: 'b+'tcx, 'tcx: 'b> {
-    selcx: &'a mut SelectionContext<'b, 'gcx, 'tcx>,
+struct AssocTypeNormalizer<'a, 'b: 'a, 'tcx: 'b> {
+    selcx: &'a mut SelectionContext<'b, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     cause: ObligationCause<'tcx>,
     obligations: Vec<PredicateObligation<'tcx>>,
     depth: usize,
 }
 
-impl<'a, 'b, 'gcx, 'tcx> AssocTypeNormalizer<'a, 'b, 'gcx, 'tcx> {
-    fn new(selcx: &'a mut SelectionContext<'b, 'gcx, 'tcx>,
+impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
+    fn new(selcx: &'a mut SelectionContext<'b, 'tcx>,
            param_env: ty::ParamEnv<'tcx>,
            cause: ObligationCause<'tcx>,
            depth: usize)
-           -> AssocTypeNormalizer<'a, 'b, 'gcx, 'tcx>
+           -> AssocTypeNormalizer<'a, 'b, 'tcx>
     {
         AssocTypeNormalizer {
             selcx,
@@ -322,8 +322,8 @@ impl<'a, 'b, 'gcx, 'tcx> AssocTypeNormalizer<'a, 'b, 'gcx, 'tcx> {
     }
 }
 
-impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssocTypeNormalizer<'a, 'b, 'gcx, 'tcx> {
-    fn tcx<'c>(&'c self) -> TyCtxt<'gcx, 'tcx> {
+impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
+    fn tcx<'c>(&'c self) -> TyCtxt<'tcx> {
         self.selcx.tcx()
     }
 
@@ -456,8 +456,8 @@ impl<'tcx,T> Normalized<'tcx,T> {
 /// there are unresolved type variables in the projection, we will
 /// substitute a fresh type variable `$X` and generate a new
 /// obligation `<T as Trait>::Item == $X` for later.
-pub fn normalize_projection_type<'a, 'b, 'gcx, 'tcx>(
-    selcx: &'a mut SelectionContext<'b, 'gcx, 'tcx>,
+pub fn normalize_projection_type<'a, 'b, 'tcx>(
+    selcx: &'a mut SelectionContext<'b, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     projection_ty: ty::ProjectionTy<'tcx>,
     cause: ObligationCause<'tcx>,
@@ -501,8 +501,8 @@ pub fn normalize_projection_type<'a, 'b, 'gcx, 'tcx>(
 /// often immediately appended to another obligations vector. So now this
 /// function takes an obligations vector and appends to it directly, which is
 /// slightly uglier but avoids the need for an extra short-lived allocation.
-fn opt_normalize_projection_type<'a, 'b, 'gcx, 'tcx>(
-    selcx: &'a mut SelectionContext<'b, 'gcx, 'tcx>,
+fn opt_normalize_projection_type<'a, 'b, 'tcx>(
+    selcx: &'a mut SelectionContext<'b, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     projection_ty: ty::ProjectionTy<'tcx>,
     cause: ObligationCause<'tcx>,
@@ -705,7 +705,7 @@ fn opt_normalize_projection_type<'a, 'b, 'gcx, 'tcx>(
 /// If there are unresolved type variables, then we need to include
 /// any subobligations that bind them, at least until those type
 /// variables are fully resolved.
-fn prune_cache_value_obligations<'a, 'gcx, 'tcx>(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
+fn prune_cache_value_obligations<'a, 'tcx>(infcx: &'a InferCtxt<'a, 'tcx>,
                                                  result: &NormalizedTy<'tcx>)
                                                  -> NormalizedTy<'tcx> {
     if infcx.unresolved_type_vars(&result.value).is_none() {
@@ -763,8 +763,8 @@ fn prune_cache_value_obligations<'a, 'gcx, 'tcx>(infcx: &'a InferCtxt<'a, 'gcx,
 /// that may yet turn out to be wrong. This *may* lead to some sort
 /// of trouble, though we don't have a concrete example of how that
 /// can occur yet. But it seems risky at best.
-fn get_paranoid_cache_value_obligation<'a, 'gcx, 'tcx>(
-    infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
+fn get_paranoid_cache_value_obligation<'a, 'tcx>(
+    infcx: &'a InferCtxt<'a, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     projection_ty: ty::ProjectionTy<'tcx>,
     cause: ObligationCause<'tcx>,
@@ -799,7 +799,7 @@ fn get_paranoid_cache_value_obligation<'a, 'gcx, 'tcx>(
 /// an error for this obligation, but we legitimately should not,
 /// because it contains `[type error]`. Yuck! (See issue #29857 for
 /// one case where this arose.)
-fn normalize_to_error<'a, 'gcx, 'tcx>(selcx: &mut SelectionContext<'a, 'gcx, 'tcx>,
+fn normalize_to_error<'a, 'tcx>(selcx: &mut SelectionContext<'a, 'tcx>,
                                       param_env: ty::ParamEnv<'tcx>,
                                       projection_ty: ty::ProjectionTy<'tcx>,
                                       cause: ObligationCause<'tcx>,
@@ -836,7 +836,7 @@ struct Progress<'tcx> {
 }
 
 impl<'tcx> Progress<'tcx> {
-    fn error<'gcx>(tcx: TyCtxt<'gcx, 'tcx>) -> Self {
+    fn error(tcx: TyCtxt<'tcx>) -> Self {
         Progress {
             ty: tcx.types.err,
             obligations: vec![],
@@ -861,8 +861,8 @@ impl<'tcx> Progress<'tcx> {
 ///
 /// IMPORTANT:
 /// - `obligation` must be fully normalized
-fn project_type<'cx, 'gcx, 'tcx>(
-    selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
+fn project_type<'cx, 'tcx>(
+    selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &ProjectionTyObligation<'tcx>)
     -> Result<ProjectedTy<'tcx>, ProjectionTyError<'tcx>>
 {
@@ -925,8 +925,8 @@ fn project_type<'cx, 'gcx, 'tcx>(
 /// The first thing we have to do is scan through the parameter
 /// environment to see whether there are any projection predicates
 /// there that can answer this question.
-fn assemble_candidates_from_param_env<'cx, 'gcx, 'tcx>(
-    selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
+fn assemble_candidates_from_param_env<'cx, 'tcx>(
+    selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &ProjectionTyObligation<'tcx>,
     obligation_trait_ref: &ty::TraitRef<'tcx>,
     candidate_set: &mut ProjectionTyCandidateSet<'tcx>)
@@ -950,8 +950,8 @@ fn assemble_candidates_from_param_env<'cx, 'gcx, 'tcx>(
 /// ```
 ///
 /// Here, for example, we could conclude that the result is `i32`.
-fn assemble_candidates_from_trait_def<'cx, 'gcx, 'tcx>(
-    selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
+fn assemble_candidates_from_trait_def<'cx, 'tcx>(
+    selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &ProjectionTyObligation<'tcx>,
     obligation_trait_ref: &ty::TraitRef<'tcx>,
     candidate_set: &mut ProjectionTyCandidateSet<'tcx>)
@@ -986,8 +986,8 @@ fn assemble_candidates_from_trait_def<'cx, 'gcx, 'tcx>(
                                         bounds)
 }
 
-fn assemble_candidates_from_predicates<'cx, 'gcx, 'tcx, I>(
-    selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
+fn assemble_candidates_from_predicates<'cx, 'tcx, I>(
+    selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &ProjectionTyObligation<'tcx>,
     obligation_trait_ref: &ty::TraitRef<'tcx>,
     candidate_set: &mut ProjectionTyCandidateSet<'tcx>,
@@ -1029,8 +1029,8 @@ fn assemble_candidates_from_predicates<'cx, 'gcx, 'tcx, I>(
     }
 }
 
-fn assemble_candidates_from_impls<'cx, 'gcx, 'tcx>(
-    selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
+fn assemble_candidates_from_impls<'cx, 'tcx>(
+    selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &ProjectionTyObligation<'tcx>,
     obligation_trait_ref: &ty::TraitRef<'tcx>,
     candidate_set: &mut ProjectionTyCandidateSet<'tcx>)
@@ -1177,8 +1177,8 @@ fn assemble_candidates_from_impls<'cx, 'gcx, 'tcx>(
     });
 }
 
-fn confirm_candidate<'cx, 'gcx, 'tcx>(
-    selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
+fn confirm_candidate<'cx, 'tcx>(
+    selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &ProjectionTyObligation<'tcx>,
     obligation_trait_ref: &ty::TraitRef<'tcx>,
     candidate: ProjectionTyCandidate<'tcx>)
@@ -1200,8 +1200,8 @@ fn confirm_candidate<'cx, 'gcx, 'tcx>(
     }
 }
 
-fn confirm_select_candidate<'cx, 'gcx, 'tcx>(
-    selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
+fn confirm_select_candidate<'cx, 'tcx>(
+    selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &ProjectionTyObligation<'tcx>,
     obligation_trait_ref: &ty::TraitRef<'tcx>,
     vtable: Selection<'tcx>)
@@ -1230,8 +1230,8 @@ fn confirm_select_candidate<'cx, 'gcx, 'tcx>(
     }
 }
 
-fn confirm_object_candidate<'cx, 'gcx, 'tcx>(
-    selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
+fn confirm_object_candidate<'cx, 'tcx>(
+    selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation:  &ProjectionTyObligation<'tcx>,
     obligation_trait_ref: &ty::TraitRef<'tcx>)
     -> Progress<'tcx>
@@ -1295,8 +1295,8 @@ fn confirm_object_candidate<'cx, 'gcx, 'tcx>(
     confirm_param_env_candidate(selcx, obligation, env_predicate)
 }
 
-fn confirm_generator_candidate<'cx, 'gcx, 'tcx>(
-    selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
+fn confirm_generator_candidate<'cx, 'tcx>(
+    selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &ProjectionTyObligation<'tcx>,
     vtable: VtableGeneratorData<'tcx, PredicateObligation<'tcx>>)
     -> Progress<'tcx>
@@ -1348,8 +1348,8 @@ fn confirm_generator_candidate<'cx, 'gcx, 'tcx>(
         .with_addl_obligations(obligations)
 }
 
-fn confirm_fn_pointer_candidate<'cx, 'gcx, 'tcx>(
-    selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
+fn confirm_fn_pointer_candidate<'cx, 'tcx>(
+    selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &ProjectionTyObligation<'tcx>,
     fn_pointer_vtable: VtableFnPointerData<'tcx, PredicateObligation<'tcx>>)
     -> Progress<'tcx>
@@ -1370,8 +1370,8 @@ fn confirm_fn_pointer_candidate<'cx, 'gcx, 'tcx>(
         .with_addl_obligations(obligations)
 }
 
-fn confirm_closure_candidate<'cx, 'gcx, 'tcx>(
-    selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
+fn confirm_closure_candidate<'cx, 'tcx>(
+    selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &ProjectionTyObligation<'tcx>,
     vtable: VtableClosureData<'tcx, PredicateObligation<'tcx>>)
     -> Progress<'tcx>
@@ -1402,8 +1402,8 @@ fn confirm_closure_candidate<'cx, 'gcx, 'tcx>(
         .with_addl_obligations(obligations)
 }
 
-fn confirm_callable_candidate<'cx, 'gcx, 'tcx>(
-    selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
+fn confirm_callable_candidate<'cx, 'tcx>(
+    selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &ProjectionTyObligation<'tcx>,
     fn_sig: ty::PolyFnSig<'tcx>,
     flag: util::TupleArgumentsFlag)
@@ -1437,8 +1437,8 @@ fn confirm_callable_candidate<'cx, 'gcx, 'tcx>(
     confirm_param_env_candidate(selcx, obligation, predicate)
 }
 
-fn confirm_param_env_candidate<'cx, 'gcx, 'tcx>(
-    selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
+fn confirm_param_env_candidate<'cx, 'tcx>(
+    selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &ProjectionTyObligation<'tcx>,
     poly_cache_entry: ty::PolyProjectionPredicate<'tcx>,
 ) -> Progress<'tcx> {
@@ -1478,8 +1478,8 @@ fn confirm_param_env_candidate<'cx, 'gcx, 'tcx>(
     }
 }
 
-fn confirm_impl_candidate<'cx, 'gcx, 'tcx>(
-    selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
+fn confirm_impl_candidate<'cx, 'tcx>(
+    selcx: &mut SelectionContext<'cx, 'tcx>,
     obligation: &ProjectionTyObligation<'tcx>,
     impl_vtable: VtableImplData<'tcx, PredicateObligation<'tcx>>)
     -> Progress<'tcx>
@@ -1521,8 +1521,8 @@ fn confirm_impl_candidate<'cx, 'gcx, 'tcx>(
 ///
 /// Based on the "projection mode", this lookup may in fact only examine the
 /// topmost impl. See the comments for `Reveal` for more details.
-fn assoc_ty_def<'cx, 'gcx, 'tcx>(
-    selcx: &SelectionContext<'cx, 'gcx, 'tcx>,
+fn assoc_ty_def<'cx, 'tcx>(
+    selcx: &SelectionContext<'cx, 'tcx>,
     impl_def_id: DefId,
     assoc_ty_def_id: DefId)
     -> specialization_graph::NodeItem<ty::AssocItem>
@@ -1608,8 +1608,8 @@ pub struct ProjectionCacheKey<'tcx> {
     ty: ty::ProjectionTy<'tcx>
 }
 
-impl<'cx, 'gcx, 'tcx> ProjectionCacheKey<'tcx> {
-    pub fn from_poly_projection_predicate(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
+impl<'cx, 'tcx> ProjectionCacheKey<'tcx> {
+    pub fn from_poly_projection_predicate(selcx: &mut SelectionContext<'cx, 'tcx>,
                                           predicate: &ty::PolyProjectionPredicate<'tcx>)
                                           -> Option<Self>
     {
diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs
index 90df5ed10d7..46403a38c99 100644
--- a/src/librustc/traits/query/dropck_outlives.rs
+++ b/src/librustc/traits/query/dropck_outlives.rs
@@ -6,7 +6,7 @@ use syntax::source_map::Span;
 use crate::ty::subst::Kind;
 use crate::ty::{self, Ty, TyCtxt};
 
-impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> {
+impl<'cx, 'tcx> At<'cx, 'tcx> {
     /// Given a type `ty` of some value being dropped, computes a set
     /// of "kinds" (types, regions) that must be outlive the execution
     /// of the destructor. These basically correspond to data that the
@@ -85,7 +85,7 @@ pub struct DropckOutlivesResult<'tcx> {
 }
 
 impl<'tcx> DropckOutlivesResult<'tcx> {
-    pub fn report_overflows(&self, tcx: TyCtxt<'_, 'tcx>, span: Span, ty: Ty<'tcx>) {
+    pub fn report_overflows(&self, tcx: TyCtxt<'tcx>, span: Span, ty: Ty<'tcx>) {
         if let Some(overflow_ty) = self.overflows.iter().next() {
             let mut err = struct_span_err!(
                 tcx.sess,
@@ -101,7 +101,7 @@ impl<'tcx> DropckOutlivesResult<'tcx> {
 
     pub fn into_kinds_reporting_overflows(
         self,
-        tcx: TyCtxt<'_, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         span: Span,
         ty: Ty<'tcx>,
     ) -> Vec<Kind<'tcx>> {
@@ -185,7 +185,7 @@ impl_stable_hash_for!(struct DtorckConstraint<'tcx> {
 ///
 /// Note also that `needs_drop` requires a "global" type (i.e., one
 /// with erased regions), but this function does not.
-pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
+pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
     match ty.sty {
         // None of these types have a destructor and hence they do not
         // require anything in particular to outlive the dtor's
diff --git a/src/librustc/traits/query/evaluate_obligation.rs b/src/librustc/traits/query/evaluate_obligation.rs
index d5230f15c25..031e3424847 100644
--- a/src/librustc/traits/query/evaluate_obligation.rs
+++ b/src/librustc/traits/query/evaluate_obligation.rs
@@ -3,7 +3,7 @@ use crate::infer::canonical::OriginalQueryValues;
 use crate::traits::{EvaluationResult, PredicateObligation, SelectionContext,
              TraitQueryMode, OverflowError};
 
-impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
+impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
     /// Evaluates whether the predicate can be satisfied (by any means)
     /// in the given `ParamEnv`.
     pub fn predicate_may_hold(
diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs
index 86067a7c1d8..50476721e82 100644
--- a/src/librustc/traits/query/normalize.rs
+++ b/src/librustc/traits/query/normalize.rs
@@ -14,7 +14,7 @@ use crate::ty::{self, Ty, TyCtxt};
 
 use super::NoSolution;
 
-impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> {
+impl<'cx, 'tcx> At<'cx, 'tcx> {
     /// Normalize `value` in the context of the inference context,
     /// yielding a resulting type, or an error if `value` cannot be
     /// normalized. If you don't care about regions, you should prefer
@@ -73,8 +73,8 @@ pub struct NormalizationResult<'tcx> {
     pub normalized_ty: Ty<'tcx>,
 }
 
-struct QueryNormalizer<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
-    infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
+struct QueryNormalizer<'cx, 'tcx: 'cx> {
+    infcx: &'cx InferCtxt<'cx, 'tcx>,
     cause: &'cx ObligationCause<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     obligations: Vec<PredicateObligation<'tcx>>,
@@ -82,8 +82,8 @@ struct QueryNormalizer<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
     anon_depth: usize,
 }
 
-impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx> {
-    fn tcx<'c>(&'c self) -> TyCtxt<'gcx, 'tcx> {
+impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
+    fn tcx<'c>(&'c self) -> TyCtxt<'tcx> {
         self.infcx.tcx
     }
 
diff --git a/src/librustc/traits/query/normalize_erasing_regions.rs b/src/librustc/traits/query/normalize_erasing_regions.rs
index 8b820e22cac..3218ff062ce 100644
--- a/src/librustc/traits/query/normalize_erasing_regions.rs
+++ b/src/librustc/traits/query/normalize_erasing_regions.rs
@@ -10,7 +10,7 @@
 use crate::ty::{self, Ty, TyCtxt};
 use crate::ty::fold::{TypeFoldable, TypeFolder};
 
-impl<'tcx> TyCtxt<'tcx, 'tcx> {
+impl<'tcx> TyCtxt<'tcx> {
     /// Erase the regions in `value` and then fully normalize all the
     /// types found within. The result will also have regions erased.
     ///
@@ -63,12 +63,12 @@ impl<'tcx> TyCtxt<'tcx, 'tcx> {
 }
 
 struct NormalizeAfterErasingRegionsFolder<'tcx> {
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
 }
 
-impl TypeFolder<'tcx, 'tcx> for NormalizeAfterErasingRegionsFolder<'tcx> {
-    fn tcx(&self) -> TyCtxt<'tcx, 'tcx> {
+impl TypeFolder<'tcx> for NormalizeAfterErasingRegionsFolder<'tcx> {
+    fn tcx(&self) -> TyCtxt<'tcx> {
         self.tcx
     }
 
diff --git a/src/librustc/traits/query/outlives_bounds.rs b/src/librustc/traits/query/outlives_bounds.rs
index 954de15905f..40bd18738b5 100644
--- a/src/librustc/traits/query/outlives_bounds.rs
+++ b/src/librustc/traits/query/outlives_bounds.rs
@@ -64,7 +64,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for OutlivesBound<'tcx> {
     }
 }
 
-impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
+impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
     /// Implied bounds are region relationships that we deduce
     /// automatically. The idea is that (e.g.) a caller must check that a
     /// function's argument types are well-formed immediately before
diff --git a/src/librustc/traits/query/type_op/ascribe_user_type.rs b/src/librustc/traits/query/type_op/ascribe_user_type.rs
index c663a65659c..05a4d4336a7 100644
--- a/src/librustc/traits/query/type_op/ascribe_user_type.rs
+++ b/src/librustc/traits/query/type_op/ascribe_user_type.rs
@@ -21,25 +21,25 @@ impl<'tcx> AscribeUserType<'tcx> {
     }
 }
 
-impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for AscribeUserType<'tcx> {
+impl<'tcx> super::QueryTypeOp<'tcx> for AscribeUserType<'tcx> {
     type QueryResponse = ();
 
     fn try_fast_path(
-        _tcx: TyCtxt<'gcx, 'tcx>,
+        _tcx: TyCtxt<'tcx>,
         _key: &ParamEnvAnd<'tcx, Self>,
     ) -> Option<Self::QueryResponse> {
         None
     }
 
     fn perform_query(
-        tcx: TyCtxt<'gcx, 'tcx>,
-        canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Self>>,
-    ) -> Fallible<CanonicalizedQueryResponse<'gcx, ()>> {
+        tcx: TyCtxt<'tcx>,
+        canonicalized: Canonicalized<'tcx, ParamEnvAnd<'tcx, Self>>,
+    ) -> Fallible<CanonicalizedQueryResponse<'tcx, ()>> {
         tcx.type_op_ascribe_user_type(canonicalized)
     }
 
     fn shrink_to_tcx_lifetime(
-        v: &'a CanonicalizedQueryResponse<'gcx, ()>,
+        v: &'a CanonicalizedQueryResponse<'tcx, ()>,
     ) -> &'a Canonical<'tcx, QueryResponse<'tcx, ()>> {
         v
     }
diff --git a/src/librustc/traits/query/type_op/custom.rs b/src/librustc/traits/query/type_op/custom.rs
index 5933d2366e8..72550e23460 100644
--- a/src/librustc/traits/query/type_op/custom.rs
+++ b/src/librustc/traits/query/type_op/custom.rs
@@ -14,9 +14,9 @@ pub struct CustomTypeOp<F, G> {
 }
 
 impl<F, G> CustomTypeOp<F, G> {
-    pub fn new<'gcx, 'tcx, R>(closure: F, description: G) -> Self
+    pub fn new<'tcx, R>(closure: F, description: G) -> Self
     where
-        F: FnOnce(&InferCtxt<'_, 'gcx, 'tcx>) -> Fallible<InferOk<'tcx, R>>,
+        F: FnOnce(&InferCtxt<'_, 'tcx>) -> Fallible<InferOk<'tcx, R>>,
         G: Fn() -> String,
     {
         CustomTypeOp {
@@ -26,9 +26,9 @@ impl<F, G> CustomTypeOp<F, G> {
     }
 }
 
-impl<'gcx, 'tcx, F, R, G> super::TypeOp<'gcx, 'tcx> for CustomTypeOp<F, G>
+impl<'tcx, F, R, G> super::TypeOp<'tcx> for CustomTypeOp<F, G>
 where
-    F: for<'a, 'cx> FnOnce(&'a InferCtxt<'cx, 'gcx, 'tcx>) -> Fallible<InferOk<'tcx, R>>,
+    F: for<'a, 'cx> FnOnce(&'a InferCtxt<'cx, 'tcx>) -> Fallible<InferOk<'tcx, R>>,
     G: Fn() -> String,
 {
     type Output = R;
@@ -38,7 +38,7 @@ where
     /// (they will be given over to the NLL region solver).
     fn fully_perform(
         self,
-        infcx: &InferCtxt<'_, 'gcx, 'tcx>,
+        infcx: &InferCtxt<'_, 'tcx>,
     ) -> Fallible<(Self::Output, Option<Rc<Vec<QueryRegionConstraint<'tcx>>>>)> {
         if cfg!(debug_assertions) {
             info!("fully_perform({:?})", self);
@@ -59,8 +59,8 @@ where
 
 /// Executes `op` and then scrapes out all the "old style" region
 /// constraints that result, creating query-region-constraints.
-fn scrape_region_constraints<'gcx, 'tcx, R>(
-    infcx: &InferCtxt<'_, 'gcx, 'tcx>,
+fn scrape_region_constraints<'tcx, R>(
+    infcx: &InferCtxt<'_, 'tcx>,
     op: impl FnOnce() -> Fallible<InferOk<'tcx, R>>,
 ) -> Fallible<(R, Option<Rc<Vec<QueryRegionConstraint<'tcx>>>>)> {
     let mut fulfill_cx = TraitEngine::new(infcx.tcx);
diff --git a/src/librustc/traits/query/type_op/eq.rs b/src/librustc/traits/query/type_op/eq.rs
index c431178bb2a..e8ec304f918 100644
--- a/src/librustc/traits/query/type_op/eq.rs
+++ b/src/librustc/traits/query/type_op/eq.rs
@@ -14,11 +14,11 @@ impl<'tcx> Eq<'tcx> {
     }
 }
 
-impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for Eq<'tcx> {
+impl<'tcx> super::QueryTypeOp<'tcx> for Eq<'tcx> {
     type QueryResponse = ();
 
     fn try_fast_path(
-        _tcx: TyCtxt<'gcx, 'tcx>,
+        _tcx: TyCtxt<'tcx>,
         key: &ParamEnvAnd<'tcx, Eq<'tcx>>,
     ) -> Option<Self::QueryResponse> {
         if key.value.a == key.value.b {
@@ -29,14 +29,14 @@ impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for Eq<'tcx> {
     }
 
     fn perform_query(
-        tcx: TyCtxt<'gcx, 'tcx>,
-        canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Self>>,
-    ) -> Fallible<CanonicalizedQueryResponse<'gcx, ()>> {
+        tcx: TyCtxt<'tcx>,
+        canonicalized: Canonicalized<'tcx, ParamEnvAnd<'tcx, Self>>,
+    ) -> Fallible<CanonicalizedQueryResponse<'tcx, ()>> {
         tcx.type_op_eq(canonicalized)
     }
 
     fn shrink_to_tcx_lifetime(
-        v: &'a CanonicalizedQueryResponse<'gcx, ()>,
+        v: &'a CanonicalizedQueryResponse<'tcx, ()>,
     ) -> &'a Canonical<'tcx, QueryResponse<'tcx, ()>> {
         v
     }
diff --git a/src/librustc/traits/query/type_op/implied_outlives_bounds.rs b/src/librustc/traits/query/type_op/implied_outlives_bounds.rs
index 762e09b03ac..3beb4d64656 100644
--- a/src/librustc/traits/query/type_op/implied_outlives_bounds.rs
+++ b/src/librustc/traits/query/type_op/implied_outlives_bounds.rs
@@ -14,20 +14,20 @@ impl<'tcx> ImpliedOutlivesBounds<'tcx> {
     }
 }
 
-impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for ImpliedOutlivesBounds<'tcx> {
+impl<'tcx> super::QueryTypeOp<'tcx> for ImpliedOutlivesBounds<'tcx> {
     type QueryResponse = Vec<OutlivesBound<'tcx>>;
 
     fn try_fast_path(
-        _tcx: TyCtxt<'gcx, 'tcx>,
+        _tcx: TyCtxt<'tcx>,
         _key: &ParamEnvAnd<'tcx, Self>,
     ) -> Option<Self::QueryResponse> {
         None
     }
 
     fn perform_query(
-        tcx: TyCtxt<'gcx, 'tcx>,
-        canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Self>>,
-    ) -> Fallible<CanonicalizedQueryResponse<'gcx, Self::QueryResponse>> {
+        tcx: TyCtxt<'tcx>,
+        canonicalized: Canonicalized<'tcx, ParamEnvAnd<'tcx, Self>>,
+    ) -> Fallible<CanonicalizedQueryResponse<'tcx, Self::QueryResponse>> {
         // FIXME this `unchecked_map` is only necessary because the
         // query is defined as taking a `ParamEnvAnd<Ty>`; it should
         // take a `ImpliedOutlivesBounds` instead
@@ -40,7 +40,7 @@ impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for ImpliedOutlivesBounds<
     }
 
     fn shrink_to_tcx_lifetime(
-        v: &'a CanonicalizedQueryResponse<'gcx, Self::QueryResponse>,
+        v: &'a CanonicalizedQueryResponse<'tcx, Self::QueryResponse>,
     ) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self::QueryResponse>> {
         v
     }
diff --git a/src/librustc/traits/query/type_op/mod.rs b/src/librustc/traits/query/type_op/mod.rs
index 1553d17e684..8dfb11230f2 100644
--- a/src/librustc/traits/query/type_op/mod.rs
+++ b/src/librustc/traits/query/type_op/mod.rs
@@ -23,7 +23,7 @@ pub mod subtype;
 /// "Type ops" are used in NLL to perform some particular action and
 /// extract out the resulting region constraints (or an error if it
 /// cannot be completed).
-pub trait TypeOp<'gcx, 'tcx>: Sized + fmt::Debug {
+pub trait TypeOp<'tcx>: Sized + fmt::Debug {
     type Output;
 
     /// Processes the operation and all resulting obligations,
@@ -31,7 +31,7 @@ pub trait TypeOp<'gcx, 'tcx>: Sized + fmt::Debug {
     /// (they will be given over to the NLL region solver).
     fn fully_perform(
         self,
-        infcx: &InferCtxt<'_, 'gcx, 'tcx>,
+        infcx: &InferCtxt<'_, 'tcx>,
     ) -> Fallible<(Self::Output, Option<Rc<Vec<QueryRegionConstraint<'tcx>>>>)>;
 }
 
@@ -44,16 +44,16 @@ pub trait TypeOp<'gcx, 'tcx>: Sized + fmt::Debug {
 /// which produces the resulting query region constraints.
 ///
 /// [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html
-pub trait QueryTypeOp<'gcx: 'tcx, 'tcx>:
-    fmt::Debug + Sized + TypeFoldable<'tcx> + Lift<'gcx>
+pub trait QueryTypeOp<'tcx>:
+    fmt::Debug + Sized + TypeFoldable<'tcx> + Lift<'tcx>
 {
-    type QueryResponse: TypeFoldable<'tcx> + Lift<'gcx>;
+    type QueryResponse: TypeFoldable<'tcx> + Lift<'tcx>;
 
     /// Give query the option for a simple fast path that never
     /// actually hits the tcx cache lookup etc. Return `Some(r)` with
     /// a final result or `None` to do the full path.
     fn try_fast_path(
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         key: &ParamEnvAnd<'tcx, Self>,
     ) -> Option<Self::QueryResponse>;
 
@@ -64,29 +64,29 @@ pub trait QueryTypeOp<'gcx: 'tcx, 'tcx>:
     /// bad, because it would create subregion relationships that are
     /// not captured in the return value.
     fn perform_query(
-        tcx: TyCtxt<'gcx, 'tcx>,
-        canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Self>>,
-    ) -> Fallible<CanonicalizedQueryResponse<'gcx, Self::QueryResponse>>;
+        tcx: TyCtxt<'tcx>,
+        canonicalized: Canonicalized<'tcx, ParamEnvAnd<'tcx, Self>>,
+    ) -> Fallible<CanonicalizedQueryResponse<'tcx, Self::QueryResponse>>;
 
     /// Casts a lifted query result (which is in the gcx lifetime)
     /// into the tcx lifetime. This is always just an identity cast,
     /// but the generic code doesn't realize it -- put another way, in
-    /// the generic code, we have a `Lifted<'gcx, Self::QueryResponse>`
+    /// the generic code, we have a `Lifted<'tcx, Self::QueryResponse>`
     /// and we want to convert that to a `Self::QueryResponse`. This is
     /// not a priori valid, so we can't do it -- but in practice, it
     /// is always a no-op (e.g., the lifted form of a type,
-    /// `Ty<'gcx>`, is a subtype of `Ty<'tcx>`). So we have to push
+    /// `Ty<'tcx>`, is a subtype of `Ty<'tcx>`). So we have to push
     /// the operation into the impls that know more specifically what
     /// `QueryResponse` is. This operation would (maybe) be nicer with
     /// something like HKTs or GATs, since then we could make
-    /// `QueryResponse` parametric and `'gcx` and `'tcx` etc.
+    /// `QueryResponse` parametric and `'tcx` and `'tcx` etc.
     fn shrink_to_tcx_lifetime(
-        lifted_query_result: &'a CanonicalizedQueryResponse<'gcx, Self::QueryResponse>,
+        lifted_query_result: &'a CanonicalizedQueryResponse<'tcx, Self::QueryResponse>,
     ) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self::QueryResponse>>;
 
     fn fully_perform_into(
         query_key: ParamEnvAnd<'tcx, Self>,
-        infcx: &InferCtxt<'_, 'gcx, 'tcx>,
+        infcx: &InferCtxt<'_, 'tcx>,
         output_query_region_constraints: &mut Vec<QueryRegionConstraint<'tcx>>,
     ) -> Fallible<Self::QueryResponse> {
         if let Some(result) = QueryTypeOp::try_fast_path(infcx.tcx, &query_key) {
@@ -133,15 +133,15 @@ pub trait QueryTypeOp<'gcx: 'tcx, 'tcx>:
     }
 }
 
-impl<'gcx: 'tcx, 'tcx, Q> TypeOp<'gcx, 'tcx> for ParamEnvAnd<'tcx, Q>
+impl<'tcx, Q> TypeOp<'tcx> for ParamEnvAnd<'tcx, Q>
 where
-    Q: QueryTypeOp<'gcx, 'tcx>,
+    Q: QueryTypeOp<'tcx>,
 {
     type Output = Q::QueryResponse;
 
     fn fully_perform(
         self,
-        infcx: &InferCtxt<'_, 'gcx, 'tcx>,
+        infcx: &InferCtxt<'_, 'tcx>,
     ) -> Fallible<(Self::Output, Option<Rc<Vec<QueryRegionConstraint<'tcx>>>>)> {
         let mut qrc = vec![];
         let r = Q::fully_perform_into(self, infcx, &mut qrc)?;
diff --git a/src/librustc/traits/query/type_op/normalize.rs b/src/librustc/traits/query/type_op/normalize.rs
index 52a0c6042ba..5a768d9d58f 100644
--- a/src/librustc/traits/query/type_op/normalize.rs
+++ b/src/librustc/traits/query/type_op/normalize.rs
@@ -18,13 +18,13 @@ where
     }
 }
 
-impl<'gcx: 'tcx, 'tcx, T> super::QueryTypeOp<'gcx, 'tcx> for Normalize<T>
+impl<'tcx, T> super::QueryTypeOp<'tcx> for Normalize<T>
 where
-    T: Normalizable<'gcx, 'tcx>,
+    T: Normalizable<'tcx>,
 {
     type QueryResponse = T;
 
-    fn try_fast_path(_tcx: TyCtxt<'gcx, 'tcx>, key: &ParamEnvAnd<'tcx, Self>) -> Option<T> {
+    fn try_fast_path(_tcx: TyCtxt<'tcx>, key: &ParamEnvAnd<'tcx, Self>) -> Option<T> {
         if !key.value.value.has_projections() {
             Some(key.value.value)
         } else {
@@ -33,99 +33,87 @@ where
     }
 
     fn perform_query(
-        tcx: TyCtxt<'gcx, 'tcx>,
-        canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Self>>,
-    ) -> Fallible<CanonicalizedQueryResponse<'gcx, Self::QueryResponse>> {
+        tcx: TyCtxt<'tcx>,
+        canonicalized: Canonicalized<'tcx, ParamEnvAnd<'tcx, Self>>,
+    ) -> Fallible<CanonicalizedQueryResponse<'tcx, Self::QueryResponse>> {
         T::type_op_method(tcx, canonicalized)
     }
 
     fn shrink_to_tcx_lifetime(
-        v: &'a CanonicalizedQueryResponse<'gcx, T>,
+        v: &'a CanonicalizedQueryResponse<'tcx, T>,
     ) -> &'a Canonical<'tcx, QueryResponse<'tcx, T>> {
         T::shrink_to_tcx_lifetime(v)
     }
 }
 
-pub trait Normalizable<'gcx, 'tcx>: fmt::Debug + TypeFoldable<'tcx> + Lift<'gcx> + Copy {
+pub trait Normalizable<'tcx>: fmt::Debug + TypeFoldable<'tcx> + Lift<'tcx> + Copy {
     fn type_op_method(
-        tcx: TyCtxt<'gcx, 'tcx>,
-        canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
-    ) -> Fallible<CanonicalizedQueryResponse<'gcx, Self>>;
+        tcx: TyCtxt<'tcx>,
+        canonicalized: Canonicalized<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
+    ) -> Fallible<CanonicalizedQueryResponse<'tcx, Self>>;
 
-    /// Converts from the `'gcx` (lifted) form of `Self` into the `tcx`
+    /// Converts from the `'tcx` (lifted) form of `Self` into the `tcx`
     /// form of `Self`.
     fn shrink_to_tcx_lifetime(
-        v: &'a CanonicalizedQueryResponse<'gcx, Self>,
+        v: &'a CanonicalizedQueryResponse<'tcx, Self>,
     ) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self>>;
 }
 
-impl Normalizable<'gcx, 'tcx> for Ty<'tcx>
-where
-    'gcx: 'tcx,
-{
+impl Normalizable<'tcx> for Ty<'tcx> {
     fn type_op_method(
-        tcx: TyCtxt<'gcx, 'tcx>,
-        canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
-    ) -> Fallible<CanonicalizedQueryResponse<'gcx, Self>> {
+        tcx: TyCtxt<'tcx>,
+        canonicalized: Canonicalized<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
+    ) -> Fallible<CanonicalizedQueryResponse<'tcx, Self>> {
         tcx.type_op_normalize_ty(canonicalized)
     }
 
     fn shrink_to_tcx_lifetime(
-        v: &'a CanonicalizedQueryResponse<'gcx, Self>,
+        v: &'a CanonicalizedQueryResponse<'tcx, Self>,
     ) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self>> {
         v
     }
 }
 
-impl Normalizable<'gcx, 'tcx> for ty::Predicate<'tcx>
-where
-    'gcx: 'tcx,
-{
+impl Normalizable<'tcx> for ty::Predicate<'tcx> {
     fn type_op_method(
-        tcx: TyCtxt<'gcx, 'tcx>,
-        canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
-    ) -> Fallible<CanonicalizedQueryResponse<'gcx, Self>> {
+        tcx: TyCtxt<'tcx>,
+        canonicalized: Canonicalized<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
+    ) -> Fallible<CanonicalizedQueryResponse<'tcx, Self>> {
         tcx.type_op_normalize_predicate(canonicalized)
     }
 
     fn shrink_to_tcx_lifetime(
-        v: &'a CanonicalizedQueryResponse<'gcx, Self>,
+        v: &'a CanonicalizedQueryResponse<'tcx, Self>,
     ) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self>> {
         v
     }
 }
 
-impl Normalizable<'gcx, 'tcx> for ty::PolyFnSig<'tcx>
-where
-    'gcx: 'tcx,
-{
+impl Normalizable<'tcx> for ty::PolyFnSig<'tcx> {
     fn type_op_method(
-        tcx: TyCtxt<'gcx, 'tcx>,
-        canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
-    ) -> Fallible<CanonicalizedQueryResponse<'gcx, Self>> {
+        tcx: TyCtxt<'tcx>,
+        canonicalized: Canonicalized<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
+    ) -> Fallible<CanonicalizedQueryResponse<'tcx, Self>> {
         tcx.type_op_normalize_poly_fn_sig(canonicalized)
     }
 
     fn shrink_to_tcx_lifetime(
-        v: &'a CanonicalizedQueryResponse<'gcx, Self>,
+        v: &'a CanonicalizedQueryResponse<'tcx, Self>,
     ) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self>> {
         v
     }
 }
 
-impl Normalizable<'gcx, 'tcx> for ty::FnSig<'tcx>
-where
-    'gcx: 'tcx,
-{
+impl Normalizable<'tcx> for ty::FnSig<'tcx> {
     fn type_op_method(
-        tcx: TyCtxt<'gcx, 'tcx>,
-        canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
-    ) -> Fallible<CanonicalizedQueryResponse<'gcx, Self>> {
+        tcx: TyCtxt<'tcx>,
+        canonicalized: Canonicalized<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,
+    ) -> Fallible<CanonicalizedQueryResponse<'tcx, Self>> {
         tcx.type_op_normalize_fn_sig(canonicalized)
     }
 
     fn shrink_to_tcx_lifetime(
-        v: &'a CanonicalizedQueryResponse<'gcx, Self>,
+        v: &'a CanonicalizedQueryResponse<'tcx, Self>,
     ) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self>> {
         v
     }
diff --git a/src/librustc/traits/query/type_op/outlives.rs b/src/librustc/traits/query/type_op/outlives.rs
index 56a051e08e7..d4b36356ffb 100644
--- a/src/librustc/traits/query/type_op/outlives.rs
+++ b/src/librustc/traits/query/type_op/outlives.rs
@@ -15,14 +15,11 @@ impl<'tcx> DropckOutlives<'tcx> {
     }
 }
 
-impl super::QueryTypeOp<'gcx, 'tcx> for DropckOutlives<'tcx>
-where
-    'gcx: 'tcx,
-{
+impl super::QueryTypeOp<'tcx> for DropckOutlives<'tcx> {
     type QueryResponse = DropckOutlivesResult<'tcx>;
 
     fn try_fast_path(
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         key: &ParamEnvAnd<'tcx, Self>,
     ) -> Option<Self::QueryResponse> {
         if trivial_dropck_outlives(tcx, key.value.dropped_ty) {
@@ -33,9 +30,9 @@ where
     }
 
     fn perform_query(
-        tcx: TyCtxt<'gcx, 'tcx>,
-        canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Self>>,
-    ) -> Fallible<CanonicalizedQueryResponse<'gcx, Self::QueryResponse>> {
+        tcx: TyCtxt<'tcx>,
+        canonicalized: Canonicalized<'tcx, ParamEnvAnd<'tcx, Self>>,
+    ) -> Fallible<CanonicalizedQueryResponse<'tcx, Self::QueryResponse>> {
         // Subtle: note that we are not invoking
         // `infcx.at(...).dropck_outlives(...)` here, but rather the
         // underlying `dropck_outlives` query. This same underlying
@@ -58,7 +55,7 @@ where
     }
 
     fn shrink_to_tcx_lifetime(
-        lifted_query_result: &'a CanonicalizedQueryResponse<'gcx, Self::QueryResponse>,
+        lifted_query_result: &'a CanonicalizedQueryResponse<'tcx, Self::QueryResponse>,
     ) -> &'a Canonical<'tcx, QueryResponse<'tcx, Self::QueryResponse>> {
         lifted_query_result
     }
diff --git a/src/librustc/traits/query/type_op/prove_predicate.rs b/src/librustc/traits/query/type_op/prove_predicate.rs
index 64fcc73187c..1efe66326d7 100644
--- a/src/librustc/traits/query/type_op/prove_predicate.rs
+++ b/src/librustc/traits/query/type_op/prove_predicate.rs
@@ -13,11 +13,11 @@ impl<'tcx> ProvePredicate<'tcx> {
     }
 }
 
-impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for ProvePredicate<'tcx> {
+impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> {
     type QueryResponse = ();
 
     fn try_fast_path(
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         key: &ParamEnvAnd<'tcx, Self>,
     ) -> Option<Self::QueryResponse> {
         // Proving Sized, very often on "obviously sized" types like
@@ -38,14 +38,14 @@ impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for ProvePredicate<'tcx> {
     }
 
     fn perform_query(
-        tcx: TyCtxt<'gcx, 'tcx>,
-        canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Self>>,
-    ) -> Fallible<CanonicalizedQueryResponse<'gcx, ()>> {
+        tcx: TyCtxt<'tcx>,
+        canonicalized: Canonicalized<'tcx, ParamEnvAnd<'tcx, Self>>,
+    ) -> Fallible<CanonicalizedQueryResponse<'tcx, ()>> {
         tcx.type_op_prove_predicate(canonicalized)
     }
 
     fn shrink_to_tcx_lifetime(
-        v: &'a CanonicalizedQueryResponse<'gcx, ()>,
+        v: &'a CanonicalizedQueryResponse<'tcx, ()>,
     ) -> &'a Canonical<'tcx, QueryResponse<'tcx, ()>> {
         v
     }
diff --git a/src/librustc/traits/query/type_op/subtype.rs b/src/librustc/traits/query/type_op/subtype.rs
index a2f47211f48..71c74999c27 100644
--- a/src/librustc/traits/query/type_op/subtype.rs
+++ b/src/librustc/traits/query/type_op/subtype.rs
@@ -17,10 +17,10 @@ impl<'tcx> Subtype<'tcx> {
     }
 }
 
-impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for Subtype<'tcx> {
+impl<'tcx> super::QueryTypeOp<'tcx> for Subtype<'tcx> {
     type QueryResponse = ();
 
-    fn try_fast_path(_tcx: TyCtxt<'gcx, 'tcx>, key: &ParamEnvAnd<'tcx, Self>) -> Option<()> {
+    fn try_fast_path(_tcx: TyCtxt<'tcx>, key: &ParamEnvAnd<'tcx, Self>) -> Option<()> {
         if key.value.sub == key.value.sup {
             Some(())
         } else {
@@ -29,14 +29,14 @@ impl<'gcx: 'tcx, 'tcx> super::QueryTypeOp<'gcx, 'tcx> for Subtype<'tcx> {
     }
 
     fn perform_query(
-        tcx: TyCtxt<'gcx, 'tcx>,
-        canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Self>>,
-    ) -> Fallible<CanonicalizedQueryResponse<'gcx, ()>> {
+        tcx: TyCtxt<'tcx>,
+        canonicalized: Canonicalized<'tcx, ParamEnvAnd<'tcx, Self>>,
+    ) -> Fallible<CanonicalizedQueryResponse<'tcx, ()>> {
         tcx.type_op_subtype(canonicalized)
     }
 
     fn shrink_to_tcx_lifetime(
-        v: &'a CanonicalizedQueryResponse<'gcx, ()>,
+        v: &'a CanonicalizedQueryResponse<'tcx, ()>,
     ) -> &'a Canonical<'tcx, QueryResponse<'tcx, ()>> {
         v
     }
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 57a361d469e..329a243d2d7 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -50,15 +50,15 @@ use std::iter;
 use std::rc::Rc;
 use crate::util::nodemap::{FxHashMap, FxHashSet};
 
-pub struct SelectionContext<'cx, 'gcx: 'cx + 'tcx, 'tcx: 'cx> {
-    infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
+pub struct SelectionContext<'cx, 'tcx: 'cx> {
+    infcx: &'cx InferCtxt<'cx, 'tcx>,
 
     /// Freshener used specifically for entries on the obligation
     /// stack. This ensures that all entries on the stack at one time
     /// will have the same set of placeholder entries, which is
     /// important for checking for trait bounds that recursively
     /// require themselves.
-    freshener: TypeFreshener<'cx, 'gcx, 'tcx>,
+    freshener: TypeFreshener<'cx, 'tcx>,
 
     /// If `true`, indicates that the evaluation should be conservative
     /// and consider the possibility of types outside this crate.
@@ -300,7 +300,7 @@ enum SelectionCandidate<'tcx> {
 
 impl<'a, 'tcx> ty::Lift<'tcx> for SelectionCandidate<'a> {
     type Lifted = SelectionCandidate<'tcx>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         Some(match *self {
             BuiltinCandidate { has_nested } => BuiltinCandidate { has_nested },
             ImplCandidate(def_id) => ImplCandidate(def_id),
@@ -487,8 +487,8 @@ pub struct EvaluationCache<'tcx> {
     hashmap: Lock<FxHashMap<ty::PolyTraitRef<'tcx>, WithDepNode<EvaluationResult>>>,
 }
 
-impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
-    pub fn new(infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>) -> SelectionContext<'cx, 'gcx, 'tcx> {
+impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
+    pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>) -> SelectionContext<'cx, 'tcx> {
         SelectionContext {
             infcx,
             freshener: infcx.freshener(),
@@ -500,9 +500,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
     }
 
     pub fn intercrate(
-        infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
+        infcx: &'cx InferCtxt<'cx, 'tcx>,
         mode: IntercrateMode,
-    ) -> SelectionContext<'cx, 'gcx, 'tcx> {
+    ) -> SelectionContext<'cx, 'tcx> {
         debug!("intercrate({:?})", mode);
         SelectionContext {
             infcx,
@@ -515,9 +515,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
     }
 
     pub fn with_negative(
-        infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
+        infcx: &'cx InferCtxt<'cx, 'tcx>,
         allow_negative_impls: bool,
-    ) -> SelectionContext<'cx, 'gcx, 'tcx> {
+    ) -> SelectionContext<'cx, 'tcx> {
         debug!("with_negative({:?})", allow_negative_impls);
         SelectionContext {
             infcx,
@@ -530,9 +530,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
     }
 
     pub fn with_query_mode(
-        infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
+        infcx: &'cx InferCtxt<'cx, 'tcx>,
         query_mode: TraitQueryMode,
-    ) -> SelectionContext<'cx, 'gcx, 'tcx> {
+    ) -> SelectionContext<'cx, 'tcx> {
         debug!("with_query_mode({:?})", query_mode);
         SelectionContext {
             infcx,
@@ -564,15 +564,15 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
         self.intercrate_ambiguity_causes.take().unwrap_or(vec![])
     }
 
-    pub fn infcx(&self) -> &'cx InferCtxt<'cx, 'gcx, 'tcx> {
+    pub fn infcx(&self) -> &'cx InferCtxt<'cx, 'tcx> {
         self.infcx
     }
 
-    pub fn tcx(&self) -> TyCtxt<'gcx, 'tcx> {
+    pub fn tcx(&self) -> TyCtxt<'tcx> {
         self.infcx.tcx
     }
 
-    pub fn closure_typer(&self) -> &'cx InferCtxt<'cx, 'gcx, 'tcx> {
+    pub fn closure_typer(&self) -> &'cx InferCtxt<'cx, 'tcx> {
         self.infcx
     }
 
@@ -3989,7 +3989,7 @@ impl<T: Clone> WithDepNode<T> {
         }
     }
 
-    pub fn get(&self, tcx: TyCtxt<'_, '_>) -> T {
+    pub fn get(&self, tcx: TyCtxt<'_>) -> T {
         tcx.dep_graph.read_index(self.dep_node);
         self.cached_value.clone()
     }
diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs
index 27891bed2b7..3f1fcea35a0 100644
--- a/src/librustc/traits/specialize/mod.rs
+++ b/src/librustc/traits/specialize/mod.rs
@@ -69,7 +69,7 @@ pub struct OverlapError {
 /// through associated type projection. We deal with such cases by using
 /// *fulfillment* to relate the two impls, requiring that all projections are
 /// resolved.
-pub fn translate_substs<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
+pub fn translate_substs<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                                         param_env: ty::ParamEnv<'tcx>,
                                         source_impl: DefId,
                                         source_substs: SubstsRef<'tcx>,
@@ -110,7 +110,7 @@ pub fn translate_substs<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
 /// that impl, a less specialized impl, or the trait default,
 /// whichever applies.
 pub fn find_associated_item<'tcx>(
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     item: &ty::AssocItem,
     substs: SubstsRef<'tcx>,
@@ -150,7 +150,7 @@ pub fn find_associated_item<'tcx>(
 /// `impl1` specializes `impl2` if it applies to a subset of the types `impl2` applies
 /// to.
 pub(super) fn specializes<'tcx>(
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     (impl1_def_id, impl2_def_id): (DefId, DefId),
 ) -> bool {
     debug!("specializes({:?}, {:?})", impl1_def_id, impl2_def_id);
@@ -209,7 +209,7 @@ pub(super) fn specializes<'tcx>(
 /// generics of `target_impl`, including both those needed to unify with
 /// `source_trait_ref` and those whose identity is determined via a where
 /// clause in the impl.
-fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
+fn fulfill_implication<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                                        param_env: ty::ParamEnv<'tcx>,
                                        source_trait_ref: ty::TraitRef<'tcx>,
                                        target_impl: DefId)
@@ -286,7 +286,7 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
 
 // Query provider for `specialization_graph_of`.
 pub(super) fn specialization_graph_provider<'tcx>(
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     trait_id: DefId,
 ) -> &'tcx specialization_graph::Graph {
     let mut sg = specialization_graph::Graph::new();
@@ -390,7 +390,7 @@ pub(super) fn specialization_graph_provider<'tcx>(
 
 /// Recovers the "impl X for Y" signature from `impl_def_id` and returns it as a
 /// string.
-fn to_pretty_impl_header(tcx: TyCtxt<'_, '_>, impl_def_id: DefId) -> Option<String> {
+fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option<String> {
     use std::fmt::Write;
 
     let trait_ref = if let Some(tr) = tcx.impl_trait_ref(impl_def_id) {
diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs
index 2e86d40a3ad..a6eae6da922 100644
--- a/src/librustc/traits/specialize/specialization_graph.rs
+++ b/src/librustc/traits/specialize/specialization_graph.rs
@@ -81,9 +81,9 @@ enum Inserted {
     ShouldRecurseOn(DefId),
 }
 
-impl<'gcx, 'tcx> Children {
+impl<'tcx> Children {
     /// Insert an impl into this set of children without comparing to any existing impls.
-    fn insert_blindly(&mut self, tcx: TyCtxt<'gcx, 'tcx>, impl_def_id: DefId) {
+    fn insert_blindly(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) {
         let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
         if let Some(sty) = fast_reject::simplify_type(tcx, trait_ref.self_ty(), false) {
             debug!("insert_blindly: impl_def_id={:?} sty={:?}", impl_def_id, sty);
@@ -97,7 +97,7 @@ impl<'gcx, 'tcx> Children {
     /// Removes an impl from this set of children. Used when replacing
     /// an impl with a parent. The impl must be present in the list of
     /// children already.
-    fn remove_existing(&mut self, tcx: TyCtxt<'gcx, 'tcx>, impl_def_id: DefId) {
+    fn remove_existing(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) {
         let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
         let vec: &mut Vec<DefId>;
         if let Some(sty) = fast_reject::simplify_type(tcx, trait_ref.self_ty(), false) {
@@ -116,7 +116,7 @@ impl<'gcx, 'tcx> Children {
     /// specialization relationships.
     fn insert(
         &mut self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         impl_def_id: DefId,
         simplified_self: Option<SimplifiedType>,
     ) -> Result<Inserted, OverlapError> {
@@ -278,7 +278,7 @@ impl<I, J> Iterator for PotentialSiblings<I, J>
     }
 }
 
-impl<'gcx, 'tcx> Graph {
+impl<'tcx> Graph {
     pub fn new() -> Graph {
         Graph {
             parent: Default::default(),
@@ -291,7 +291,7 @@ impl<'gcx, 'tcx> Graph {
     /// information about the area of overlap is returned in the `Err`.
     pub fn insert(
         &mut self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         impl_def_id: DefId,
     ) -> Result<Option<FutureCompatOverlapError>, OverlapError> {
         assert!(impl_def_id.is_local());
@@ -385,7 +385,7 @@ impl<'gcx, 'tcx> Graph {
     /// Insert cached metadata mapping from a child impl back to its parent.
     pub fn record_impl_from_cstore(
         &mut self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         parent: DefId,
         child: DefId,
     ) {
@@ -413,7 +413,7 @@ pub enum Node {
     Trait(DefId),
 }
 
-impl<'gcx, 'tcx> Node {
+impl<'tcx> Node {
     pub fn is_from_trait(&self) -> bool {
         match *self {
             Node::Trait(..) => true,
@@ -422,7 +422,7 @@ impl<'gcx, 'tcx> Node {
     }
 
     /// Iterate over the items defined directly by the given (impl or trait) node.
-    pub fn items(&self, tcx: TyCtxt<'gcx, 'tcx>) -> ty::AssocItemsIterator<'gcx, 'tcx> {
+    pub fn items(&self, tcx: TyCtxt<'tcx>) -> ty::AssocItemsIterator<'tcx> {
         tcx.associated_items(self.def_id())
     }
 
@@ -471,18 +471,18 @@ impl<T> NodeItem<T> {
     }
 }
 
-impl<'gcx, 'tcx> Ancestors<'gcx> {
+impl<'tcx> Ancestors<'tcx> {
     /// Search the items from the given ancestors, returning each definition
     /// with the given name and the given kind.
     // FIXME(#35870): avoid closures being unexported due to `impl Trait`.
     #[inline]
     pub fn defs(
         self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         trait_item_name: Ident,
         trait_item_kind: ty::AssocKind,
         trait_def_id: DefId,
-    ) -> impl Iterator<Item = NodeItem<ty::AssocItem>> + Captures<'gcx> + 'tcx {
+    ) -> impl Iterator<Item = NodeItem<ty::AssocItem>> + Captures<'tcx> + 'tcx {
         self.flat_map(move |node| {
             use crate::ty::AssocKind::*;
             node.items(tcx).filter(move |impl_item| match (trait_item_kind, impl_item.kind) {
@@ -505,7 +505,7 @@ impl<'gcx, 'tcx> Ancestors<'gcx> {
 /// Walk up the specialization ancestors of a given impl, starting with that
 /// impl itself.
 pub fn ancestors(
-    tcx: TyCtxt<'tcx, '_>,
+    tcx: TyCtxt<'tcx>,
     trait_def_id: DefId,
     start_from_impl: DefId,
 ) -> Ancestors<'tcx> {
diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs
index e919f0ed2b4..129a400d28f 100644
--- a/src/librustc/traits/structural_impls.rs
+++ b/src/librustc/traits/structural_impls.rs
@@ -446,7 +446,7 @@ impl<'tcx> fmt::Display for traits::Clause<'tcx> {
 
 impl<'a, 'tcx> Lift<'tcx> for traits::SelectionError<'a> {
     type Lifted = traits::SelectionError<'tcx>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         match *self {
             super::Unimplemented => Some(super::Unimplemented),
             super::OutputTypeParameterMismatch(a, b, ref err) => {
@@ -464,7 +464,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::SelectionError<'a> {
 
 impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
     type Lifted = traits::ObligationCauseCode<'tcx>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         match *self {
             super::ReturnNoExpression => Some(super::ReturnNoExpression),
             super::MiscObligation => Some(super::MiscObligation),
@@ -546,7 +546,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
 
 impl<'a, 'tcx> Lift<'tcx> for traits::DerivedObligationCause<'a> {
     type Lifted = traits::DerivedObligationCause<'tcx>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         tcx.lift(&self.parent_trait_ref).and_then(|trait_ref|
             tcx.lift(&*self.parent_code)
                .map(|code| traits::DerivedObligationCause {
@@ -559,7 +559,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::DerivedObligationCause<'a> {
 
 impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCause<'a> {
     type Lifted = traits::ObligationCause<'tcx>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         tcx.lift(&self.code).map(|code| traits::ObligationCause {
             span: self.span,
             body_id: self.body_id,
@@ -571,7 +571,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCause<'a> {
 // For codegen only.
 impl<'a, 'tcx> Lift<'tcx> for traits::Vtable<'a, ()> {
     type Lifted = traits::Vtable<'tcx, ()>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         match self.clone() {
             traits::VtableImpl(traits::VtableImplData {
                 impl_def_id,
@@ -691,7 +691,7 @@ EnumLiftImpl! {
 
 impl<'a, 'tcx> Lift<'tcx> for traits::Environment<'a> {
     type Lifted = traits::Environment<'tcx>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         tcx.lift(&self.clauses).map(|clauses| {
             traits::Environment {
                 clauses,
@@ -702,7 +702,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::Environment<'a> {
 
 impl<'a, 'tcx, G: Lift<'tcx>> Lift<'tcx> for traits::InEnvironment<'a, G> {
     type Lifted = traits::InEnvironment<'tcx, G::Lifted>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::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 {
@@ -721,7 +721,7 @@ where
 {
     type Lifted = C::LiftedExClause;
 
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         <C as traits::ChalkContextLift>::lift_ex_clause_to_tcx(self, tcx)
     }
 }
@@ -733,7 +733,7 @@ where
 {
     type Lifted = C::LiftedDelayedLiteral;
 
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         <C as traits::ChalkContextLift>::lift_delayed_literal_to_tcx(self, tcx)
     }
 }
@@ -745,7 +745,7 @@ where
 {
     type Lifted = C::LiftedLiteral;
 
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         <C as traits::ChalkContextLift>::lift_literal_to_tcx(self, tcx)
     }
 }
@@ -754,7 +754,7 @@ where
 // TypeFoldable implementations.
 
 impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx, O> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         traits::Obligation {
             cause: self.cause.clone(),
             recursion_depth: self.recursion_depth,
@@ -887,7 +887,7 @@ EnumTypeFoldableImpl! {
 }
 
 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<traits::Goal<'tcx>> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    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]>>();
@@ -900,7 +900,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<traits::Goal<'tcx>> {
 }
 
 impl<'tcx> TypeFoldable<'tcx> for traits::Goal<'tcx> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         let v = (**self).fold_with(folder);
         folder.tcx().mk_goal(v)
     }
@@ -941,7 +941,7 @@ BraceStructTypeFoldableImpl! {
 }
 
 impl<'tcx> TypeFoldable<'tcx> for traits::Clauses<'tcx> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    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]>>();
@@ -959,7 +959,7 @@ where
     C::Substitution: Clone,
     C::RegionConstraint: Clone,
 {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         <C as traits::ExClauseFold>::fold_ex_clause_with(
             self,
             folder,
diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs
index c5ff174e944..c7491343426 100644
--- a/src/librustc/traits/util.rs
+++ b/src/librustc/traits/util.rs
@@ -12,8 +12,8 @@ use crate::util::nodemap::FxHashSet;
 
 use super::{Obligation, ObligationCause, PredicateObligation, SelectionContext, Normalized};
 
-fn anonymize_predicate<'gcx, 'tcx>(
-    tcx: TyCtxt<'gcx, 'tcx>,
+fn anonymize_predicate<'tcx>(
+    tcx: TyCtxt<'tcx>,
     pred: &ty::Predicate<'tcx>,
 ) -> ty::Predicate<'tcx> {
     match *pred {
@@ -46,13 +46,13 @@ fn anonymize_predicate<'gcx, 'tcx>(
     }
 }
 
-struct PredicateSet<'gcx, 'tcx> {
-    tcx: TyCtxt<'gcx, 'tcx>,
+struct PredicateSet<'tcx> {
+    tcx: TyCtxt<'tcx>,
     set: FxHashSet<ty::Predicate<'tcx>>,
 }
 
-impl PredicateSet<'gcx, 'tcx> {
-    fn new(tcx: TyCtxt<'gcx, 'tcx>) -> Self {
+impl PredicateSet<'tcx> {
+    fn new(tcx: TyCtxt<'tcx>) -> Self {
         Self { tcx: tcx, set: Default::default() }
     }
 
@@ -71,7 +71,7 @@ impl PredicateSet<'gcx, 'tcx> {
     }
 }
 
-impl<T: AsRef<ty::Predicate<'tcx>>> Extend<T> for PredicateSet<'gcx, 'tcx> {
+impl<T: AsRef<ty::Predicate<'tcx>>> Extend<T> for PredicateSet<'tcx> {
     fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
         for pred in iter {
             self.insert(pred.as_ref());
@@ -89,36 +89,36 @@ impl<T: AsRef<ty::Predicate<'tcx>>> Extend<T> for PredicateSet<'gcx, 'tcx> {
 /// if we know that `T: Ord`, the elaborator would deduce that `T: PartialOrd`
 /// holds as well. Similarly, if we have `trait Foo: 'static`, and we know that
 /// `T: Foo`, then we know that `T: 'static`.
-pub struct Elaborator<'gcx, 'tcx> {
+pub struct Elaborator<'tcx> {
     stack: Vec<ty::Predicate<'tcx>>,
-    visited: PredicateSet<'gcx, 'tcx>,
+    visited: PredicateSet<'tcx>,
 }
 
-pub fn elaborate_trait_ref<'gcx, 'tcx>(
-    tcx: TyCtxt<'gcx, 'tcx>,
+pub fn elaborate_trait_ref<'tcx>(
+    tcx: TyCtxt<'tcx>,
     trait_ref: ty::PolyTraitRef<'tcx>,
-) -> Elaborator<'gcx, 'tcx> {
+) -> Elaborator<'tcx> {
     elaborate_predicates(tcx, vec![trait_ref.to_predicate()])
 }
 
-pub fn elaborate_trait_refs<'gcx, 'tcx>(
-    tcx: TyCtxt<'gcx, 'tcx>,
+pub fn elaborate_trait_refs<'tcx>(
+    tcx: TyCtxt<'tcx>,
     trait_refs: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
-) -> Elaborator<'gcx, 'tcx> {
+) -> Elaborator<'tcx> {
     let predicates = trait_refs.map(|trait_ref| trait_ref.to_predicate()).collect();
     elaborate_predicates(tcx, predicates)
 }
 
-pub fn elaborate_predicates<'gcx, 'tcx>(
-    tcx: TyCtxt<'gcx, 'tcx>,
+pub fn elaborate_predicates<'tcx>(
+    tcx: TyCtxt<'tcx>,
     mut predicates: Vec<ty::Predicate<'tcx>>,
-) -> Elaborator<'gcx, 'tcx> {
+) -> Elaborator<'tcx> {
     let mut visited = PredicateSet::new(tcx);
     predicates.retain(|pred| visited.insert(pred));
     Elaborator { stack: predicates, visited }
 }
 
-impl Elaborator<'gcx, 'tcx> {
+impl Elaborator<'tcx> {
     pub fn filter_to_traits(self) -> FilterToTraits<Self> {
         FilterToTraits::new(self)
     }
@@ -230,7 +230,7 @@ impl Elaborator<'gcx, 'tcx> {
     }
 }
 
-impl Iterator for Elaborator<'gcx, 'tcx> {
+impl Iterator for Elaborator<'tcx> {
     type Item = ty::Predicate<'tcx>;
 
     fn size_hint(&self) -> (usize, Option<usize>) {
@@ -252,19 +252,19 @@ impl Iterator for Elaborator<'gcx, 'tcx> {
 // Supertrait iterator
 ///////////////////////////////////////////////////////////////////////////
 
-pub type Supertraits<'gcx, 'tcx> = FilterToTraits<Elaborator<'gcx, 'tcx>>;
+pub type Supertraits<'tcx> = FilterToTraits<Elaborator<'tcx>>;
 
-pub fn supertraits<'gcx, 'tcx>(
-    tcx: TyCtxt<'gcx, 'tcx>,
+pub fn supertraits<'tcx>(
+    tcx: TyCtxt<'tcx>,
     trait_ref: ty::PolyTraitRef<'tcx>,
-) -> Supertraits<'gcx, 'tcx> {
+) -> Supertraits<'tcx> {
     elaborate_trait_ref(tcx, trait_ref).filter_to_traits()
 }
 
-pub fn transitive_bounds<'gcx, 'tcx>(
-    tcx: TyCtxt<'gcx, 'tcx>,
+pub fn transitive_bounds<'tcx>(
+    tcx: TyCtxt<'tcx>,
     bounds: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
-) -> Supertraits<'gcx, 'tcx> {
+) -> Supertraits<'tcx> {
     elaborate_trait_refs(tcx, bounds).filter_to_traits()
 }
 
@@ -280,8 +280,8 @@ pub fn transitive_bounds<'gcx, 'tcx>(
 /// `Read + Write + Sync + Send`.
 /// Expansion is done via a DFS (depth-first search), and the `visited` field
 /// is used to avoid cycles.
-pub struct TraitAliasExpander<'gcx, 'tcx> {
-    tcx: TyCtxt<'gcx, 'tcx>,
+pub struct TraitAliasExpander<'tcx> {
+    tcx: TyCtxt<'tcx>,
     stack: Vec<TraitAliasExpansionInfo<'tcx>>,
 }
 
@@ -337,10 +337,10 @@ impl<'tcx> TraitAliasExpansionInfo<'tcx> {
     }
 }
 
-pub fn expand_trait_aliases<'gcx, 'tcx>(
-    tcx: TyCtxt<'gcx, 'tcx>,
+pub fn expand_trait_aliases<'tcx>(
+    tcx: TyCtxt<'tcx>,
     trait_refs: impl IntoIterator<Item = (ty::PolyTraitRef<'tcx>, Span)>,
-) -> TraitAliasExpander<'gcx, 'tcx> {
+) -> TraitAliasExpander<'tcx> {
     let items: Vec<_> = trait_refs
         .into_iter()
         .map(|(trait_ref, span)| TraitAliasExpansionInfo::new(trait_ref, span))
@@ -348,7 +348,7 @@ pub fn expand_trait_aliases<'gcx, 'tcx>(
     TraitAliasExpander { tcx, stack: items }
 }
 
-impl<'gcx, 'tcx> TraitAliasExpander<'gcx, 'tcx> {
+impl<'tcx> TraitAliasExpander<'tcx> {
     /// If `item` is a trait alias and its predicate has not yet been visited, then expands `item`
     /// to the definition, pushes the resulting expansion onto `self.stack`, and returns `false`.
     /// Otherwise, immediately returns `true` if `item` is a regular trait, or `false` if it is a
@@ -393,7 +393,7 @@ impl<'gcx, 'tcx> TraitAliasExpander<'gcx, 'tcx> {
     }
 }
 
-impl<'gcx, 'tcx> Iterator for TraitAliasExpander<'gcx, 'tcx> {
+impl<'tcx> Iterator for TraitAliasExpander<'tcx> {
     type Item = TraitAliasExpansionInfo<'tcx>;
 
     fn size_hint(&self) -> (usize, Option<usize>) {
@@ -414,16 +414,16 @@ impl<'gcx, 'tcx> Iterator for TraitAliasExpander<'gcx, 'tcx> {
 // Iterator over def-IDs of supertraits
 ///////////////////////////////////////////////////////////////////////////
 
-pub struct SupertraitDefIds<'gcx, 'tcx> {
-    tcx: TyCtxt<'gcx, 'tcx>,
+pub struct SupertraitDefIds<'tcx> {
+    tcx: TyCtxt<'tcx>,
     stack: Vec<DefId>,
     visited: FxHashSet<DefId>,
 }
 
-pub fn supertrait_def_ids<'gcx, 'tcx>(
-    tcx: TyCtxt<'gcx, 'tcx>,
+pub fn supertrait_def_ids<'tcx>(
+    tcx: TyCtxt<'tcx>,
     trait_def_id: DefId,
-) -> SupertraitDefIds<'gcx, 'tcx> {
+) -> SupertraitDefIds<'tcx> {
     SupertraitDefIds {
         tcx,
         stack: vec![trait_def_id],
@@ -431,7 +431,7 @@ pub fn supertrait_def_ids<'gcx, 'tcx>(
     }
 }
 
-impl Iterator for SupertraitDefIds<'gcx, 'tcx> {
+impl Iterator for SupertraitDefIds<'tcx> {
     type Item = DefId;
 
     fn next(&mut self) -> Option<DefId> {
@@ -489,7 +489,7 @@ impl<'tcx, I: Iterator<Item = ty::Predicate<'tcx>>> Iterator for FilterToTraits<
 /// Instantiate all bound parameters of the impl with the given substs,
 /// returning the resulting trait ref and all obligations that arise.
 /// The obligations are closed under normalization.
-pub fn impl_trait_ref_and_oblig<'a, 'gcx, 'tcx>(selcx: &mut SelectionContext<'a, 'gcx, 'tcx>,
+pub fn impl_trait_ref_and_oblig<'a, 'tcx>(selcx: &mut SelectionContext<'a, 'tcx>,
                                                 param_env: ty::ParamEnv<'tcx>,
                                                 impl_def_id: DefId,
                                                 impl_substs: SubstsRef<'tcx>,)
@@ -552,7 +552,7 @@ pub fn predicate_for_trait_ref<'tcx>(
     }
 }
 
-impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
+impl<'tcx> TyCtxt<'tcx> {
     pub fn predicate_for_trait_def(self,
                                    param_env: ty::ParamEnv<'tcx>,
                                    cause: ObligationCause<'tcx>,
diff --git a/src/librustc/ty/_match.rs b/src/librustc/ty/_match.rs
index 213f556f9ac..6e10dc03a28 100644
--- a/src/librustc/ty/_match.rs
+++ b/src/librustc/ty/_match.rs
@@ -19,19 +19,19 @@ use crate::mir::interpret::ConstValue;
 /// Like subtyping, matching is really a binary relation, so the only
 /// important thing about the result is Ok/Err. Also, matching never
 /// affects any type variables or unification state.
-pub struct Match<'gcx, 'tcx> {
-    tcx: TyCtxt<'gcx, 'tcx>,
+pub struct Match<'tcx> {
+    tcx: TyCtxt<'tcx>,
 }
 
-impl Match<'gcx, 'tcx> {
-    pub fn new(tcx: TyCtxt<'gcx, 'tcx>) -> Match<'gcx, 'tcx> {
+impl Match<'tcx> {
+    pub fn new(tcx: TyCtxt<'tcx>) -> Match<'tcx> {
         Match { tcx }
     }
 }
 
-impl TypeRelation<'gcx, 'tcx> for Match<'gcx, 'tcx> {
+impl TypeRelation<'tcx> for Match<'tcx> {
     fn tag(&self) -> &'static str { "Match" }
-    fn tcx(&self) -> TyCtxt<'gcx, 'tcx> { self.tcx }
+    fn tcx(&self) -> TyCtxt<'tcx> { self.tcx }
     fn a_is_expected(&self) -> bool { true } // irrelevant
 
     fn relate_with_variance<T: Relate<'tcx>>(&mut self,
diff --git a/src/librustc/ty/adjustment.rs b/src/librustc/ty/adjustment.rs
index e1f86bee4ba..2a228ed79a4 100644
--- a/src/librustc/ty/adjustment.rs
+++ b/src/librustc/ty/adjustment.rs
@@ -103,10 +103,10 @@ pub struct OverloadedDeref<'tcx> {
     pub mutbl: hir::Mutability,
 }
 
-impl<'gcx, 'tcx> OverloadedDeref<'tcx> {
+impl<'tcx> OverloadedDeref<'tcx> {
     pub fn method_call(
         &self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         source: Ty<'tcx>,
     ) -> (DefId, SubstsRef<'tcx>) {
         let trait_def_id = match self.mutbl {
diff --git a/src/librustc/ty/codec.rs b/src/librustc/ty/codec.rs
index ea5d088d540..224f7d5f28d 100644
--- a/src/librustc/ty/codec.rs
+++ b/src/librustc/ty/codec.rs
@@ -108,7 +108,7 @@ pub fn encode_predicates<'tcx, E, C>(encoder: &mut E,
 }
 
 pub trait TyDecoder<'tcx>: Decoder {
-    fn tcx(&self) -> TyCtxt<'tcx, 'tcx>;
+    fn tcx(&self) -> TyCtxt<'tcx>;
 
     fn peek_byte(&self) -> u8;
 
diff --git a/src/librustc/ty/constness.rs b/src/librustc/ty/constness.rs
index 466cb353c85..65b83224ae5 100644
--- a/src/librustc/ty/constness.rs
+++ b/src/librustc/ty/constness.rs
@@ -6,7 +6,7 @@ use syntax_pos::symbol::{sym, Symbol};
 use crate::hir::map::blocks::FnLikeNode;
 use syntax::attr;
 
-impl<'tcx> TyCtxt<'tcx, 'tcx> {
+impl<'tcx> TyCtxt<'tcx> {
     /// Whether the `def_id` counts as const fn in your current crate, considering all active
     /// feature gates
     pub fn is_const_fn(self, def_id: DefId) -> bool {
@@ -69,7 +69,7 @@ impl<'tcx> TyCtxt<'tcx, 'tcx> {
 
 pub fn provide<'tcx>(providers: &mut Providers<'tcx>) {
     /// only checks whether the function has a `const` modifier
-    fn is_const_fn_raw<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, def_id: DefId) -> bool {
+    fn is_const_fn_raw<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
         let hir_id = tcx.hir().as_local_hir_id(def_id)
                               .expect("Non-local call to local provider is_const_fn");
 
@@ -83,7 +83,7 @@ pub fn provide<'tcx>(providers: &mut Providers<'tcx>) {
         }
     }
 
-    fn is_promotable_const_fn<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, def_id: DefId) -> bool {
+    fn is_promotable_const_fn<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
         tcx.is_const_fn(def_id) && match tcx.lookup_stability(def_id) {
             Some(stab) => {
                 if cfg!(debug_assertions) && stab.promotable {
@@ -101,7 +101,7 @@ pub fn provide<'tcx>(providers: &mut Providers<'tcx>) {
         }
     }
 
-    fn const_fn_is_allowed_fn_ptr<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, def_id: DefId) -> bool {
+    fn const_fn_is_allowed_fn_ptr<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
         tcx.is_const_fn(def_id) &&
             tcx.lookup_stability(def_id)
                 .map(|stab| stab.allow_const_fn_ptr).unwrap_or(false)
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 4e255edfe85..a28da275ff1 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -115,7 +115,7 @@ pub struct CtxtInterners<'tcx> {
     const_: InternedSet<'tcx, Const<'tcx>>,
 }
 
-impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
+impl<'tcx> CtxtInterners<'tcx> {
     fn new(arena: &'tcx SyncDroplessArena) -> CtxtInterners<'tcx> {
         CtxtInterners {
             arena,
@@ -137,8 +137,8 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
     /// Intern a type
     #[inline(never)]
     fn intern_ty(
-        local: &CtxtInterners<'gcx>,
-        global: &CtxtInterners<'gcx>,
+        local: &CtxtInterners<'tcx>,
+        global: &CtxtInterners<'tcx>,
         st: TyKind<'tcx>
     ) -> Ty<'tcx> {
         let flags = super::flags::FlagComputation::for_sty(&st);
@@ -164,7 +164,7 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
 
                 // This is safe because all the types the ty_struct can point to
                 // already is in the local arena or the global arena
-                let ty_struct: TyS<'gcx> = unsafe {
+                let ty_struct: TyS<'tcx> = unsafe {
                     mem::transmute(ty_struct)
                 };
 
@@ -180,7 +180,7 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
 
                 // This is safe because all the types the ty_struct can point to
                 // already is in the global arena
-                let ty_struct: TyS<'gcx> = unsafe {
+                let ty_struct: TyS<'tcx> = unsafe {
                     mem::transmute(ty_struct)
                 };
 
@@ -750,7 +750,7 @@ impl<'tcx> TypeckTables<'tcx> {
 
 }
 
-impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for TypeckTables<'gcx> {
+impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TypeckTables<'tcx> {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
                                           hasher: &mut StableHasher<W>) {
@@ -859,9 +859,9 @@ BraceStructLiftImpl! {
 
 
 /// Canonicalized user type annotation.
-pub type CanonicalUserType<'gcx> = Canonical<'gcx, UserType<'gcx>>;
+pub type CanonicalUserType<'tcx> = Canonical<'tcx, UserType<'tcx>>;
 
-impl CanonicalUserType<'gcx> {
+impl CanonicalUserType<'tcx> {
     /// Returns `true` if this represents a substitution of the form `[?0, ?1, ?2]`,
     /// i.e., each thing is mapped to a canonical variable with the same index.
     pub fn is_identity(&self) -> bool {
@@ -1016,14 +1016,14 @@ pub struct FreeRegionInfo {
 ///
 /// [rustc guide]: https://rust-lang.github.io/rustc-guide/ty.html
 #[derive(Copy, Clone)]
-pub struct TyCtxt<'gcx: 'tcx, 'tcx> {
-    gcx: &'gcx GlobalCtxt<'gcx>,
-    interners: &'gcx CtxtInterners<'gcx>,
+pub struct TyCtxt<'tcx> {
+    gcx: &'tcx GlobalCtxt<'tcx>,
+    interners: &'tcx CtxtInterners<'tcx>,
     dummy: PhantomData<&'tcx ()>,
 }
 
-impl<'gcx> Deref for TyCtxt<'gcx, '_> {
-    type Target = &'gcx GlobalCtxt<'gcx>;
+impl<'tcx> Deref for TyCtxt<'tcx> {
+    type Target = &'tcx GlobalCtxt<'tcx>;
     #[inline(always)]
     fn deref(&self) -> &Self::Target {
         &self.gcx
@@ -1119,10 +1119,10 @@ pub struct GlobalCtxt<'tcx> {
     output_filenames: Arc<OutputFilenames>,
 }
 
-impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
+impl<'tcx> TyCtxt<'tcx> {
     /// Gets the global `TyCtxt`.
     #[inline]
-    pub fn global_tcx(self) -> TyCtxt<'gcx, 'gcx> {
+    pub fn global_tcx(self) -> TyCtxt<'tcx> {
         TyCtxt {
             gcx: self.gcx,
             interners: &self.gcx.global_interners,
@@ -1131,11 +1131,11 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
     }
 
     #[inline(always)]
-    pub fn hir(self) -> &'tcx hir_map::Map<'gcx> {
+    pub fn hir(self) -> &'tcx hir_map::Map<'tcx> {
         &self.hir_map
     }
 
-    pub fn alloc_steal_mir(self, mir: Body<'gcx>) -> &'gcx Steal<Body<'gcx>> {
+    pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal<Body<'tcx>> {
         self.arena.alloc(Steal::new(mir))
     }
 
@@ -1144,12 +1144,12 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
                          kind: AdtKind,
                          variants: IndexVec<VariantIdx, ty::VariantDef>,
                          repr: ReprOptions)
-                         -> &'gcx ty::AdtDef {
+                         -> &'tcx ty::AdtDef {
         let def = ty::AdtDef::new(self, did, kind, variants, repr);
         self.arena.alloc(def)
     }
 
-    pub fn intern_const_alloc(self, alloc: Allocation) -> &'gcx Allocation {
+    pub fn intern_const_alloc(self, alloc: Allocation) -> &'tcx Allocation {
         self.allocation_interner.borrow_mut().intern(alloc, |alloc| {
             self.arena.alloc(alloc)
         })
@@ -1163,13 +1163,13 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
         self.alloc_map.lock().create_memory_alloc(alloc)
     }
 
-    pub fn intern_stability(self, stab: attr::Stability) -> &'gcx attr::Stability {
+    pub fn intern_stability(self, stab: attr::Stability) -> &'tcx attr::Stability {
         self.stability_interner.borrow_mut().intern(stab, |stab| {
             self.arena.alloc(stab)
         })
     }
 
-    pub fn intern_layout(self, layout: LayoutDetails) -> &'gcx LayoutDetails {
+    pub fn intern_layout(self, layout: LayoutDetails) -> &'tcx LayoutDetails {
         self.layout_interner.borrow_mut().intern(layout, |layout| {
             self.arena.alloc(layout)
         })
@@ -1201,7 +1201,7 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
     }
 
     /// Like lift, but only tries in the global tcx.
-    pub fn lift_to_global<T: ?Sized + Lift<'gcx>>(self, value: &T) -> Option<T::Lifted> {
+    pub fn lift_to_global<T: ?Sized + Lift<'tcx>>(self, value: &T) -> Option<T::Lifted> {
         value.lift_to_tcx(self.global_tcx())
     }
 
@@ -1343,11 +1343,11 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
         self.sess.consider_optimizing(&cname, msg)
     }
 
-    pub fn lib_features(self) -> &'gcx middle::lib_features::LibFeatures {
+    pub fn lib_features(self) -> &'tcx middle::lib_features::LibFeatures {
         self.get_lib_features(LOCAL_CRATE)
     }
 
-    pub fn lang_items(self) -> &'gcx middle::lang_items::LanguageItems {
+    pub fn lang_items(self) -> &'tcx middle::lang_items::LanguageItems {
         self.get_lang_items(LOCAL_CRATE)
     }
 
@@ -1385,15 +1385,15 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
         else { None }
     }
 
-    pub fn stability(self) -> &'gcx stability::Index<'gcx> {
+    pub fn stability(self) -> &'tcx stability::Index<'tcx> {
         self.stability_index(LOCAL_CRATE)
     }
 
-    pub fn crates(self) -> &'gcx [CrateNum] {
+    pub fn crates(self) -> &'tcx [CrateNum] {
         self.all_crate_nums(LOCAL_CRATE)
     }
 
-    pub fn features(self) -> &'gcx feature_gate::Features {
+    pub fn features(self) -> &'tcx feature_gate::Features {
         self.features_query(LOCAL_CRATE)
     }
 
@@ -1666,7 +1666,7 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
     }
 }
 
-impl<'tcx> TyCtxt<'tcx, 'tcx> {
+impl<'tcx> TyCtxt<'tcx> {
     pub fn encode_metadata(self)
         -> EncodedMetadata
     {
@@ -1674,14 +1674,13 @@ impl<'tcx> TyCtxt<'tcx, 'tcx> {
     }
 }
 
-impl<'gcx> GlobalCtxt<'gcx> {
+impl<'tcx> GlobalCtxt<'tcx> {
     /// Call the closure with a local `TyCtxt` using the given arena.
     /// `interners` is a slot passed so we can create a CtxtInterners
     /// with the same lifetime as `arena`.
-    pub fn enter_local<'tcx, F, R>(&'gcx self, f: F) -> R
+    pub fn enter_local<F, R>(&'tcx self, f: F) -> R
     where
-        F: FnOnce(TyCtxt<'gcx, 'tcx>) -> R,
-        'gcx: 'tcx,
+        F: FnOnce(TyCtxt<'tcx>) -> R,
     {
         let tcx = TyCtxt {
             gcx: self,
@@ -1722,7 +1721,7 @@ impl<'gcx> GlobalCtxt<'gcx> {
 /// e.g., `()` or `u8`, was interned in a different context.
 pub trait Lift<'tcx>: fmt::Debug {
     type Lifted: fmt::Debug + 'tcx;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted>;
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted>;
 }
 
 
@@ -1730,7 +1729,7 @@ macro_rules! nop_lift {
     ($ty:ty => $lifted:ty) => {
         impl<'a, 'tcx> Lift<'tcx> for $ty {
                     type Lifted = $lifted;
-                    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+                    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
                         if tcx.interners.arena.in_arena(*self as *const _) {
                             return Some(unsafe { mem::transmute(*self) });
                         }
@@ -1749,7 +1748,7 @@ macro_rules! nop_list_lift {
     ($ty:ty => $lifted:ty) => {
         impl<'a, 'tcx> Lift<'tcx> for &'a List<$ty> {
                     type Lifted = &'tcx List<$lifted>;
-                    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+                    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
                         if self.is_empty() {
                             return Some(List::empty());
                         }
@@ -1809,14 +1808,14 @@ pub mod tls {
     /// you should also have access to an ImplicitCtxt through the functions
     /// in this module.
     #[derive(Clone)]
-    pub struct ImplicitCtxt<'a, 'gcx: 'tcx, 'tcx> {
+    pub struct ImplicitCtxt<'a, 'tcx> {
         /// The current TyCtxt. Initially created by `enter_global` and updated
         /// by `enter_local` with a new local interner
-        pub tcx: TyCtxt<'gcx, 'tcx>,
+        pub tcx: TyCtxt<'tcx>,
 
         /// The current query job, if any. This is updated by JobOwner::start in
         /// ty::query::plumbing when executing a query
-        pub query: Option<Lrc<query::QueryJob<'gcx>>>,
+        pub query: Option<Lrc<query::QueryJob<'tcx>>>,
 
         /// Where to store diagnostics for the current query job, if any.
         /// This is updated by JobOwner::start in ty::query::plumbing when executing a query
@@ -1924,9 +1923,9 @@ pub mod tls {
 
     /// Sets `context` as the new current ImplicitCtxt for the duration of the function `f`
     #[inline]
-    pub fn enter_context<'a, 'gcx: 'tcx, 'tcx, F, R>(context: &ImplicitCtxt<'a, 'gcx, 'tcx>,
+    pub fn enter_context<'a, 'tcx, F, R>(context: &ImplicitCtxt<'a, 'tcx>,
                                                      f: F) -> R
-        where F: FnOnce(&ImplicitCtxt<'a, 'gcx, 'tcx>) -> R
+        where F: FnOnce(&ImplicitCtxt<'a, 'tcx>) -> R
     {
         set_tlv(context as *const _ as usize, || {
             f(&context)
@@ -1937,9 +1936,9 @@ pub mod tls {
     /// creating a initial TyCtxt and ImplicitCtxt.
     /// This happens once per rustc session and TyCtxts only exists
     /// inside the `f` function.
-    pub fn enter_global<'gcx, F, R>(gcx: &'gcx GlobalCtxt<'gcx>, f: F) -> R
+    pub fn enter_global<'tcx, F, R>(gcx: &'tcx GlobalCtxt<'tcx>, f: F) -> R
     where
-        F: FnOnce(TyCtxt<'gcx, 'gcx>) -> R,
+        F: FnOnce(TyCtxt<'tcx>) -> R,
     {
         // Update GCX_PTR to indicate there's a GlobalCtxt available
         GCX_PTR.with(|lock| {
@@ -1977,7 +1976,7 @@ pub mod tls {
     /// This is used in the deadlock handler.
     pub unsafe fn with_global<F, R>(f: F) -> R
     where
-        F: for<'gcx, 'tcx> FnOnce(TyCtxt<'gcx, 'tcx>) -> R,
+        F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> R,
     {
         let gcx = GCX_PTR.with(|lock| *lock.lock());
         assert!(gcx != 0);
@@ -2000,7 +1999,7 @@ pub mod tls {
     /// Allows access to the current ImplicitCtxt in a closure if one is available
     #[inline]
     pub fn with_context_opt<F, R>(f: F) -> R
-        where F: for<'a, 'gcx, 'tcx> FnOnce(Option<&ImplicitCtxt<'a, 'gcx, 'tcx>>) -> R
+        where F: for<'a, 'tcx> FnOnce(Option<&ImplicitCtxt<'a, 'tcx>>) -> R
     {
         let context = get_tlv();
         if context == 0 {
@@ -2008,9 +2007,9 @@ pub mod tls {
         } else {
             // We could get a ImplicitCtxt pointer from another thread.
             // Ensure that ImplicitCtxt is Sync
-            sync::assert_sync::<ImplicitCtxt<'_, '_, '_>>();
+            sync::assert_sync::<ImplicitCtxt<'_, '_>>();
 
-            unsafe { f(Some(&*(context as *const ImplicitCtxt<'_, '_, '_>))) }
+            unsafe { f(Some(&*(context as *const ImplicitCtxt<'_, '_>))) }
         }
     }
 
@@ -2018,25 +2017,25 @@ pub mod tls {
     /// Panics if there is no ImplicitCtxt available
     #[inline]
     pub fn with_context<F, R>(f: F) -> R
-        where F: for<'a, 'gcx, 'tcx> FnOnce(&ImplicitCtxt<'a, 'gcx, 'tcx>) -> R
+        where F: for<'a, 'tcx> FnOnce(&ImplicitCtxt<'a, 'tcx>) -> R
     {
         with_context_opt(|opt_context| f(opt_context.expect("no ImplicitCtxt stored in tls")))
     }
 
     /// Allows access to the current ImplicitCtxt whose tcx field has the same global
     /// interner as the tcx argument passed in. This means the closure is given an ImplicitCtxt
-    /// with the same 'gcx lifetime as the TyCtxt passed in.
+    /// with the same 'tcx lifetime as the TyCtxt passed in.
     /// This will panic if you pass it a TyCtxt which has a different global interner from
     /// the current ImplicitCtxt's tcx field.
     #[inline]
-    pub fn with_related_context<'gcx, 'tcx1, F, R>(tcx: TyCtxt<'gcx, 'tcx1>, f: F) -> R
+    pub fn with_related_context<'tcx, F, R>(tcx: TyCtxt<'tcx>, f: F) -> R
     where
-        F: for<'b, 'tcx2> FnOnce(&ImplicitCtxt<'b, 'gcx, 'tcx2>) -> R,
+        F: FnOnce(&ImplicitCtxt<'_, 'tcx>) -> R,
     {
         with_context(|context| {
             unsafe {
                 assert!(ptr_eq(context.tcx.gcx, tcx.gcx));
-                let context: &ImplicitCtxt<'_, '_, '_> = mem::transmute(context);
+                let context: &ImplicitCtxt<'_, '_> = mem::transmute(context);
                 f(context)
             }
         })
@@ -2044,19 +2043,19 @@ pub mod tls {
 
     /// Allows access to the current ImplicitCtxt whose tcx field has the same global
     /// interner and local interner as the tcx argument passed in. This means the closure
-    /// is given an ImplicitCtxt with the same 'tcx and 'gcx lifetimes as the TyCtxt passed in.
+    /// is given an ImplicitCtxt with the same 'tcx and 'tcx lifetimes as the TyCtxt passed in.
     /// This will panic if you pass it a TyCtxt which has a different global interner or
     /// a different local interner from the current ImplicitCtxt's tcx field.
     #[inline]
-    pub fn with_fully_related_context<'gcx, 'tcx, F, R>(tcx: TyCtxt<'gcx, 'tcx>, f: F) -> R
+    pub fn with_fully_related_context<'tcx, F, R>(tcx: TyCtxt<'tcx>, f: F) -> R
     where
-        F: for<'b> FnOnce(&ImplicitCtxt<'b, 'gcx, 'tcx>) -> R,
+        F: for<'b> FnOnce(&ImplicitCtxt<'b, 'tcx>) -> R,
     {
         with_context(|context| {
             unsafe {
                 assert!(ptr_eq(context.tcx.gcx, tcx.gcx));
                 assert!(ptr_eq(context.tcx.interners, tcx.interners));
-                let context: &ImplicitCtxt<'_, '_, '_> = mem::transmute(context);
+                let context: &ImplicitCtxt<'_, '_> = mem::transmute(context);
                 f(context)
             }
         })
@@ -2067,7 +2066,7 @@ pub mod tls {
     #[inline]
     pub fn with<F, R>(f: F) -> R
     where
-        F: for<'gcx, 'tcx> FnOnce(TyCtxt<'gcx, 'tcx>) -> R,
+        F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> R,
     {
         with_context(|context| f(context.tcx))
     }
@@ -2077,7 +2076,7 @@ pub mod tls {
     #[inline]
     pub fn with_opt<F, R>(f: F) -> R
     where
-        F: for<'gcx, 'tcx> FnOnce(Option<TyCtxt<'gcx, 'tcx>>) -> R,
+        F: for<'tcx> FnOnce(Option<TyCtxt<'tcx>>) -> R,
     {
         with_context_opt(|opt_context| f(opt_context.map(|context| context.tcx)))
     }
@@ -2101,7 +2100,7 @@ macro_rules! sty_debug_print {
                 all_infer: usize,
             }
 
-            pub fn go(tcx: TyCtxt<'_, '_>) {
+            pub fn go(tcx: TyCtxt<'_>) {
                 let mut total = DebugStat {
                     total: 0,
                     lt_infer: 0,
@@ -2154,7 +2153,7 @@ macro_rules! sty_debug_print {
     }}
 }
 
-impl<'tcx> TyCtxt<'tcx, 'tcx> {
+impl<'tcx> TyCtxt<'tcx> {
     pub fn print_debug_stats(self) {
         sty_debug_print!(
             self,
@@ -2196,8 +2195,8 @@ impl<'tcx> Hash for Interned<'tcx, TyS<'tcx>> {
     }
 }
 
-impl<'tcx: 'lcx, 'lcx> Borrow<TyKind<'lcx>> for Interned<'tcx, TyS<'tcx>> {
-    fn borrow<'a>(&'a self) -> &'a TyKind<'lcx> {
+impl<'tcx> Borrow<TyKind<'tcx>> for Interned<'tcx, TyS<'tcx>> {
+    fn borrow<'a>(&'a self) -> &'a TyKind<'tcx> {
         &self.0.sty
     }
 }
@@ -2217,20 +2216,20 @@ impl<'tcx, T: Hash> Hash for Interned<'tcx, List<T>> {
     }
 }
 
-impl<'tcx: 'lcx, 'lcx> Borrow<[Ty<'lcx>]> for Interned<'tcx, List<Ty<'tcx>>> {
-    fn borrow<'a>(&'a self) -> &'a [Ty<'lcx>] {
+impl<'tcx> Borrow<[Ty<'tcx>]> for Interned<'tcx, List<Ty<'tcx>>> {
+    fn borrow<'a>(&'a self) -> &'a [Ty<'tcx>] {
         &self.0[..]
     }
 }
 
-impl<'tcx: 'lcx, 'lcx> Borrow<[CanonicalVarInfo]> for Interned<'tcx, List<CanonicalVarInfo>> {
+impl<'tcx> Borrow<[CanonicalVarInfo]> for Interned<'tcx, List<CanonicalVarInfo>> {
     fn borrow<'a>(&'a self) -> &'a [CanonicalVarInfo] {
         &self.0[..]
     }
 }
 
-impl<'tcx: 'lcx, 'lcx> Borrow<[Kind<'lcx>]> for Interned<'tcx, InternalSubsts<'tcx>> {
-    fn borrow<'a>(&'a self) -> &'a [Kind<'lcx>] {
+impl<'tcx> Borrow<[Kind<'tcx>]> for Interned<'tcx, InternalSubsts<'tcx>> {
+    fn borrow<'a>(&'a self) -> &'a [Kind<'tcx>] {
         &self.0[..]
     }
 }
@@ -2248,42 +2247,42 @@ impl<'tcx> Borrow<RegionKind> for Interned<'tcx, RegionKind> {
     }
 }
 
-impl<'tcx: 'lcx, 'lcx> Borrow<GoalKind<'lcx>> for Interned<'tcx, GoalKind<'tcx>> {
-    fn borrow<'a>(&'a self) -> &'a GoalKind<'lcx> {
+impl<'tcx> Borrow<GoalKind<'tcx>> for Interned<'tcx, GoalKind<'tcx>> {
+    fn borrow<'a>(&'a self) -> &'a GoalKind<'tcx> {
         &self.0
     }
 }
 
-impl<'tcx: 'lcx, 'lcx> Borrow<[ExistentialPredicate<'lcx>]>
+impl<'tcx> Borrow<[ExistentialPredicate<'tcx>]>
     for Interned<'tcx, List<ExistentialPredicate<'tcx>>> {
-    fn borrow<'a>(&'a self) -> &'a [ExistentialPredicate<'lcx>] {
+    fn borrow<'a>(&'a self) -> &'a [ExistentialPredicate<'tcx>] {
         &self.0[..]
     }
 }
 
-impl<'tcx: 'lcx, 'lcx> Borrow<[Predicate<'lcx>]>
+impl<'tcx> Borrow<[Predicate<'tcx>]>
     for Interned<'tcx, List<Predicate<'tcx>>> {
-    fn borrow<'a>(&'a self) -> &'a [Predicate<'lcx>] {
+    fn borrow<'a>(&'a self) -> &'a [Predicate<'tcx>] {
         &self.0[..]
     }
 }
 
-impl<'tcx: 'lcx, 'lcx> Borrow<Const<'lcx>> for Interned<'tcx, Const<'tcx>> {
-    fn borrow<'a>(&'a self) -> &'a Const<'lcx> {
+impl<'tcx> Borrow<Const<'tcx>> for Interned<'tcx, Const<'tcx>> {
+    fn borrow<'a>(&'a self) -> &'a Const<'tcx> {
         &self.0
     }
 }
 
-impl<'tcx: 'lcx, 'lcx> Borrow<[Clause<'lcx>]>
+impl<'tcx> Borrow<[Clause<'tcx>]>
 for Interned<'tcx, List<Clause<'tcx>>> {
-    fn borrow<'a>(&'a self) -> &'a [Clause<'lcx>] {
+    fn borrow<'a>(&'a self) -> &'a [Clause<'tcx>] {
         &self.0[..]
     }
 }
 
-impl<'tcx: 'lcx, 'lcx> Borrow<[Goal<'lcx>]>
+impl<'tcx> Borrow<[Goal<'tcx>]>
 for Interned<'tcx, List<Goal<'tcx>>> {
-    fn borrow<'a>(&'a self) -> &'a [Goal<'lcx>] {
+    fn borrow<'a>(&'a self) -> &'a [Goal<'tcx>] {
         &self.0[..]
     }
 }
@@ -2293,21 +2292,10 @@ macro_rules! intern_method {
                                             $alloc_method:expr,
                                             $alloc_to_key:expr,
                                             $keep_in_local_tcx:expr) -> $ty:ty) => {
-        impl<'gcx, $lt_tcx> TyCtxt<'gcx, $lt_tcx> {
+        impl<$lt_tcx> TyCtxt<$lt_tcx> {
             pub fn $method(self, v: $alloc) -> &$lt_tcx $ty {
                 let key = ($alloc_to_key)(&v);
 
-                let alloc = |v, interners: &'gcx CtxtInterners<'gcx>| {
-                    // This transmutes $alloc<'tcx> to $alloc<'gcx>
-                    let v = unsafe {
-                        mem::transmute(v)
-                    };
-                    let i: &$lt_tcx $ty = $alloc_method(&interners.arena, v);
-                    // Cast to 'gcx
-                    let i = unsafe { mem::transmute(i) };
-                    Interned(i)
-                };
-
                 // HACK(eddyb) Depend on flags being accurate to
                 // determine that all contents are in the global tcx.
                 // See comments on Lift for why we can't use that.
@@ -2321,11 +2309,11 @@ macro_rules! intern_method {
                                 v);
                         }
 
-                        alloc(v, &self.interners)
+                        Interned($alloc_method(&self.interners.arena, v))
                     }).0
                 } else {
                     self.global_interners.$name.borrow_mut().intern_ref(key, || {
-                        alloc(v, &self.global_interners)
+                        Interned($alloc_method(&self.global_interners.arena, v))
                     }).0
                 }
             }
@@ -2403,7 +2391,7 @@ intern_method! {
     ) -> List<CanonicalVarInfo>
 }
 
-impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
+impl<'tcx> TyCtxt<'tcx> {
     /// Given a `fn` type, returns an equivalent `unsafe fn` type;
     /// that is, a `fn` type that is equivalent in every way for being
     /// unsafe.
@@ -2772,7 +2760,7 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
         }
     }
 
-    pub fn intern_canonical_var_infos(self, ts: &[CanonicalVarInfo]) -> CanonicalVarInfos<'gcx> {
+    pub fn intern_canonical_var_infos(self, ts: &[CanonicalVarInfo]) -> CanonicalVarInfos<'tcx> {
         if ts.len() == 0 {
             List::empty()
         } else {
@@ -2938,7 +2926,7 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
         lint::struct_lint_level(self.sess, lint, level, src, None, msg)
     }
 
-    pub fn in_scope_traits(self, id: HirId) -> Option<&'gcx StableVec<TraitCandidate>> {
+    pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx StableVec<TraitCandidate>> {
         self.in_scope_traits_map(id.owner)
             .and_then(|map| map.get(&id.local_id))
     }
@@ -2955,7 +2943,7 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
     }
 
     pub fn object_lifetime_defaults(self, id: HirId)
-        -> Option<&'gcx [ObjectLifetimeDefault]>
+        -> Option<&'tcx [ObjectLifetimeDefault]>
     {
         self.object_lifetime_defaults_map(id.owner)
             .and_then(|map| map.get(&id.local_id).map(|v| &**v))
diff --git a/src/librustc/ty/erase_regions.rs b/src/librustc/ty/erase_regions.rs
index 330343c250c..999b4eff856 100644
--- a/src/librustc/ty/erase_regions.rs
+++ b/src/librustc/ty/erase_regions.rs
@@ -8,13 +8,13 @@ pub(super) fn provide(providers: &mut ty::query::Providers<'_>) {
     };
 }
 
-fn erase_regions_ty<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
+fn erase_regions_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
     // N.B., use `super_fold_with` here. If we used `fold_with`, it
     // could invoke the `erase_regions_ty` query recursively.
     ty.super_fold_with(&mut RegionEraserVisitor { tcx })
 }
 
-impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
+impl<'tcx> TyCtxt<'tcx> {
     /// Returns an equivalent value with all free regions removed (note
     /// that late-bound regions remain, because they are important for
     /// subtyping, but they are anonymized and normalized as well)..
@@ -32,12 +32,12 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
     }
 }
 
-struct RegionEraserVisitor<'gcx, 'tcx> {
-    tcx: TyCtxt<'gcx, 'tcx>,
+struct RegionEraserVisitor<'tcx> {
+    tcx: TyCtxt<'tcx>,
 }
 
-impl TypeFolder<'gcx, 'tcx> for RegionEraserVisitor<'gcx, 'tcx> {
-    fn tcx<'b>(&'b self) -> TyCtxt<'gcx, 'tcx> {
+impl TypeFolder<'tcx> for RegionEraserVisitor<'tcx> {
+    fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
         self.tcx
     }
 
diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
index 000e0854f4e..d5e04500350 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -183,8 +183,8 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
     }
 }
 
-impl<'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
-    pub fn sort_string(&self, tcx: TyCtxt<'gcx, 'lcx>) -> Cow<'static, str> {
+impl<'tcx> ty::TyS<'tcx> {
+    pub fn sort_string(&self, tcx: TyCtxt<'_>) -> Cow<'static, str> {
         match self.sty {
             ty::Bool | ty::Char | ty::Int(_) |
             ty::Uint(_) | ty::Float(_) | ty::Str | ty::Never => self.to_string().into(),
@@ -249,7 +249,7 @@ impl<'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
     }
 }
 
-impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
+impl<'tcx> TyCtxt<'tcx> {
     pub fn note_and_explain_type_err(self,
                                      db: &mut DiagnosticBuilder<'_>,
                                      err: &TypeError<'tcx>,
diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs
index d32ad0f5c6d..7aab1aef3b8 100644
--- a/src/librustc/ty/fast_reject.rs
+++ b/src/librustc/ty/fast_reject.rs
@@ -55,8 +55,8 @@ pub enum SimplifiedTypeGen<D>
 /// then we can't say much about whether two types would unify. Put another way,
 /// `can_simplify_params` should be true if type parameters appear free in `ty` and `false` if they
 /// are to be considered bound.
-pub fn simplify_type<'gcx, 'tcx>(
-    tcx: TyCtxt<'gcx, 'tcx>,
+pub fn simplify_type<'tcx>(
+    tcx: TyCtxt<'tcx>,
     ty: Ty<'_>,
     can_simplify_params: bool,
 ) -> Option<SimplifiedType> {
diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs
index c79dad04df6..9da35824bd0 100644
--- a/src/librustc/ty/fold.rs
+++ b/src/librustc/ty/fold.rs
@@ -45,8 +45,8 @@ use crate::util::nodemap::FxHashSet;
 /// To implement this conveniently, use the
 /// `BraceStructTypeFoldableImpl` etc macros found in `macros.rs`.
 pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self;
-    fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self;
+    fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         self.super_fold_with(folder)
     }
 
@@ -155,8 +155,8 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
 /// default implementation that does an "identity" fold. Within each
 /// identity fold, it should invoke `foo.fold_with(self)` to fold each
 /// sub-item.
-pub trait TypeFolder<'gcx: 'tcx, 'tcx>: Sized {
-    fn tcx<'a>(&'a self) -> TyCtxt<'gcx, 'tcx>;
+pub trait TypeFolder<'tcx>: Sized {
+    fn tcx<'a>(&'a self) -> TyCtxt<'tcx>;
 
     fn fold_binder<T>(&mut self, t: &Binder<T>) -> Binder<T>
         where T : TypeFoldable<'tcx>
@@ -198,25 +198,25 @@ pub trait TypeVisitor<'tcx> : Sized {
 ///////////////////////////////////////////////////////////////////////////
 // Some sample folders
 
-pub struct BottomUpFolder<'gcx, 'tcx, F, G, H>
+pub struct BottomUpFolder<'tcx, F, G, H>
 where
     F: FnMut(Ty<'tcx>) -> Ty<'tcx>,
     G: FnMut(ty::Region<'tcx>) -> ty::Region<'tcx>,
     H: FnMut(&'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx>,
 {
-    pub tcx: TyCtxt<'gcx, 'tcx>,
+    pub tcx: TyCtxt<'tcx>,
     pub ty_op: F,
     pub lt_op: G,
     pub ct_op: H,
 }
 
-impl<'gcx, 'tcx, F, G, H> TypeFolder<'gcx, 'tcx> for BottomUpFolder<'gcx, 'tcx, F, G, H>
+impl<'tcx, F, G, H> TypeFolder<'tcx> for BottomUpFolder<'tcx, F, G, H>
 where
     F: FnMut(Ty<'tcx>) -> Ty<'tcx>,
     G: FnMut(ty::Region<'tcx>) -> ty::Region<'tcx>,
     H: FnMut(&'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx>,
 {
-    fn tcx<'b>(&'b self) -> TyCtxt<'gcx, 'tcx> {
+    fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
         self.tcx
         }
 
@@ -239,7 +239,7 @@ where
 ///////////////////////////////////////////////////////////////////////////
 // Region folder
 
-impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
+impl<'tcx> TyCtxt<'tcx> {
     /// Collects the free and escaping regions in `value` into `region_set`. Returns
     /// whether any late-bound regions were skipped
     pub fn collect_regions<T>(self,
@@ -365,8 +365,8 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
 /// visited by this folder; only regions that occur free will be
 /// visited by `fld_r`.
 
-pub struct RegionFolder<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
-    tcx: TyCtxt<'gcx, 'tcx>,
+pub struct RegionFolder<'a, 'tcx> {
+    tcx: TyCtxt<'tcx>,
     skipped_regions: &'a mut bool,
 
     /// Stores the index of a binder *just outside* the stuff we have
@@ -381,13 +381,13 @@ pub struct RegionFolder<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
         &'a mut (dyn FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx> + 'a),
 }
 
-impl<'a, 'gcx, 'tcx> RegionFolder<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> RegionFolder<'a, 'tcx> {
     #[inline]
     pub fn new(
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         skipped_regions: &'a mut bool,
         fold_region_fn: &'a mut dyn FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>,
-    ) -> RegionFolder<'a, 'gcx, 'tcx> {
+    ) -> RegionFolder<'a, 'tcx> {
         RegionFolder {
             tcx,
             skipped_regions,
@@ -397,8 +397,8 @@ impl<'a, 'gcx, 'tcx> RegionFolder<'a, 'gcx, 'tcx> {
     }
 }
 
-impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionFolder<'a, 'gcx, 'tcx> {
-    fn tcx<'b>(&'b self) -> TyCtxt<'gcx, 'tcx> {
+impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
+    fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
         self.tcx
         }
 
@@ -430,8 +430,8 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionFolder<'a, 'gcx, 'tcx> {
 // Bound vars replacer
 
 /// Replaces the escaping bound vars (late bound regions or bound types) in a type.
-struct BoundVarReplacer<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
-    tcx: TyCtxt<'gcx, 'tcx>,
+struct BoundVarReplacer<'a, 'tcx> {
+    tcx: TyCtxt<'tcx>,
 
     /// As with `RegionFolder`, represents the index of a binder *just outside*
     /// the ones we have visited.
@@ -442,9 +442,9 @@ struct BoundVarReplacer<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
     fld_c: &'a mut (dyn FnMut(ty::BoundVar, Ty<'tcx>) -> &'tcx ty::Const<'tcx> + 'a),
 }
 
-impl<'a, 'gcx, 'tcx> BoundVarReplacer<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> BoundVarReplacer<'a, 'tcx> {
     fn new<F, G, H>(
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         fld_r: &'a mut F,
         fld_t: &'a mut G,
         fld_c: &'a mut H,
@@ -464,8 +464,8 @@ impl<'a, 'gcx, 'tcx> BoundVarReplacer<'a, 'gcx, 'tcx> {
     }
 }
 
-impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for BoundVarReplacer<'a, 'gcx, 'tcx> {
-    fn tcx<'b>(&'b self) -> TyCtxt<'gcx, 'tcx> {
+impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
+    fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
         self.tcx
         }
 
@@ -549,7 +549,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for BoundVarReplacer<'a, 'gcx, 'tcx>
     }
 }
 
-impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
+impl<'tcx> TyCtxt<'tcx> {
     /// Replaces all regions bound by the given `Binder` with the
     /// results returned by the closure; the closure is expected to
     /// return a free region (relative to this binder), and hence the
@@ -729,15 +729,15 @@ enum Direction {
     Out,
 }
 
-struct Shifter<'gcx, 'tcx> {
-    tcx: TyCtxt<'gcx, 'tcx>,
+struct Shifter<'tcx> {
+    tcx: TyCtxt<'tcx>,
     current_index: ty::DebruijnIndex,
     amount: u32,
     direction: Direction,
 }
 
-impl Shifter<'gcx, 'tcx> {
-    pub fn new(tcx: TyCtxt<'gcx, 'tcx>, amount: u32, direction: Direction) -> Self {
+impl Shifter<'tcx> {
+    pub fn new(tcx: TyCtxt<'tcx>, amount: u32, direction: Direction) -> Self {
         Shifter {
             tcx,
             current_index: ty::INNERMOST,
@@ -747,8 +747,8 @@ impl Shifter<'gcx, 'tcx> {
     }
 }
 
-impl TypeFolder<'gcx, 'tcx> for Shifter<'gcx, 'tcx> {
-    fn tcx<'b>(&'b self) -> TyCtxt<'gcx, 'tcx> {
+impl TypeFolder<'tcx> for Shifter<'tcx> {
+    fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
         self.tcx
         }
 
@@ -826,8 +826,8 @@ impl TypeFolder<'gcx, 'tcx> for Shifter<'gcx, 'tcx> {
     }
 }
 
-pub fn shift_region<'gcx, 'tcx>(
-    tcx: TyCtxt<'gcx, 'tcx>,
+pub fn shift_region<'tcx>(
+    tcx: TyCtxt<'tcx>,
     region: ty::Region<'tcx>,
     amount: u32,
 ) -> ty::Region<'tcx> {
@@ -841,7 +841,7 @@ pub fn shift_region<'gcx, 'tcx>(
     }
 }
 
-pub fn shift_vars<'gcx, 'tcx, T>(tcx: TyCtxt<'gcx, 'tcx>, value: &T, amount: u32) -> T
+pub fn shift_vars<'tcx, T>(tcx: TyCtxt<'tcx>, value: &T, amount: u32) -> T
 where
     T: TypeFoldable<'tcx>,
 {
@@ -851,7 +851,7 @@ where
     value.fold_with(&mut Shifter::new(tcx, amount, Direction::In))
 }
 
-pub fn shift_out_vars<'gcx, 'tcx, T>(tcx: TyCtxt<'gcx, 'tcx>, value: &T, amount: u32) -> T
+pub fn shift_out_vars<'tcx, T>(tcx: TyCtxt<'tcx>, value: &T, amount: u32) -> T
 where
     T: TypeFoldable<'tcx>,
 {
diff --git a/src/librustc/ty/inhabitedness/def_id_forest.rs b/src/librustc/ty/inhabitedness/def_id_forest.rs
index 023460096a8..b22bd21e9de 100644
--- a/src/librustc/ty/inhabitedness/def_id_forest.rs
+++ b/src/librustc/ty/inhabitedness/def_id_forest.rs
@@ -21,7 +21,7 @@ pub struct DefIdForest {
     root_ids: SmallVec<[DefId; 1]>,
 }
 
-impl<'gcx, 'tcx> DefIdForest {
+impl<'tcx> DefIdForest {
     /// Creates an empty forest.
     pub fn empty() -> DefIdForest {
         DefIdForest {
@@ -32,7 +32,7 @@ impl<'gcx, 'tcx> DefIdForest {
     /// Creates a forest consisting of a single tree representing the entire
     /// crate.
     #[inline]
-    pub fn full(tcx: TyCtxt<'gcx, 'tcx>) -> DefIdForest {
+    pub fn full(tcx: TyCtxt<'tcx>) -> DefIdForest {
         let crate_id = tcx.hir().local_def_id(CRATE_NODE_ID);
         DefIdForest::from_id(crate_id)
     }
@@ -52,12 +52,12 @@ impl<'gcx, 'tcx> DefIdForest {
     }
 
     /// Tests whether the forest contains a given DefId.
-    pub fn contains(&self, tcx: TyCtxt<'gcx, 'tcx>, id: DefId) -> bool {
+    pub fn contains(&self, tcx: TyCtxt<'tcx>, id: DefId) -> bool {
         self.root_ids.iter().any(|root_id| tcx.is_descendant_of(id, *root_id))
     }
 
     /// Calculate the intersection of a collection of forests.
-    pub fn intersection<I>(tcx: TyCtxt<'gcx, 'tcx>, iter: I) -> DefIdForest
+    pub fn intersection<I>(tcx: TyCtxt<'tcx>, iter: I) -> DefIdForest
     where
         I: IntoIterator<Item = DefIdForest>,
     {
@@ -94,7 +94,7 @@ impl<'gcx, 'tcx> DefIdForest {
     }
 
     /// Calculate the union of a collection of forests.
-    pub fn union<I>(tcx: TyCtxt<'gcx, 'tcx>, iter: I) -> DefIdForest
+    pub fn union<I>(tcx: TyCtxt<'tcx>, iter: I) -> DefIdForest
     where
         I: IntoIterator<Item = DefIdForest>,
     {
diff --git a/src/librustc/ty/inhabitedness/mod.rs b/src/librustc/ty/inhabitedness/mod.rs
index b9e34e0cabc..5ce750849f4 100644
--- a/src/librustc/ty/inhabitedness/mod.rs
+++ b/src/librustc/ty/inhabitedness/mod.rs
@@ -51,7 +51,7 @@ mod def_id_forest;
 // This code should only compile in modules where the uninhabitedness of Foo is
 // visible.
 
-impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
+impl<'tcx> TyCtxt<'tcx> {
     /// Checks whether a type is visibly uninhabited from a particular module.
     /// # Example
     /// ```rust
@@ -106,9 +106,9 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
     }
 }
 
-impl<'gcx, 'tcx> AdtDef {
+impl<'tcx> AdtDef {
     /// Calculate the forest of DefIds from which this adt is visibly uninhabited.
-    fn uninhabited_from(&self, tcx: TyCtxt<'gcx, 'tcx>, substs: SubstsRef<'tcx>) -> DefIdForest {
+    fn uninhabited_from(&self, tcx: TyCtxt<'tcx>, substs: SubstsRef<'tcx>) -> DefIdForest {
         // Non-exhaustive ADTs from other crates are always considered inhabited.
         if self.is_variant_list_non_exhaustive() && !self.did.is_local() {
             DefIdForest::empty()
@@ -120,11 +120,11 @@ impl<'gcx, 'tcx> AdtDef {
     }
 }
 
-impl<'gcx, 'tcx> VariantDef {
+impl<'tcx> VariantDef {
     /// Calculate the forest of DefIds from which this variant is visibly uninhabited.
     pub fn uninhabited_from(
         &self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         substs: SubstsRef<'tcx>,
         adt_kind: AdtKind,
     ) -> DefIdForest {
@@ -146,11 +146,11 @@ impl<'gcx, 'tcx> VariantDef {
     }
 }
 
-impl<'gcx, 'tcx> FieldDef {
+impl<'tcx> FieldDef {
     /// Calculate the forest of DefIds from which this field is visibly uninhabited.
     fn uninhabited_from(
         &self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         substs: SubstsRef<'tcx>,
         is_enum: bool,
     ) -> DefIdForest {
@@ -176,9 +176,9 @@ impl<'gcx, 'tcx> FieldDef {
     }
 }
 
-impl<'gcx, 'tcx> TyS<'tcx> {
+impl<'tcx> TyS<'tcx> {
     /// Calculate the forest of DefIds from which this type is visibly uninhabited.
-    fn uninhabited_from(&self, tcx: TyCtxt<'gcx, 'tcx>) -> DefIdForest {
+    fn uninhabited_from(&self, tcx: TyCtxt<'tcx>) -> DefIdForest {
         match self.sty {
             Adt(def, substs) => def.uninhabited_from(tcx, substs),
 
diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs
index 16df0da8820..457d018f017 100644
--- a/src/librustc/ty/instance.rs
+++ b/src/librustc/ty/instance.rs
@@ -43,7 +43,7 @@ pub enum InstanceDef<'tcx> {
 }
 
 impl<'tcx> Instance<'tcx> {
-    pub fn ty(&self, tcx: TyCtxt<'tcx, 'tcx>) -> Ty<'tcx> {
+    pub fn ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         let ty = tcx.type_of(self.def.def_id());
         tcx.subst_and_normalize_erasing_regions(
             self.substs,
@@ -52,7 +52,7 @@ impl<'tcx> Instance<'tcx> {
         )
     }
 
-    fn fn_sig_noadjust(&self, tcx: TyCtxt<'tcx, 'tcx>) -> PolyFnSig<'tcx> {
+    fn fn_sig_noadjust(&self, tcx: TyCtxt<'tcx>) -> PolyFnSig<'tcx> {
         let ty = self.ty(tcx);
         match ty.sty {
             ty::FnDef(..) |
@@ -102,7 +102,7 @@ impl<'tcx> Instance<'tcx> {
         }
     }
 
-    pub fn fn_sig(&self, tcx: TyCtxt<'tcx, 'tcx>) -> ty::PolyFnSig<'tcx> {
+    pub fn fn_sig(&self, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> {
         let mut fn_sig = self.fn_sig_noadjust(tcx);
         if let InstanceDef::VtableShim(..) = self.def {
             // Modify fn(self, ...) to fn(self: *mut Self, ...)
@@ -133,11 +133,11 @@ impl<'tcx> InstanceDef<'tcx> {
     }
 
     #[inline]
-    pub fn attrs(&self, tcx: TyCtxt<'tcx, 'tcx>) -> ty::Attributes<'tcx> {
+    pub fn attrs(&self, tcx: TyCtxt<'tcx>) -> ty::Attributes<'tcx> {
         tcx.get_attrs(self.def_id())
     }
 
-    pub fn is_inline(&self, tcx: TyCtxt<'tcx, 'tcx>) -> bool {
+    pub fn is_inline(&self, tcx: TyCtxt<'tcx>) -> bool {
         use crate::hir::map::DefPathData;
         let def_id = match *self {
             ty::InstanceDef::Item(def_id) => def_id,
@@ -150,7 +150,7 @@ impl<'tcx> InstanceDef<'tcx> {
         }
     }
 
-    pub fn requires_local(&self, tcx: TyCtxt<'tcx, 'tcx>) -> bool {
+    pub fn requires_local(&self, tcx: TyCtxt<'tcx>) -> bool {
         if self.is_inline(tcx) {
             return true
         }
@@ -200,7 +200,7 @@ impl<'tcx> fmt::Display for Instance<'tcx> {
     }
 }
 
-impl<'b, 'tcx> Instance<'tcx> {
+impl<'tcx> Instance<'tcx> {
     pub fn new(def_id: DefId, substs: SubstsRef<'tcx>)
                -> Instance<'tcx> {
         assert!(!substs.has_escaping_bound_vars(),
@@ -209,7 +209,7 @@ impl<'b, 'tcx> Instance<'tcx> {
         Instance { def: InstanceDef::Item(def_id), substs: substs }
     }
 
-    pub fn mono(tcx: TyCtxt<'tcx, 'b>, def_id: DefId) -> Instance<'tcx> {
+    pub fn mono(tcx: TyCtxt<'tcx>, def_id: DefId) -> Instance<'tcx> {
         Instance::new(def_id, tcx.global_tcx().empty_substs_for_def_id(def_id))
     }
 
@@ -237,7 +237,7 @@ impl<'b, 'tcx> Instance<'tcx> {
     /// in a monomorphic context (i.e., like during codegen), then it is guaranteed to return
     /// `Some`.
     pub fn resolve(
-        tcx: TyCtxt<'tcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         def_id: DefId,
         substs: SubstsRef<'tcx>,
@@ -291,7 +291,7 @@ impl<'b, 'tcx> Instance<'tcx> {
     }
 
     pub fn resolve_for_vtable(
-        tcx: TyCtxt<'tcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         def_id: DefId,
         substs: SubstsRef<'tcx>,
@@ -312,7 +312,7 @@ impl<'b, 'tcx> Instance<'tcx> {
     }
 
     pub fn resolve_closure(
-        tcx: TyCtxt<'tcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         def_id: DefId,
         substs: ty::ClosureSubsts<'tcx>,
         requested_kind: ty::ClosureKind,
@@ -325,14 +325,14 @@ impl<'b, 'tcx> Instance<'tcx> {
         }
     }
 
-    pub fn resolve_drop_in_place(tcx: TyCtxt<'tcx, 'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> {
+    pub fn resolve_drop_in_place(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> {
         let def_id = tcx.require_lang_item(DropInPlaceFnLangItem);
         let substs = tcx.intern_substs(&[ty.into()]);
         Instance::resolve(tcx, ty::ParamEnv::reveal_all(), def_id, substs).unwrap()
     }
 
     pub fn fn_once_adapter_instance(
-        tcx: TyCtxt<'tcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         closure_did: DefId,
         substs: ty::ClosureSubsts<'tcx>,
     ) -> Instance<'tcx> {
@@ -366,7 +366,7 @@ impl<'b, 'tcx> Instance<'tcx> {
 }
 
 fn resolve_associated_item<'tcx>(
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     trait_item: &ty::AssocItem,
     param_env: ty::ParamEnv<'tcx>,
     trait_id: DefId,
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index efbae81a5dd..70db4f19a4c 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -29,10 +29,10 @@ use rustc_target::abi::call::{
 };
 
 pub trait IntegerExt {
-    fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx, 'tcx>, signed: bool) -> Ty<'tcx>;
+    fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>, signed: bool) -> Ty<'tcx>;
     fn from_attr<C: HasDataLayout>(cx: &C, ity: attr::IntType) -> Integer;
     fn repr_discr<'tcx>(
-        tcx: TyCtxt<'tcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         ty: Ty<'tcx>,
         repr: &ReprOptions,
         min: i128,
@@ -41,7 +41,7 @@ pub trait IntegerExt {
 }
 
 impl IntegerExt for Integer {
-    fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx, 'tcx>, signed: bool) -> Ty<'tcx> {
+    fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>, signed: bool) -> Ty<'tcx> {
         match (*self, signed) {
             (I8, false) => tcx.types.u8,
             (I16, false) => tcx.types.u16,
@@ -77,7 +77,7 @@ impl IntegerExt for Integer {
     /// N.B.: u128 values above i128::MAX will be treated as signed, but
     /// that shouldn't affect anything, other than maybe debuginfo.
     fn repr_discr<'tcx>(
-        tcx: TyCtxt<'tcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         ty: Ty<'tcx>,
         repr: &ReprOptions,
         min: i128,
@@ -126,11 +126,11 @@ impl IntegerExt for Integer {
 }
 
 pub trait PrimitiveExt {
-    fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx, 'tcx>) -> Ty<'tcx>;
+    fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx>;
 }
 
 impl PrimitiveExt for Primitive {
-    fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx, 'tcx>) -> Ty<'tcx> {
+    fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         match *self {
             Int(i, signed) => i.to_ty(tcx, signed),
             Float(FloatTy::F32) => tcx.types.f32,
@@ -172,7 +172,7 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> {
 }
 
 fn layout_raw<'tcx>(
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
 ) -> Result<&'tcx LayoutDetails, LayoutError<'tcx>> {
     ty::tls::with_related_context(tcx, move |icx| {
@@ -226,7 +226,7 @@ enum StructKind {
     Prefixed(Size, Align),
 }
 
-impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx, 'tcx>> {
+impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
     fn scalar_pair(&self, a: Scalar, b: Scalar) -> LayoutDetails {
         let dl = self.data_layout();
         let b_align = b.value.align(dl);
@@ -1221,7 +1221,7 @@ enum SavedLocalEligibility {
 // Also included in the layout are the upvars and the discriminant.
 // These are included as fields on the "outer" layout; they are not part
 // of any variant.
-impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx, 'tcx>> {
+impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
     /// Compute the eligibility and assignment of each local.
     fn generator_saved_local_eligibility(&self, info: &GeneratorLayout<'tcx>)
     -> (BitSet<GeneratorSavedLocal>, IndexVec<GeneratorSavedLocal, SavedLocalEligibility>) {
@@ -1606,7 +1606,7 @@ pub enum SizeSkeleton<'tcx> {
 impl<'tcx> SizeSkeleton<'tcx> {
     pub fn compute(
         ty: Ty<'tcx>,
-        tcx: TyCtxt<'tcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
     ) -> Result<SizeSkeleton<'tcx>, LayoutError<'tcx>> {
         debug_assert!(!ty.has_infer_types());
@@ -1728,21 +1728,21 @@ impl<'tcx> SizeSkeleton<'tcx> {
 }
 
 pub trait HasTyCtxt<'tcx>: HasDataLayout {
-    fn tcx(&self) -> TyCtxt<'tcx, 'tcx>;
+    fn tcx(&self) -> TyCtxt<'tcx>;
 }
 
 pub trait HasParamEnv<'tcx> {
     fn param_env(&self) -> ty::ParamEnv<'tcx>;
 }
 
-impl<'gcx, 'tcx> HasDataLayout for TyCtxt<'gcx, 'tcx> {
+impl<'tcx> HasDataLayout for TyCtxt<'tcx> {
     fn data_layout(&self) -> &TargetDataLayout {
         &self.data_layout
     }
 }
 
-impl<'gcx, 'tcx> HasTyCtxt<'gcx> for TyCtxt<'gcx, 'tcx> {
-    fn tcx(&self) -> TyCtxt<'gcx, 'gcx> {
+impl<'tcx> HasTyCtxt<'tcx> for TyCtxt<'tcx> {
+    fn tcx(&self) -> TyCtxt<'tcx> {
         self.global_tcx()
     }
 }
@@ -1759,8 +1759,8 @@ impl<'tcx, T: HasDataLayout> HasDataLayout for LayoutCx<'tcx, T> {
     }
 }
 
-impl<'gcx, 'tcx, T: HasTyCtxt<'gcx>> HasTyCtxt<'gcx> for LayoutCx<'tcx, T> {
-    fn tcx(&self) -> TyCtxt<'gcx, 'gcx> {
+impl<'tcx, T: HasTyCtxt<'tcx>> HasTyCtxt<'tcx> for LayoutCx<'tcx, T> {
+    fn tcx(&self) -> TyCtxt<'tcx> {
         self.tcx.tcx()
     }
 }
@@ -1797,7 +1797,7 @@ impl<T, E> MaybeResult<T> for Result<T, E> {
 
 pub type TyLayout<'tcx> = ::rustc_target::abi::TyLayout<'tcx, Ty<'tcx>>;
 
-impl<'tcx> LayoutOf for LayoutCx<'tcx, TyCtxt<'tcx, 'tcx>> {
+impl<'tcx> LayoutOf for LayoutCx<'tcx, TyCtxt<'tcx>> {
     type Ty = Ty<'tcx>;
     type TyLayout = Result<TyLayout<'tcx>, LayoutError<'tcx>>;
 
@@ -1824,7 +1824,7 @@ impl<'tcx> LayoutOf for LayoutCx<'tcx, TyCtxt<'tcx, 'tcx>> {
     }
 }
 
-impl LayoutOf for LayoutCx<'tcx, ty::query::TyCtxtAt<'tcx, 'tcx>> {
+impl LayoutOf for LayoutCx<'tcx, ty::query::TyCtxtAt<'tcx>> {
     type Ty = Ty<'tcx>;
     type TyLayout = Result<TyLayout<'tcx>, LayoutError<'tcx>>;
 
@@ -1856,7 +1856,7 @@ impl LayoutOf for LayoutCx<'tcx, ty::query::TyCtxtAt<'tcx, 'tcx>> {
 }
 
 // Helper (inherent) `layout_of` methods to avoid pushing `LayoutCx` to users.
-impl TyCtxt<'tcx, '_> {
+impl TyCtxt<'tcx> {
     /// Computes the layout of a type. Note that this implicitly
     /// executes in "reveal all" mode.
     #[inline]
@@ -1870,7 +1870,7 @@ impl TyCtxt<'tcx, '_> {
     }
 }
 
-impl ty::query::TyCtxtAt<'tcx, '_> {
+impl ty::query::TyCtxtAt<'tcx> {
     /// Computes the layout of a type. Note that this implicitly
     /// executes in "reveal all" mode.
     #[inline]
@@ -2190,7 +2190,7 @@ struct Niche {
 impl Niche {
     fn reserve<'tcx>(
         &self,
-        cx: &LayoutCx<'tcx, TyCtxt<'tcx, 'tcx>>,
+        cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
         count: u128,
     ) -> Option<(u128, Scalar)> {
         if count > self.available {
@@ -2206,7 +2206,7 @@ impl Niche {
     }
 }
 
-impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx, 'tcx>> {
+impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
     /// Find the offset of a niche leaf field, starting from
     /// the given type and recursing through aggregates.
     // FIXME(eddyb) traverse already optimized enums.
@@ -2442,23 +2442,23 @@ impl_stable_hash_for!(struct crate::ty::layout::AbiAndPrefAlign {
     pref
 });
 
-impl<'gcx> HashStable<StableHashingContext<'gcx>> for Align {
+impl<'tcx> HashStable<StableHashingContext<'tcx>> for Align {
     fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'gcx>,
+                                          hcx: &mut StableHashingContext<'tcx>,
                                           hasher: &mut StableHasher<W>) {
         self.bytes().hash_stable(hcx, hasher);
     }
 }
 
-impl<'gcx> HashStable<StableHashingContext<'gcx>> for Size {
+impl<'tcx> HashStable<StableHashingContext<'tcx>> for Size {
     fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'gcx>,
+                                          hcx: &mut StableHashingContext<'tcx>,
                                           hasher: &mut StableHasher<W>) {
         self.bytes().hash_stable(hcx, hasher);
     }
 }
 
-impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for LayoutError<'gcx>
+impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for LayoutError<'tcx>
 {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 71955764e10..2e39f045747 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -213,7 +213,7 @@ impl AssocItem {
         }
     }
 
-    pub fn signature<'tcx>(&self, tcx: TyCtxt<'tcx, 'tcx>) -> String {
+    pub fn signature<'tcx>(&self, tcx: TyCtxt<'tcx>) -> String {
         match self.kind {
             ty::AssocKind::Method => {
                 // We skip the binder here because the binder would deanonymize all
@@ -259,14 +259,14 @@ pub trait DefIdTree: Copy {
     }
 }
 
-impl<'gcx, 'tcx> DefIdTree for TyCtxt<'gcx, 'tcx> {
+impl<'tcx> DefIdTree for TyCtxt<'tcx> {
     fn parent(self, id: DefId) -> Option<DefId> {
         self.def_key(id).parent.map(|index| DefId { index: index, ..id })
     }
 }
 
 impl Visibility {
-    pub fn from_hir(visibility: &hir::Visibility, id: hir::HirId, tcx: TyCtxt<'_, '_>) -> Self {
+    pub fn from_hir(visibility: &hir::Visibility, id: hir::HirId, tcx: TyCtxt<'_>) -> Self {
         match visibility.node {
             hir::VisibilityKind::Public => Visibility::Public,
             hir::VisibilityKind::Crate(_) => Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)),
@@ -569,7 +569,7 @@ impl<'tcx> TyS<'tcx> {
     }
 }
 
-impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::TyS<'gcx> {
+impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::TyS<'tcx> {
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
                                           hasher: &mut StableHasher<W>) {
@@ -592,7 +592,7 @@ pub type Ty<'tcx> = &'tcx TyS<'tcx>;
 impl<'tcx> serialize::UseSpecializedEncodable for Ty<'tcx> {}
 impl<'tcx> serialize::UseSpecializedDecodable for Ty<'tcx> {}
 
-pub type CanonicalTy<'gcx> = Canonical<'gcx, Ty<'gcx>>;
+pub type CanonicalTy<'tcx> = Canonical<'tcx, Ty<'tcx>>;
 
 extern {
     /// A dummy type used to force List to by unsized without requiring fat pointers
@@ -912,7 +912,7 @@ pub struct Generics {
     pub has_late_bound_regions: Option<Span>,
 }
 
-impl<'gcx, 'tcx> Generics {
+impl<'tcx> Generics {
     pub fn count(&self) -> usize {
         self.parent_count + self.params.len()
     }
@@ -934,7 +934,7 @@ impl<'gcx, 'tcx> Generics {
         own_counts
     }
 
-    pub fn requires_monomorphization(&self, tcx: TyCtxt<'gcx, 'tcx>) -> bool {
+    pub fn requires_monomorphization(&self, tcx: TyCtxt<'tcx>) -> bool {
         if self.own_requires_monomorphization() {
             return true;
         }
@@ -960,7 +960,7 @@ impl<'gcx, 'tcx> Generics {
     pub fn region_param(
         &'tcx self,
         param: &EarlyBoundRegion,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
     ) -> &'tcx GenericParamDef {
         if let Some(index) = param.index.checked_sub(self.parent_count as u32) {
             let param = &self.params[index as usize];
@@ -978,7 +978,7 @@ impl<'gcx, 'tcx> Generics {
     pub fn type_param(
         &'tcx self,
         param: &ParamTy,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
     ) -> &'tcx GenericParamDef {
         if let Some(index) = param.index.checked_sub(self.parent_count as u32) {
             let param = &self.params[index as usize];
@@ -996,7 +996,7 @@ impl<'gcx, 'tcx> Generics {
     pub fn const_param(
         &'tcx self,
         param: &ParamConst,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
     ) -> &GenericParamDef {
         if let Some(index) = param.index.checked_sub(self.parent_count as u32) {
             let param = &self.params[index as usize];
@@ -1021,10 +1021,10 @@ pub struct GenericPredicates<'tcx> {
 impl<'tcx> serialize::UseSpecializedEncodable for GenericPredicates<'tcx> {}
 impl<'tcx> serialize::UseSpecializedDecodable for GenericPredicates<'tcx> {}
 
-impl<'gcx, 'tcx> GenericPredicates<'tcx> {
+impl<'tcx> GenericPredicates<'tcx> {
     pub fn instantiate(
         &self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         substs: SubstsRef<'tcx>,
     ) -> InstantiatedPredicates<'tcx> {
         let mut instantiated = InstantiatedPredicates::empty();
@@ -1034,7 +1034,7 @@ impl<'gcx, 'tcx> GenericPredicates<'tcx> {
 
     pub fn instantiate_own(
         &self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         substs: SubstsRef<'tcx>,
     ) -> InstantiatedPredicates<'tcx> {
         InstantiatedPredicates {
@@ -1044,7 +1044,7 @@ impl<'gcx, 'tcx> GenericPredicates<'tcx> {
 
     fn instantiate_into(
         &self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         instantiated: &mut InstantiatedPredicates<'tcx>,
         substs: SubstsRef<'tcx>,
     ) {
@@ -1056,7 +1056,7 @@ impl<'gcx, 'tcx> GenericPredicates<'tcx> {
         );
     }
 
-    pub fn instantiate_identity(&self, tcx: TyCtxt<'gcx, 'tcx>) -> InstantiatedPredicates<'tcx> {
+    pub fn instantiate_identity(&self, tcx: TyCtxt<'tcx>) -> InstantiatedPredicates<'tcx> {
         let mut instantiated = InstantiatedPredicates::empty();
         self.instantiate_identity_into(tcx, &mut instantiated);
         instantiated
@@ -1064,7 +1064,7 @@ impl<'gcx, 'tcx> GenericPredicates<'tcx> {
 
     fn instantiate_identity_into(
         &self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         instantiated: &mut InstantiatedPredicates<'tcx>,
     ) {
         if let Some(def_id) = self.parent {
@@ -1075,7 +1075,7 @@ impl<'gcx, 'tcx> GenericPredicates<'tcx> {
 
     pub fn instantiate_supertrait(
         &self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         poly_trait_ref: &ty::PolyTraitRef<'tcx>,
     ) -> InstantiatedPredicates<'tcx> {
         assert_eq!(self.parent, None);
@@ -1142,7 +1142,7 @@ impl<'tcx> AsRef<Predicate<'tcx>> for Predicate<'tcx> {
     }
 }
 
-impl<'gcx, 'tcx> Predicate<'tcx> {
+impl<'tcx> Predicate<'tcx> {
     /// Performs a substitution suitable for going from a
     /// poly-trait-ref to supertraits that must hold if that
     /// poly-trait-ref holds. This is slightly different from a normal
@@ -1150,7 +1150,7 @@ impl<'gcx, 'tcx> Predicate<'tcx> {
     /// lengthy comment below for details.
     pub fn subst_supertrait(
         &self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         trait_ref: &ty::PolyTraitRef<'tcx>,
     ) -> ty::Predicate<'tcx> {
         // The interaction between HRTB and supertraits is not entirely
@@ -1309,7 +1309,7 @@ impl<'tcx> PolyProjectionPredicate<'tcx> {
     }
 
     #[inline]
-    pub fn to_poly_trait_ref(&self, tcx: TyCtxt<'_, '_>) -> PolyTraitRef<'tcx> {
+    pub fn to_poly_trait_ref(&self, tcx: TyCtxt<'_>) -> PolyTraitRef<'tcx> {
         // Note: unlike with `TraitRef::to_poly_trait_ref()`,
         // `self.0.trait_ref` is permitted to have escaping regions.
         // This is because here `self` has a `Binder` and so does our
@@ -1771,7 +1771,7 @@ impl<'tcx, T> ParamEnvAnd<'tcx, T> {
     }
 }
 
-impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>> for ParamEnvAnd<'gcx, T>
+impl<'a, 'tcx, T> HashStable<StableHashingContext<'a>> for ParamEnvAnd<'tcx, T>
     where T: HashStable<StableHashingContext<'a>>
 {
     fn hash_stable<W: StableHasherResult>(&self,
@@ -1853,7 +1853,7 @@ pub struct VariantDef {
     pub recovered: bool,
 }
 
-impl<'gcx, 'tcx> VariantDef {
+impl<'tcx> VariantDef {
     /// Creates a new `VariantDef`.
     ///
     /// `variant_did` is the `DefId` that identifies the enum variant (if this `VariantDef`
@@ -1871,7 +1871,7 @@ impl<'gcx, 'tcx> VariantDef {
     /// If someone speeds up attribute loading to not be a performance concern, they can
     /// remove this hack and use the constructor `DefId` everywhere.
     pub fn new(
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         ident: Ident,
         variant_did: Option<DefId>,
         ctor_def_id: Option<DefId>,
@@ -2084,7 +2084,7 @@ impl_stable_hash_for!(struct ReprOptions {
 });
 
 impl ReprOptions {
-    pub fn new(tcx: TyCtxt<'_, '_>, did: DefId) -> ReprOptions {
+    pub fn new(tcx: TyCtxt<'_>, did: DefId) -> ReprOptions {
         let mut flags = ReprFlags::empty();
         let mut size = None;
         let mut max_align = 0;
@@ -2157,10 +2157,10 @@ impl ReprOptions {
     }
 }
 
-impl<'gcx, 'tcx> AdtDef {
+impl<'tcx> AdtDef {
     /// Creates a new `AdtDef`.
     fn new(
-        tcx: TyCtxt<'_, '_>,
+        tcx: TyCtxt<'_>,
         did: DefId,
         kind: AdtKind,
         variants: IndexVec<VariantIdx, VariantDef>,
@@ -2300,7 +2300,7 @@ impl<'gcx, 'tcx> AdtDef {
     }
 
     /// Returns `true` if this type has a destructor.
-    pub fn has_dtor(&self, tcx: TyCtxt<'gcx, 'tcx>) -> bool {
+    pub fn has_dtor(&self, tcx: TyCtxt<'tcx>) -> bool {
         self.destructor(tcx).is_some()
     }
 
@@ -2311,7 +2311,7 @@ impl<'gcx, 'tcx> AdtDef {
     }
 
     #[inline]
-    pub fn predicates(&self, tcx: TyCtxt<'gcx, 'tcx>) -> &'tcx GenericPredicates<'gcx> {
+    pub fn predicates(&self, tcx: TyCtxt<'tcx>) -> &'tcx GenericPredicates<'tcx> {
         tcx.predicates_of(self.did)
     }
 
@@ -2365,7 +2365,7 @@ impl<'gcx, 'tcx> AdtDef {
     #[inline]
     pub fn eval_explicit_discr(
         &self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         expr_did: DefId,
     ) -> Option<Discr<'tcx>> {
         let param_env = ParamEnv::empty();
@@ -2412,8 +2412,8 @@ impl<'gcx, 'tcx> AdtDef {
     #[inline]
     pub fn discriminants(
         &'tcx self,
-        tcx: TyCtxt<'gcx, 'tcx>,
-    ) -> impl Iterator<Item = (VariantIdx, Discr<'tcx>)> + Captures<'gcx> {
+        tcx: TyCtxt<'tcx>,
+    ) -> impl Iterator<Item = (VariantIdx, Discr<'tcx>)> + Captures<'tcx> {
         let repr_type = self.repr.discr_type();
         let initial = repr_type.initial_discriminant(tcx.global_tcx());
         let mut prev_discr = None::<Discr<'tcx>>;
@@ -2443,7 +2443,7 @@ impl<'gcx, 'tcx> AdtDef {
     #[inline]
     pub fn discriminant_for_variant(
         &self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         variant_index: VariantIdx,
     ) -> Discr<'tcx> {
         let (val, offset) = self.discriminant_def_for_variant(variant_index);
@@ -2480,7 +2480,7 @@ impl<'gcx, 'tcx> AdtDef {
         (expr_did, variant_index.as_u32() - explicit_index)
     }
 
-    pub fn destructor(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Destructor> {
+    pub fn destructor(&self, tcx: TyCtxt<'tcx>) -> Option<Destructor> {
         tcx.adt_destructor(self.did)
     }
 
@@ -2494,11 +2494,11 @@ impl<'gcx, 'tcx> AdtDef {
     ///
     /// Due to normalization being eager, this applies even if
     /// the associated type is behind a pointer (e.g., issue #31299).
-    pub fn sized_constraint(&self, tcx: TyCtxt<'gcx, 'tcx>) -> &'tcx [Ty<'tcx>] {
+    pub fn sized_constraint(&self, tcx: TyCtxt<'tcx>) -> &'tcx [Ty<'tcx>] {
         tcx.adt_sized_constraint(self.did).0
     }
 
-    fn sized_constraint_for_ty(&self, tcx: TyCtxt<'tcx, 'tcx>, ty: Ty<'tcx>) -> Vec<Ty<'tcx>> {
+    fn sized_constraint_for_ty(&self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Vec<Ty<'tcx>> {
         let result = match ty.sty {
             Bool | Char | Int(..) | Uint(..) | Float(..) |
             RawPtr(..) | Ref(..) | FnDef(..) | FnPtr(_) |
@@ -2575,8 +2575,8 @@ impl<'gcx, 'tcx> AdtDef {
     }
 }
 
-impl<'gcx, 'tcx> FieldDef {
-    pub fn ty(&self, tcx: TyCtxt<'gcx, 'tcx>, subst: SubstsRef<'tcx>) -> Ty<'tcx> {
+impl<'tcx> FieldDef {
+    pub fn ty(&self, tcx: TyCtxt<'tcx>, subst: SubstsRef<'tcx>) -> Ty<'tcx> {
         tcx.type_of(self.did).subst(tcx, subst)
     }
 }
@@ -2602,7 +2602,7 @@ impl<'tcx> ClosureKind {
     // This is the initial value used when doing upvar inference.
     pub const LATTICE_BOTTOM: ClosureKind = ClosureKind::Fn;
 
-    pub fn trait_did(&self, tcx: TyCtxt<'tcx, 'tcx>) -> DefId {
+    pub fn trait_did(&self, tcx: TyCtxt<'tcx>) -> DefId {
         match *self {
             ClosureKind::Fn => tcx.require_lang_item(FnTraitLangItem),
             ClosureKind::FnMut => {
@@ -2630,7 +2630,7 @@ impl<'tcx> ClosureKind {
 
     /// Returns the representative scalar type for this closure kind.
     /// See `TyS::to_opt_closure_kind` for more details.
-    pub fn to_ty(self, tcx: TyCtxt<'_, 'tcx>) -> Ty<'tcx> {
+    pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         match self {
             ty::ClosureKind::Fn => tcx.types.i8,
             ty::ClosureKind::FnMut => tcx.types.i16,
@@ -2712,12 +2712,12 @@ impl BorrowKind {
 }
 
 #[derive(Debug, Clone)]
-pub enum Attributes<'gcx> {
+pub enum Attributes<'tcx> {
     Owned(Lrc<[ast::Attribute]>),
-    Borrowed(&'gcx [ast::Attribute])
+    Borrowed(&'tcx [ast::Attribute])
 }
 
-impl<'gcx> ::std::ops::Deref for Attributes<'gcx> {
+impl<'tcx> ::std::ops::Deref for Attributes<'tcx> {
     type Target = [ast::Attribute];
 
     fn deref(&self) -> &[ast::Attribute] {
@@ -2767,15 +2767,15 @@ pub enum ImplOverlapKind {
     Issue33140
 }
 
-impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
-    pub fn body_tables(self, body: hir::BodyId) -> &'gcx TypeckTables<'gcx> {
+impl<'tcx> TyCtxt<'tcx> {
+    pub fn body_tables(self, body: hir::BodyId) -> &'tcx TypeckTables<'tcx> {
         self.typeck_tables_of(self.hir().body_owner_def_id(body))
     }
 
     /// Returns an iterator of the `DefId`s for all body-owners in this
     /// crate. If you would prefer to iterate over the bodies
     /// themselves, you can do `self.hir().krate().body_ids.iter()`.
-    pub fn body_owners(self) -> impl Iterator<Item = DefId> + Captures<'gcx> + 'tcx {
+    pub fn body_owners(self) -> impl Iterator<Item = DefId> + Captures<'tcx> + 'tcx {
         self.hir().krate()
                   .body_ids
                   .iter()
@@ -2899,7 +2899,7 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
         })
     }
 
-    pub fn associated_items(self, def_id: DefId) -> AssocItemsIterator<'gcx, 'tcx> {
+    pub fn associated_items(self, def_id: DefId) -> AssocItemsIterator<'tcx> {
         // Ideally, we would use `-> impl Iterator` here, but it falls
         // afoul of the conservative "capture [restrictions]" we put
         // in place, so we use a hand-written iterator.
@@ -3007,8 +3007,8 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
     }
 
     /// Returns the possibly-auto-generated MIR of a `(DefId, Subst)` pair.
-    pub fn instance_mir(self, instance: ty::InstanceDef<'gcx>)
-                        -> &'gcx Body<'gcx>
+    pub fn instance_mir(self, instance: ty::InstanceDef<'tcx>)
+                        -> &'tcx Body<'tcx>
     {
         match instance {
             ty::InstanceDef::Item(did) => {
@@ -3027,7 +3027,7 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
     }
 
     /// Gets the attributes of a definition.
-    pub fn get_attrs(self, did: DefId) -> Attributes<'gcx> {
+    pub fn get_attrs(self, did: DefId) -> Attributes<'tcx> {
         if let Some(id) = self.hir().as_local_hir_id(did) {
             Attributes::Borrowed(self.hir().attrs_by_hir_id(id))
         } else {
@@ -3122,13 +3122,13 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
     }
 }
 
-pub struct AssocItemsIterator<'gcx, 'tcx> {
-    tcx: TyCtxt<'gcx, 'tcx>,
-    def_ids: &'gcx [DefId],
+pub struct AssocItemsIterator<'tcx> {
+    tcx: TyCtxt<'tcx>,
+    def_ids: &'tcx [DefId],
     next_index: usize,
 }
 
-impl Iterator for AssocItemsIterator<'_, '_> {
+impl Iterator for AssocItemsIterator<'_> {
     type Item = AssocItem;
 
     fn next(&mut self) -> Option<AssocItem> {
@@ -3138,7 +3138,7 @@ impl Iterator for AssocItemsIterator<'_, '_> {
     }
 }
 
-fn associated_item<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, def_id: DefId) -> AssocItem {
+fn associated_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> AssocItem {
     let id = tcx.hir().as_local_hir_id(def_id).unwrap();
     let parent_id = tcx.hir().get_parent_item(id);
     let parent_def_id = tcx.hir().local_def_id_from_hir_id(parent_id);
@@ -3183,7 +3183,7 @@ pub struct AdtSizedConstraint<'tcx>(pub &'tcx [Ty<'tcx>]);
 ///       such.
 ///     - a Error, if a type contained itself. The representability
 ///       check should catch this case.
-fn adt_sized_constraint<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, def_id: DefId) -> AdtSizedConstraint<'tcx> {
+fn adt_sized_constraint<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> AdtSizedConstraint<'tcx> {
     let def = tcx.adt_def(def_id);
 
     let result = tcx.mk_type_list(def.variants.iter().flat_map(|v| {
@@ -3197,7 +3197,7 @@ fn adt_sized_constraint<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, def_id: DefId) -> AdtSize
     AdtSizedConstraint(result)
 }
 
-fn associated_item_def_ids<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, def_id: DefId) -> &'tcx [DefId] {
+fn associated_item_def_ids<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx [DefId] {
     let id = tcx.hir().as_local_hir_id(def_id).unwrap();
     let item = tcx.hir().expect_item_by_hir_id(id);
     match item.node {
@@ -3220,14 +3220,14 @@ fn associated_item_def_ids<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, def_id: DefId) -> &'tc
     }
 }
 
-fn def_span<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, def_id: DefId) -> Span {
+fn def_span<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Span {
     tcx.hir().span_if_local(def_id).unwrap()
 }
 
 /// If the given `DefId` describes an item belonging to a trait,
 /// returns the `DefId` of the trait that the trait item belongs to;
 /// otherwise, returns `None`.
-fn trait_of_item<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, def_id: DefId) -> Option<DefId> {
+fn trait_of_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<DefId> {
     tcx.opt_associated_item(def_id)
         .and_then(|associated_item| {
             match associated_item.container {
@@ -3238,7 +3238,7 @@ fn trait_of_item<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, def_id: DefId) -> Option<DefId>
 }
 
 /// Yields the parent function's `DefId` if `def_id` is an `impl Trait` definition.
-pub fn is_impl_trait_defn(tcx: TyCtxt<'_, '_>, def_id: DefId) -> Option<DefId> {
+pub fn is_impl_trait_defn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> {
     if let Some(hir_id) = tcx.hir().as_local_hir_id(def_id) {
         if let Node::Item(item) = tcx.hir().get_by_hir_id(hir_id) {
             if let hir::ItemKind::Existential(ref exist_ty) = item.node {
@@ -3250,7 +3250,7 @@ pub fn is_impl_trait_defn(tcx: TyCtxt<'_, '_>, def_id: DefId) -> Option<DefId> {
 }
 
 /// See `ParamEnv` struct definition for details.
-fn param_env<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, def_id: DefId) -> ParamEnv<'tcx> {
+fn param_env<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ParamEnv<'tcx> {
     // The param_env of an impl Trait type is its defining function's param_env
     if let Some(parent) = is_impl_trait_defn(tcx, def_id) {
         return param_env(tcx, parent);
@@ -3285,23 +3285,23 @@ fn param_env<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, def_id: DefId) -> ParamEnv<'tcx> {
     traits::normalize_param_env_or_error(tcx, def_id, unnormalized_env, cause)
 }
 
-fn crate_disambiguator<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, crate_num: CrateNum) -> CrateDisambiguator {
+fn crate_disambiguator<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> CrateDisambiguator {
     assert_eq!(crate_num, LOCAL_CRATE);
     tcx.sess.local_crate_disambiguator()
 }
 
-fn original_crate_name<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, crate_num: CrateNum) -> Symbol {
+fn original_crate_name<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> Symbol {
     assert_eq!(crate_num, LOCAL_CRATE);
     tcx.crate_name.clone()
 }
 
-fn crate_hash<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, crate_num: CrateNum) -> Svh {
+fn crate_hash<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> Svh {
     assert_eq!(crate_num, LOCAL_CRATE);
     tcx.hir().crate_hash
 }
 
 fn instance_def_size_estimate<'tcx>(
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     instance_def: InstanceDef<'tcx>,
 ) -> usize {
     match instance_def {
@@ -3318,7 +3318,7 @@ fn instance_def_size_estimate<'tcx>(
 /// If `def_id` is an issue 33140 hack impl, returns its self type; otherwise, returns `None`.
 ///
 /// See [`ImplOverlapKind::Issue33140`] for more details.
-fn issue33140_self_ty<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, def_id: DefId) -> Option<Ty<'tcx>> {
+fn issue33140_self_ty<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> Option<Ty<'tcx>> {
     debug!("issue33140_self_ty({:?})", def_id);
 
     let trait_ref = tcx.impl_trait_ref(def_id).unwrap_or_else(|| {
diff --git a/src/librustc/ty/outlives.rs b/src/librustc/ty/outlives.rs
index c24c0541ad7..7d1403d1e96 100644
--- a/src/librustc/ty/outlives.rs
+++ b/src/librustc/ty/outlives.rs
@@ -45,7 +45,7 @@ pub enum Component<'tcx> {
     EscapingProjection(Vec<Component<'tcx>>),
 }
 
-impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
+impl<'tcx> TyCtxt<'tcx> {
     /// Push onto `out` all the things that must outlive `'a` for the condition
     /// `ty0: 'a` to hold. Note that `ty0` must be a **fully resolved type**.
     pub fn push_outlives_components(&self, ty0: Ty<'tcx>,
diff --git a/src/librustc/ty/print/mod.rs b/src/librustc/ty/print/mod.rs
index d5bca55c2f1..8e157bdd259 100644
--- a/src/librustc/ty/print/mod.rs
+++ b/src/librustc/ty/print/mod.rs
@@ -13,7 +13,7 @@ pub mod obsolete;
 
 // FIXME(eddyb) false positive, the lifetime parameters are used with `P:  Printer<...>`.
 #[allow(unused_lifetimes)]
-pub trait Print<'gcx, 'tcx, P> {
+pub trait Print<'tcx, P> {
     type Output;
     type Error;
 
@@ -28,7 +28,7 @@ pub trait Print<'gcx, 'tcx, P> {
 ///
 /// For pretty-printing/formatting in particular, see `PrettyPrinter`.
 // FIXME(eddyb) find a better name, this is more general than "printing".
-pub trait Printer<'gcx: 'tcx, 'tcx>: Sized {
+pub trait Printer<'tcx>: Sized {
     type Error;
 
     type Path;
@@ -37,7 +37,7 @@ pub trait Printer<'gcx: 'tcx, 'tcx>: Sized {
     type DynExistential;
     type Const;
 
-    fn tcx(&'a self) -> TyCtxt<'gcx, 'tcx>;
+    fn tcx(&'a self) -> TyCtxt<'tcx>;
 
     fn print_def_path(
         self,
@@ -302,7 +302,7 @@ pub fn characteristic_def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
     }
 }
 
-impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for ty::RegionKind {
+impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for ty::RegionKind {
     type Output = P::Region;
     type Error = P::Error;
     fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
@@ -310,7 +310,7 @@ impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for ty::Regi
     }
 }
 
-impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for ty::Region<'_> {
+impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for ty::Region<'_> {
     type Output = P::Region;
     type Error = P::Error;
     fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
@@ -318,7 +318,7 @@ impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for ty::Regi
     }
 }
 
-impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for Ty<'tcx> {
+impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for Ty<'tcx> {
     type Output = P::Type;
     type Error = P::Error;
     fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
@@ -326,7 +326,7 @@ impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for Ty<'tcx>
     }
 }
 
-impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P>
+impl<'tcx, P: Printer<'tcx>> Print<'tcx, P>
     for &'tcx ty::List<ty::ExistentialPredicate<'tcx>>
 {
     type Output = P::DynExistential;
@@ -336,7 +336,7 @@ impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P>
     }
 }
 
-impl<'gcx: 'tcx, 'tcx, P: Printer<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for &'tcx ty::Const<'tcx> {
+impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for &'tcx ty::Const<'tcx> {
     type Output = P::Const;
     type Error = P::Error;
     fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
diff --git a/src/librustc/ty/print/obsolete.rs b/src/librustc/ty/print/obsolete.rs
index a320eb47e6c..2bfe35d4f1c 100644
--- a/src/librustc/ty/print/obsolete.rs
+++ b/src/librustc/ty/print/obsolete.rs
@@ -17,14 +17,14 @@ use syntax::ast;
 /// Same as `unique_type_name()` but with the result pushed onto the given
 /// `output` parameter.
 pub struct DefPathBasedNames<'tcx> {
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     omit_disambiguators: bool,
     omit_local_crate_name: bool,
 }
 
 impl DefPathBasedNames<'tcx> {
     pub fn new(
-        tcx: TyCtxt<'tcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         omit_disambiguators: bool,
         omit_local_crate_name: bool,
     ) -> Self {
diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs
index d55f1c89836..95c5048b378 100644
--- a/src/librustc/ty/print/pretty.rs
+++ b/src/librustc/ty/print/pretty.rs
@@ -166,8 +166,8 @@ impl RegionHighlightMode {
 }
 
 /// Trait for printers that pretty-print using `fmt::Write` to the printer.
-pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>:
-    Printer<'gcx, 'tcx,
+pub trait PrettyPrinter<'tcx>:
+    Printer<'tcx,
         Error = fmt::Error,
         Path = Self,
         Region = Self,
@@ -190,7 +190,7 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>:
         self,
         value: &ty::Binder<T>,
     ) -> Result<Self, Self::Error>
-        where T: Print<'gcx, 'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>
+        where T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>
     {
         value.skip_binder().print(self)
     }
@@ -200,7 +200,7 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>:
         mut self,
         mut elems: impl Iterator<Item = T>,
     ) -> Result<Self, Self::Error>
-        where T: Print<'gcx, 'tcx, Self, Output = Self, Error = Self::Error>
+        where T: Print<'tcx, Self, Output = Self, Error = Self::Error>
     {
         if let Some(first) = elems.next() {
             self = first.print(self)?;
@@ -931,10 +931,10 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>:
 }
 
 // HACK(eddyb) boxed to avoid moving around a large struct by-value.
-pub struct FmtPrinter<'a, 'gcx, 'tcx, F>(Box<FmtPrinterData<'a, 'gcx, 'tcx, F>>);
+pub struct FmtPrinter<'a, 'tcx, F>(Box<FmtPrinterData<'a, 'tcx, F>>);
 
-pub struct FmtPrinterData<'a, 'gcx, 'tcx, F> {
-    tcx: TyCtxt<'gcx, 'tcx>,
+pub struct FmtPrinterData<'a, 'tcx, F> {
+    tcx: TyCtxt<'tcx>,
     fmt: F,
 
     empty_path: bool,
@@ -949,21 +949,21 @@ pub struct FmtPrinterData<'a, 'gcx, 'tcx, F> {
     pub name_resolver: Option<Box<&'a dyn Fn(ty::sty::TyVid) -> Option<String>>>,
 }
 
-impl<F> Deref for FmtPrinter<'a, 'gcx, 'tcx, F> {
-    type Target = FmtPrinterData<'a, 'gcx, 'tcx, F>;
+impl<F> Deref for FmtPrinter<'a, 'tcx, F> {
+    type Target = FmtPrinterData<'a, 'tcx, F>;
     fn deref(&self) -> &Self::Target {
         &self.0
     }
 }
 
-impl<F> DerefMut for FmtPrinter<'_, '_, '_, F> {
+impl<F> DerefMut for FmtPrinter<'_, '_, F> {
     fn deref_mut(&mut self) -> &mut Self::Target {
         &mut self.0
     }
 }
 
-impl<F> FmtPrinter<'a, 'gcx, 'tcx, F> {
-    pub fn new(tcx: TyCtxt<'gcx, 'tcx>, fmt: F, ns: Namespace) -> Self {
+impl<F> FmtPrinter<'a, 'tcx, F> {
+    pub fn new(tcx: TyCtxt<'tcx>, fmt: F, ns: Namespace) -> Self {
         FmtPrinter(Box::new(FmtPrinterData {
             tcx,
             fmt,
@@ -978,7 +978,7 @@ impl<F> FmtPrinter<'a, 'gcx, 'tcx, F> {
     }
 }
 
-impl TyCtxt<'_, '_> {
+impl TyCtxt<'_> {
     // HACK(eddyb) get rid of `def_path_str` and/or pass `Namespace` explicitly always
     // (but also some things just print a `DefId` generally so maybe we need this?)
     fn guess_def_namespace(self, def_id: DefId) -> Namespace {
@@ -1010,13 +1010,13 @@ impl TyCtxt<'_, '_> {
     }
 }
 
-impl<F: fmt::Write> fmt::Write for FmtPrinter<'_, '_, '_, F> {
+impl<F: fmt::Write> fmt::Write for FmtPrinter<'_, '_, F> {
     fn write_str(&mut self, s: &str) -> fmt::Result {
         self.fmt.write_str(s)
     }
 }
 
-impl<F: fmt::Write> Printer<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F> {
+impl<F: fmt::Write> Printer<'tcx> for FmtPrinter<'_, 'tcx, F> {
     type Error = fmt::Error;
 
     type Path = Self;
@@ -1025,7 +1025,7 @@ impl<F: fmt::Write> Printer<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F> {
     type DynExistential = Self;
     type Const = Self;
 
-    fn tcx(&'a self) -> TyCtxt<'gcx, 'tcx> {
+    fn tcx(&'a self) -> TyCtxt<'tcx> {
         self.tcx
     }
 
@@ -1222,7 +1222,7 @@ impl<F: fmt::Write> Printer<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F> {
     }
 }
 
-impl<F: fmt::Write> PrettyPrinter<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F> {
+impl<F: fmt::Write> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> {
     fn infer_ty_name(&self, id: ty::TyVid) -> Option<String> {
         self.0.name_resolver.as_ref().and_then(|func| func(id))
     }
@@ -1243,7 +1243,7 @@ impl<F: fmt::Write> PrettyPrinter<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F>
         self,
         value: &ty::Binder<T>,
     ) -> Result<Self, Self::Error>
-        where T: Print<'gcx, 'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>
+        where T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>
     {
         self.pretty_in_binder(value)
     }
@@ -1317,7 +1317,7 @@ impl<F: fmt::Write> PrettyPrinter<'gcx, 'tcx> for FmtPrinter<'_, 'gcx, 'tcx, F>
 }
 
 // HACK(eddyb) limited to `FmtPrinter` because of `region_highlight_mode`.
-impl<F: fmt::Write> FmtPrinter<'_, '_, '_, F> {
+impl<F: fmt::Write> FmtPrinter<'_, '_, F> {
     pub fn pretty_print_region(
         mut self,
         region: ty::Region<'_>,
@@ -1416,12 +1416,12 @@ impl<F: fmt::Write> FmtPrinter<'_, '_, '_, F> {
 
 // HACK(eddyb) limited to `FmtPrinter` because of `binder_depth`,
 // `region_index` and `used_region_names`.
-impl<F: fmt::Write> FmtPrinter<'_, 'gcx, 'tcx, F> {
+impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
     pub fn pretty_in_binder<T>(
         mut self,
         value: &ty::Binder<T>,
     ) -> Result<Self, fmt::Error>
-        where T: Print<'gcx, 'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>
+        where T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>
     {
         fn name_by_region_index(index: usize) -> InternedString {
             match index {
@@ -1510,9 +1510,9 @@ impl<F: fmt::Write> FmtPrinter<'_, 'gcx, 'tcx, F> {
     }
 }
 
-impl<'gcx: 'tcx, 'tcx, T, P: PrettyPrinter<'gcx, 'tcx>> Print<'gcx, 'tcx, P>
+impl<'tcx, T, P: PrettyPrinter<'tcx>> Print<'tcx, P>
     for ty::Binder<T>
-    where T: Print<'gcx, 'tcx, P, Output = P, Error = P::Error> + TypeFoldable<'tcx>
+    where T: Print<'tcx, P, Output = P, Error = P::Error> + TypeFoldable<'tcx>
 {
     type Output = P;
     type Error = P::Error;
@@ -1521,10 +1521,10 @@ impl<'gcx: 'tcx, 'tcx, T, P: PrettyPrinter<'gcx, 'tcx>> Print<'gcx, 'tcx, P>
     }
 }
 
-impl<'gcx: 'tcx, 'tcx, T, U, P: PrettyPrinter<'gcx, 'tcx>> Print<'gcx, 'tcx, P>
+impl<'tcx, T, U, P: PrettyPrinter<'tcx>> Print<'tcx, P>
     for ty::OutlivesPredicate<T, U>
-    where T: Print<'gcx, 'tcx, P, Output = P, Error = P::Error>,
-          U: Print<'gcx, 'tcx, P, Output = P, Error = P::Error>,
+    where T: Print<'tcx, P, Output = P, Error = P::Error>,
+          U: Print<'tcx, P, Output = P, Error = P::Error>,
 {
     type Output = P;
     type Error = P::Error;
@@ -1552,7 +1552,7 @@ macro_rules! forward_display_to_print {
 
 macro_rules! define_print_and_forward_display {
     (($self:ident, $cx:ident): $($ty:ty $print:block)+) => {
-        $(impl<'gcx: 'tcx, 'tcx, P: PrettyPrinter<'gcx, 'tcx>> Print<'gcx, 'tcx, P> for $ty {
+        $(impl<'tcx, P: PrettyPrinter<'tcx>> Print<'tcx, P> for $ty {
             type Output = P;
             type Error = fmt::Error;
             fn print(&$self, $cx: P) -> Result<Self::Output, Self::Error> {
@@ -1585,7 +1585,7 @@ forward_display_to_print! {
     &'tcx ty::Const<'tcx>,
 
     // HACK(eddyb) these are exhaustive instead of generic,
-    // because `for<'gcx: 'tcx, 'tcx>` isn't possible yet.
+    // because `for<'tcx>` isn't possible yet.
     ty::Binder<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>,
     ty::Binder<ty::TraitRef<'tcx>>,
     ty::Binder<ty::FnSig<'tcx>>,
diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs
index bd5f33eea7b..13d93f173e8 100644
--- a/src/librustc/ty/query/config.rs
+++ b/src/librustc/ty/query/config.rs
@@ -31,36 +31,36 @@ pub(crate) trait QueryAccessors<'tcx>: QueryConfig<'tcx> {
     fn query(key: Self::Key) -> Query<'tcx>;
 
     // Don't use this method to access query results, instead use the methods on TyCtxt
-    fn query_cache<'a>(tcx: TyCtxt<'tcx, '_>) -> &'a Lock<QueryCache<'tcx, Self>>;
+    fn query_cache<'a>(tcx: TyCtxt<'tcx>) -> &'a Lock<QueryCache<'tcx, Self>>;
 
-    fn to_dep_node(tcx: TyCtxt<'tcx, '_>, key: &Self::Key) -> DepNode;
+    fn to_dep_node(tcx: TyCtxt<'tcx>, key: &Self::Key) -> DepNode;
 
     // Don't use this method to compute query results, instead use the methods on TyCtxt
-    fn compute(tcx: TyCtxt<'tcx, '_>, key: Self::Key) -> Self::Value;
+    fn compute(tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value;
 
     fn hash_result(
         hcx: &mut StableHashingContext<'_>,
         result: &Self::Value
     ) -> Option<Fingerprint>;
 
-    fn handle_cycle_error(tcx: TyCtxt<'tcx, '_>, error: CycleError<'tcx>) -> Self::Value;
+    fn handle_cycle_error(tcx: TyCtxt<'tcx>, error: CycleError<'tcx>) -> Self::Value;
 }
 
 pub(crate) trait QueryDescription<'tcx>: QueryAccessors<'tcx> {
-    fn describe(tcx: TyCtxt<'_, '_>, key: Self::Key) -> Cow<'static, str>;
+    fn describe(tcx: TyCtxt<'_>, key: Self::Key) -> Cow<'static, str>;
 
     #[inline]
-    fn cache_on_disk(_: TyCtxt<'tcx, 'tcx>, _: Self::Key) -> bool {
+    fn cache_on_disk(_: TyCtxt<'tcx>, _: Self::Key) -> bool {
         false
     }
 
-    fn try_load_from_disk(_: TyCtxt<'tcx, 'tcx>, _: SerializedDepNodeIndex) -> Option<Self::Value> {
+    fn try_load_from_disk(_: TyCtxt<'tcx>, _: SerializedDepNodeIndex) -> Option<Self::Value> {
         bug!("QueryDescription::load_from_disk() called for an unsupported query.")
     }
 }
 
 impl<'tcx, M: QueryAccessors<'tcx, Key = DefId>> QueryDescription<'tcx> for M {
-    default fn describe(tcx: TyCtxt<'_, '_>, def_id: DefId) -> Cow<'static, str> {
+    default fn describe(tcx: TyCtxt<'_>, def_id: DefId) -> Cow<'static, str> {
         if !tcx.sess.verbose() {
             format!("processing `{}`", tcx.def_path_str(def_id)).into()
         } else {
@@ -71,7 +71,7 @@ impl<'tcx, M: QueryAccessors<'tcx, Key = DefId>> QueryDescription<'tcx> for M {
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::analysis<'tcx> {
-    fn describe(_tcx: TyCtxt<'_, '_>, _: CrateNum) -> Cow<'static, str> {
+    fn describe(_tcx: TyCtxt<'_>, _: CrateNum) -> Cow<'static, str> {
         "running analysis passes on this crate".into()
     }
 }
@@ -80,12 +80,12 @@ macro_rules! impl_disk_cacheable_query(
     ($query_name:ident, |$tcx:tt, $key:tt| $cond:expr) => {
         impl<'tcx> QueryDescription<'tcx> for queries::$query_name<'tcx> {
             #[inline]
-            fn cache_on_disk($tcx: TyCtxt<'tcx, 'tcx>, $key: Self::Key) -> bool {
+            fn cache_on_disk($tcx: TyCtxt<'tcx>, $key: Self::Key) -> bool {
                 $cond
             }
 
             #[inline]
-            fn try_load_from_disk(tcx: TyCtxt<'tcx, 'tcx>,
+            fn try_load_from_disk(tcx: TyCtxt<'tcx>,
                                       id: SerializedDepNodeIndex)
                                       -> Option<Self::Value> {
                 tcx.queries.on_disk_cache.try_load_query_result(tcx, id)
diff --git a/src/librustc/ty/query/job.rs b/src/librustc/ty/query/job.rs
index f300d82e372..3d00de8c8c1 100644
--- a/src/librustc/ty/query/job.rs
+++ b/src/librustc/ty/query/job.rs
@@ -75,9 +75,9 @@ impl<'tcx> QueryJob<'tcx> {
 
     /// Awaits for the query job to complete.
     #[cfg(parallel_compiler)]
-    pub(super) fn r#await<'lcx>(
+    pub(super) fn r#await(
         &self,
-        tcx: TyCtxt<'tcx, 'lcx>,
+        tcx: TyCtxt<'tcx>,
         span: Span,
     ) -> Result<(), CycleError<'tcx>> {
         tls::with_related_context(tcx, move |icx| {
@@ -100,9 +100,9 @@ impl<'tcx> QueryJob<'tcx> {
     }
 
     #[cfg(not(parallel_compiler))]
-    pub(super) fn find_cycle_in_stack<'lcx>(
+    pub(super) fn find_cycle_in_stack(
         &self,
-        tcx: TyCtxt<'tcx, 'lcx>,
+        tcx: TyCtxt<'tcx>,
         span: Span,
     ) -> CycleError<'tcx> {
         // Get the current executing query (waiter) and find the waitee amongst its parents
@@ -338,7 +338,7 @@ fn connected_to_root<'tcx>(
 // Deterministically pick an query from a list
 #[cfg(parallel_compiler)]
 fn pick_query<'a, 'tcx, T, F: Fn(&T) -> (Span, Lrc<QueryJob<'tcx>>)>(
-    tcx: TyCtxt<'tcx, '_>,
+    tcx: TyCtxt<'tcx>,
     queries: &'a [T],
     f: F,
 ) -> &'a T {
@@ -366,7 +366,7 @@ fn pick_query<'a, 'tcx, T, F: Fn(&T) -> (Span, Lrc<QueryJob<'tcx>>)>(
 fn remove_cycle<'tcx>(
     jobs: &mut Vec<Lrc<QueryJob<'tcx>>>,
     wakelist: &mut Vec<Lrc<QueryWaiter<'tcx>>>,
-    tcx: TyCtxt<'tcx, '_>,
+    tcx: TyCtxt<'tcx>,
 ) -> bool {
     let mut visited = FxHashSet::default();
     let mut stack = Vec::new();
@@ -505,7 +505,7 @@ pub unsafe fn handle_deadlock() {
 /// There may be multiple cycles involved in a deadlock, so this searches
 /// all active queries for cycles before finally resuming all the waiters at once.
 #[cfg(parallel_compiler)]
-fn deadlock(tcx: TyCtxt<'_, '_>, registry: &rayon_core::Registry) {
+fn deadlock(tcx: TyCtxt<'_>, registry: &rayon_core::Registry) {
     let on_panic = OnDrop(|| {
         eprintln!("deadlock handler panicked, aborting process");
         process::abort();
diff --git a/src/librustc/ty/query/keys.rs b/src/librustc/ty/query/keys.rs
index af13bbc24ef..30a3e53dddf 100644
--- a/src/librustc/ty/query/keys.rs
+++ b/src/librustc/ty/query/keys.rs
@@ -22,7 +22,7 @@ pub(super) trait Key: Clone + Hash + Eq + Debug {
 
     /// In the event that a cycle occurs, if no explicit span has been
     /// given for a query with key `self`, what span should we use?
-    fn default_span(&self, tcx: TyCtxt<'_, '_>) -> Span;
+    fn default_span(&self, tcx: TyCtxt<'_>) -> Span;
 }
 
 impl<'tcx> Key for ty::InstanceDef<'tcx> {
@@ -30,7 +30,7 @@ impl<'tcx> Key for ty::InstanceDef<'tcx> {
         LOCAL_CRATE
     }
 
-    fn default_span(&self, tcx: TyCtxt<'_, '_>) -> Span {
+    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
         tcx.def_span(self.def_id())
     }
 }
@@ -40,7 +40,7 @@ impl<'tcx> Key for ty::Instance<'tcx> {
         LOCAL_CRATE
     }
 
-    fn default_span(&self, tcx: TyCtxt<'_, '_>) -> Span {
+    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
         tcx.def_span(self.def_id())
     }
 }
@@ -50,7 +50,7 @@ impl<'tcx> Key for mir::interpret::GlobalId<'tcx> {
         self.instance.query_crate()
     }
 
-    fn default_span(&self, tcx: TyCtxt<'_, '_>) -> Span {
+    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
         self.instance.default_span(tcx)
     }
 }
@@ -59,7 +59,7 @@ impl Key for CrateNum {
     fn query_crate(&self) -> CrateNum {
         *self
     }
-    fn default_span(&self, _: TyCtxt<'_, '_>) -> Span {
+    fn default_span(&self, _: TyCtxt<'_>) -> Span {
         DUMMY_SP
     }
 }
@@ -68,7 +68,7 @@ impl Key for DefIndex {
     fn query_crate(&self) -> CrateNum {
         LOCAL_CRATE
     }
-    fn default_span(&self, _tcx: TyCtxt<'_, '_>) -> Span {
+    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
         DUMMY_SP
     }
 }
@@ -77,7 +77,7 @@ impl Key for DefId {
     fn query_crate(&self) -> CrateNum {
         self.krate
     }
-    fn default_span(&self, tcx: TyCtxt<'_, '_>) -> Span {
+    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
         tcx.def_span(*self)
     }
 }
@@ -86,7 +86,7 @@ impl Key for (DefId, DefId) {
     fn query_crate(&self) -> CrateNum {
         self.0.krate
     }
-    fn default_span(&self, tcx: TyCtxt<'_, '_>) -> Span {
+    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
         self.1.default_span(tcx)
     }
 }
@@ -95,7 +95,7 @@ impl Key for (CrateNum, DefId) {
     fn query_crate(&self) -> CrateNum {
         self.0
     }
-    fn default_span(&self, tcx: TyCtxt<'_, '_>) -> Span {
+    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
         self.1.default_span(tcx)
     }
 }
@@ -104,7 +104,7 @@ impl Key for (DefId, SimplifiedType) {
     fn query_crate(&self) -> CrateNum {
         self.0.krate
     }
-    fn default_span(&self, tcx: TyCtxt<'_, '_>) -> Span {
+    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
         self.0.default_span(tcx)
     }
 }
@@ -113,7 +113,7 @@ impl<'tcx> Key for (DefId, SubstsRef<'tcx>) {
     fn query_crate(&self) -> CrateNum {
         self.0.krate
     }
-    fn default_span(&self, tcx: TyCtxt<'_, '_>) -> Span {
+    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
         self.0.default_span(tcx)
     }
 }
@@ -122,7 +122,7 @@ impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) {
     fn query_crate(&self) -> CrateNum {
         self.1.def_id().krate
     }
-    fn default_span(&self, tcx: TyCtxt<'_, '_>) -> Span {
+    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
         tcx.def_span(self.1.def_id())
     }
 }
@@ -131,7 +131,7 @@ impl<'tcx> Key for (&'tcx ty::Const<'tcx>, mir::Field) {
     fn query_crate(&self) -> CrateNum {
         LOCAL_CRATE
     }
-    fn default_span(&self, _: TyCtxt<'_, '_>) -> Span {
+    fn default_span(&self, _: TyCtxt<'_>) -> Span {
         DUMMY_SP
     }
 }
@@ -140,7 +140,7 @@ impl<'tcx> Key for ty::PolyTraitRef<'tcx> {
     fn query_crate(&self) -> CrateNum {
         self.def_id().krate
     }
-    fn default_span(&self, tcx: TyCtxt<'_, '_>) -> Span {
+    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
         tcx.def_span(self.def_id())
     }
 }
@@ -149,7 +149,7 @@ impl<'tcx> Key for ty::Const<'tcx> {
     fn query_crate(&self) -> CrateNum {
         LOCAL_CRATE
     }
-    fn default_span(&self, _: TyCtxt<'_, '_>) -> Span {
+    fn default_span(&self, _: TyCtxt<'_>) -> Span {
         DUMMY_SP
     }
 }
@@ -158,7 +158,7 @@ impl<'tcx> Key for Ty<'tcx> {
     fn query_crate(&self) -> CrateNum {
         LOCAL_CRATE
     }
-    fn default_span(&self, _: TyCtxt<'_, '_>) -> Span {
+    fn default_span(&self, _: TyCtxt<'_>) -> Span {
         DUMMY_SP
     }
 }
@@ -167,7 +167,7 @@ impl<'tcx> Key for ty::ParamEnv<'tcx> {
     fn query_crate(&self) -> CrateNum {
         LOCAL_CRATE
     }
-    fn default_span(&self, _: TyCtxt<'_, '_>) -> Span {
+    fn default_span(&self, _: TyCtxt<'_>) -> Span {
         DUMMY_SP
     }
 }
@@ -176,7 +176,7 @@ impl<'tcx, T: Key> Key for ty::ParamEnvAnd<'tcx, T> {
     fn query_crate(&self) -> CrateNum {
         self.value.query_crate()
     }
-    fn default_span(&self, tcx: TyCtxt<'_, '_>) -> Span {
+    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
         self.value.default_span(tcx)
     }
 }
@@ -185,7 +185,7 @@ impl<'tcx> Key for traits::Environment<'tcx> {
     fn query_crate(&self) -> CrateNum {
         LOCAL_CRATE
     }
-    fn default_span(&self, _: TyCtxt<'_, '_>) -> Span {
+    fn default_span(&self, _: TyCtxt<'_>) -> Span {
         DUMMY_SP
     }
 }
@@ -194,7 +194,7 @@ impl Key for InternedString {
     fn query_crate(&self) -> CrateNum {
         LOCAL_CRATE
     }
-    fn default_span(&self, _tcx: TyCtxt<'_, '_>) -> Span {
+    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
         DUMMY_SP
     }
 }
@@ -209,7 +209,7 @@ where
         LOCAL_CRATE
     }
 
-    fn default_span(&self, _tcx: TyCtxt<'_, '_>) -> Span {
+    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
         DUMMY_SP
     }
 }
diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs
index bc28396a6f9..72ebd3276c7 100644
--- a/src/librustc/ty/query/on_disk_cache.rs
+++ b/src/librustc/ty/query/on_disk_cache.rs
@@ -158,7 +158,7 @@ impl<'sess> OnDiskCache<'sess> {
 
     pub fn serialize<'tcx, E>(
         &self,
-        tcx: TyCtxt<'tcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         encoder: &mut E,
     ) -> Result<(), E::Error>
     where
@@ -316,7 +316,7 @@ impl<'sess> OnDiskCache<'sess> {
 
             return Ok(());
 
-            fn sorted_cnums_including_local_crate(tcx: TyCtxt<'_, '_>) -> Vec<CrateNum> {
+            fn sorted_cnums_including_local_crate(tcx: TyCtxt<'_>) -> Vec<CrateNum> {
                 let mut cnums = vec![LOCAL_CRATE];
                 cnums.extend_from_slice(&tcx.crates()[..]);
                 cnums.sort_unstable();
@@ -330,7 +330,7 @@ impl<'sess> OnDiskCache<'sess> {
     /// Loads a diagnostic emitted during the previous compilation session.
     pub fn load_diagnostics<'tcx>(
         &self,
-        tcx: TyCtxt<'tcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         dep_node_index: SerializedDepNodeIndex,
     ) -> Vec<Diagnostic> {
         let diagnostics: Option<EncodedDiagnostics> = self.load_indexed(
@@ -359,7 +359,7 @@ impl<'sess> OnDiskCache<'sess> {
     /// the given `SerializedDepNodeIndex`; otherwise returns `None`.
     pub fn try_load_query_result<'tcx, T>(
         &self,
-        tcx: TyCtxt<'tcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         dep_node_index: SerializedDepNodeIndex,
     ) -> Option<T>
     where
@@ -389,7 +389,7 @@ impl<'sess> OnDiskCache<'sess> {
 
     fn load_indexed<'tcx, T>(
         &self,
-        tcx: TyCtxt<'tcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         dep_node_index: SerializedDepNodeIndex,
         index: &FxHashMap<SerializedDepNodeIndex, AbsoluteBytePos>,
         debug_tag: &'static str,
@@ -430,7 +430,7 @@ impl<'sess> OnDiskCache<'sess> {
     // Session that don't occur in the current one. For these, the mapping
     // maps to None.
     fn compute_cnum_map(
-        tcx: TyCtxt<'_, '_>,
+        tcx: TyCtxt<'_>,
         prev_cnums: &[(u32, String, CrateDisambiguator)],
     ) -> IndexVec<CrateNum, Option<CrateNum>> {
         tcx.dep_graph.with_ignore(|| {
@@ -464,7 +464,7 @@ impl<'sess> OnDiskCache<'sess> {
 /// we use for crate metadata decoding in that it can rebase spans and
 /// eventually will also handle things that contain `Ty` instances.
 struct CacheDecoder<'a, 'tcx> {
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     opaque: opaque::Decoder<'a>,
     source_map: &'a SourceMap,
     cnum_map: &'a IndexVec<CrateNum, Option<CrateNum>>,
@@ -532,7 +532,7 @@ fn decode_tagged<'a, 'tcx, D, T, V>(decoder: &mut D,
 
 impl<'a, 'tcx> ty_codec::TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> {
     #[inline]
-    fn tcx(&self) -> TyCtxt<'tcx, 'tcx> {
+    fn tcx(&self) -> TyCtxt<'tcx> {
         self.tcx
     }
 
@@ -751,7 +751,7 @@ impl<'a, 'tcx, T: Decodable> SpecializedDecoder<mir::ClearCrossCrate<T>>
 //- ENCODING -------------------------------------------------------------------
 
 struct CacheEncoder<'a, 'tcx, E: ty_codec::TyEncoder> {
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     encoder: &'a mut E,
     type_shorthands: FxHashMap<Ty<'tcx>, usize>,
     predicate_shorthands: FxHashMap<ty::Predicate<'tcx>, usize>,
@@ -1080,7 +1080,7 @@ impl<'a> SpecializedDecoder<IntEncodedWithFixedSize> for opaque::Decoder<'a> {
 }
 
 fn encode_query_results<'a, 'tcx, Q, E>(
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     encoder: &mut CacheEncoder<'a, 'tcx, E>,
     query_result_index: &mut EncodedQueryResultIndex,
 ) -> Result<(), E::Error>
diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs
index 662d653b2a1..0051832c5df 100644
--- a/src/librustc/ty/query/plumbing.rs
+++ b/src/librustc/ty/query/plumbing.rs
@@ -105,7 +105,7 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
     /// for some compile-time benchmarks.
     #[inline(always)]
     pub(super) fn try_get(
-        tcx: TyCtxt<'tcx, '_>,
+        tcx: TyCtxt<'tcx>,
         span: Span,
         key: &Q::Key,
     ) -> TryGetJob<'a, 'tcx, Q> {
@@ -247,22 +247,22 @@ pub(super) enum TryGetJob<'a, 'tcx: 'a, D: QueryDescription<'tcx> + 'a> {
     Cycle(D::Value),
 }
 
-impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
+impl<'tcx> TyCtxt<'tcx> {
     /// Executes a job by changing the ImplicitCtxt to point to the
     /// new query job while it executes. It returns the diagnostics
     /// captured during execution and the actual result.
     #[inline(always)]
     pub(super) fn start_query<F, R>(
         self,
-        job: Lrc<QueryJob<'gcx>>,
+        job: Lrc<QueryJob<'tcx>>,
         diagnostics: Option<&Lock<ThinVec<Diagnostic>>>,
         compute: F,
     ) -> R
     where
-        F: for<'lcx> FnOnce(TyCtxt<'gcx, 'lcx>) -> R,
+        F: FnOnce(TyCtxt<'tcx>) -> R,
     {
         // The TyCtxt stored in TLS has the same global interner lifetime
-        // as `self`, so we use `with_related_context` to relate the 'gcx lifetimes
+        // as `self`, so we use `with_related_context` to relate the 'tcx lifetimes
         // when accessing the ImplicitCtxt
         tls::with_related_context(self, move |current_icx| {
             // Update the ImplicitCtxt to point to our new query job
@@ -285,11 +285,11 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
     #[cold]
     pub(super) fn report_cycle(
         self,
-        CycleError { usage, cycle: stack }: CycleError<'gcx>,
+        CycleError { usage, cycle: stack }: CycleError<'tcx>,
     ) -> DiagnosticBuilder<'tcx> {
         assert!(!stack.is_empty());
 
-        let fix_span = |span: Span, query: &Query<'gcx>| {
+        let fix_span = |span: Span, query: &Query<'tcx>| {
             self.sess.source_map().def_span(query.default_span(self, span))
         };
 
@@ -351,7 +351,7 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
     }
 
     #[inline(never)]
-    pub(super) fn get_query<Q: QueryDescription<'gcx>>(
+    pub(super) fn get_query<Q: QueryDescription<'tcx>>(
         self,
         span: Span,
         key: Q::Key)
@@ -439,7 +439,7 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
         result
     }
 
-    fn load_from_disk_and_cache_in_memory<Q: QueryDescription<'gcx>>(
+    fn load_from_disk_and_cache_in_memory<Q: QueryDescription<'tcx>>(
         self,
         key: Q::Key,
         prev_dep_node_index: SerializedDepNodeIndex,
@@ -507,7 +507,7 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
 
     #[inline(never)]
     #[cold]
-    fn incremental_verify_ich<Q: QueryDescription<'gcx>>(
+    fn incremental_verify_ich<Q: QueryDescription<'tcx>>(
         self,
         result: &Q::Value,
         dep_node: &DepNode,
@@ -533,10 +533,10 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
     }
 
     #[inline(always)]
-    fn force_query_with_job<Q: QueryDescription<'gcx>>(
+    fn force_query_with_job<Q: QueryDescription<'tcx>>(
         self,
         key: Q::Key,
-        job: JobOwner<'_, 'gcx, Q>,
+        job: JobOwner<'_, 'tcx, Q>,
         dep_node: DepNode)
     -> (Q::Value, DepNodeIndex) {
         // If the following assertion triggers, it can have two reasons:
@@ -597,7 +597,7 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
     /// side-effects -- e.g., in order to report errors for erroneous programs.
     ///
     /// Note: The optimization is only available during incr. comp.
-    pub(super) fn ensure_query<Q: QueryDescription<'gcx>>(self, key: Q::Key) -> () {
+    pub(super) fn ensure_query<Q: QueryDescription<'tcx>>(self, key: Q::Key) -> () {
         let dep_node = Q::to_dep_node(self, &key);
 
         if dep_node.kind.is_eval_always() {
@@ -623,7 +623,7 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
     }
 
     #[allow(dead_code)]
-    fn force_query<Q: QueryDescription<'gcx>>(
+    fn force_query<Q: QueryDescription<'tcx>>(
         self,
         key: Q::Key,
         span: Span,
@@ -873,7 +873,7 @@ macro_rules! define_queries_inner {
                 }
             }
 
-            pub fn describe(&self, tcx: TyCtxt<'_, '_>) -> Cow<'static, str> {
+            pub fn describe(&self, tcx: TyCtxt<'_>) -> Cow<'static, str> {
                 let (r, name) = match *self {
                     $(Query::$name(key) => {
                         (queries::$name::describe(tcx, key), stringify!($name))
@@ -887,7 +887,7 @@ macro_rules! define_queries_inner {
             }
 
             // FIXME(eddyb) Get more valid Span's on queries.
-            pub fn default_span(&self, tcx: TyCtxt<$tcx, '_>, span: Span) -> Span {
+            pub fn default_span(&self, tcx: TyCtxt<$tcx>, span: Span) -> Span {
                 if !span.is_dummy() {
                     return span;
                 }
@@ -953,20 +953,20 @@ macro_rules! define_queries_inner {
             }
 
             #[inline(always)]
-            fn query_cache<'a>(tcx: TyCtxt<$tcx, '_>) -> &'a Lock<QueryCache<$tcx, Self>> {
+            fn query_cache<'a>(tcx: TyCtxt<$tcx>) -> &'a Lock<QueryCache<$tcx, Self>> {
                 &tcx.queries.$name
             }
 
             #[allow(unused)]
             #[inline(always)]
-            fn to_dep_node(tcx: TyCtxt<$tcx, '_>, key: &Self::Key) -> DepNode {
+            fn to_dep_node(tcx: TyCtxt<$tcx>, key: &Self::Key) -> DepNode {
                 use crate::dep_graph::DepConstructor::*;
 
                 DepNode::new(tcx, $node(*key))
             }
 
             #[inline]
-            fn compute(tcx: TyCtxt<'tcx, '_>, key: Self::Key) -> Self::Value {
+            fn compute(tcx: TyCtxt<'tcx>, key: Self::Key) -> Self::Value {
                 __query_compute::$name(move || {
                     let provider = tcx.queries.providers.get(key.query_crate())
                         // HACK(eddyb) it's possible crates may be loaded after
@@ -987,7 +987,7 @@ macro_rules! define_queries_inner {
             }
 
             fn handle_cycle_error(
-                tcx: TyCtxt<'tcx, '_>,
+                tcx: TyCtxt<'tcx>,
                 error: CycleError<'tcx>
             ) -> Self::Value {
                 handle_cycle_error!([$($modifiers)*][tcx, error])
@@ -995,11 +995,11 @@ macro_rules! define_queries_inner {
         })*
 
         #[derive(Copy, Clone)]
-        pub struct TyCtxtEnsure<'gcx, 'tcx> {
-            pub tcx: TyCtxt<'gcx, 'tcx>,
+        pub struct TyCtxtEnsure<'tcx> {
+            pub tcx: TyCtxt<'tcx>,
         }
 
-        impl TyCtxtEnsure<$tcx, 'lcx> {
+        impl TyCtxtEnsure<$tcx> {
             $($(#[$attr])*
             #[inline(always)]
             pub fn $name(self, key: $K) {
@@ -1008,24 +1008,24 @@ macro_rules! define_queries_inner {
         }
 
         #[derive(Copy, Clone)]
-        pub struct TyCtxtAt<'gcx, 'tcx> {
-            pub tcx: TyCtxt<'gcx, 'tcx>,
+        pub struct TyCtxtAt<'tcx> {
+            pub tcx: TyCtxt<'tcx>,
             pub span: Span,
         }
 
-        impl Deref for TyCtxtAt<'gcx, 'tcx> {
-            type Target = TyCtxt<'gcx, 'tcx>;
+        impl Deref for TyCtxtAt<'tcx> {
+            type Target = TyCtxt<'tcx>;
             #[inline(always)]
             fn deref(&self) -> &Self::Target {
                 &self.tcx
             }
         }
 
-        impl TyCtxt<$tcx, 'lcx> {
+        impl TyCtxt<$tcx> {
             /// Returns a transparent wrapper for `TyCtxt`, which ensures queries
             /// are executed instead of just returing their results.
             #[inline(always)]
-            pub fn ensure(self) -> TyCtxtEnsure<$tcx, 'lcx> {
+            pub fn ensure(self) -> TyCtxtEnsure<$tcx> {
                 TyCtxtEnsure {
                     tcx: self,
                 }
@@ -1034,7 +1034,7 @@ macro_rules! define_queries_inner {
             /// Returns a transparent wrapper for `TyCtxt` which uses
             /// `span` as the location of queries performed through it.
             #[inline(always)]
-            pub fn at(self, span: Span) -> TyCtxtAt<$tcx, 'lcx> {
+            pub fn at(self, span: Span) -> TyCtxtAt<$tcx> {
                 TyCtxtAt {
                     tcx: self,
                     span
@@ -1048,7 +1048,7 @@ macro_rules! define_queries_inner {
             })*
         }
 
-        impl TyCtxtAt<$tcx, 'lcx> {
+        impl TyCtxtAt<$tcx> {
             $($(#[$attr])*
             #[inline(always)]
             pub fn $name(self, key: $K) -> $V {
@@ -1089,12 +1089,12 @@ macro_rules! define_provider_struct {
     (tcx: $tcx:tt,
      input: ($(([$($modifiers:tt)*] [$name:ident] [$K:ty] [$R:ty]))*)) => {
         pub struct Providers<$tcx> {
-            $(pub $name: fn(TyCtxt<$tcx, $tcx>, $K) -> $R,)*
+            $(pub $name: fn(TyCtxt<$tcx>, $K) -> $R,)*
         }
 
         impl<$tcx> Default for Providers<$tcx> {
             fn default() -> Self {
-                $(fn $name<$tcx>(_: TyCtxt<$tcx, $tcx>, key: $K) -> $R {
+                $(fn $name<$tcx>(_: TyCtxt<$tcx>, key: $K) -> $R {
                     bug!("tcx.{}({:?}) unsupported by its crate",
                          stringify!($name), key);
                 })*
@@ -1147,7 +1147,7 @@ macro_rules! define_provider_struct {
 /// then `force_from_dep_node()` should not fail for it. Otherwise, you can just
 /// add it to the "We don't have enough information to reconstruct..." group in
 /// the match below.
-pub fn force_from_dep_node<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, dep_node: &DepNode) -> bool {
+pub fn force_from_dep_node<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> bool {
     use crate::dep_graph::RecoverKey;
 
     // We must avoid ever having to call force_from_dep_node() for a
@@ -1233,7 +1233,7 @@ macro_rules! impl_load_from_cache {
         impl DepNode {
             // Check whether the query invocation corresponding to the given
             // DepNode is eligible for on-disk-caching.
-            pub fn cache_on_disk(&self, tcx: TyCtxt<'_, '_>) -> bool {
+            pub fn cache_on_disk(&self, tcx: TyCtxt<'_>) -> bool {
                 use crate::ty::query::queries;
                 use crate::ty::query::QueryDescription;
 
@@ -1251,7 +1251,7 @@ macro_rules! impl_load_from_cache {
             // above `cache_on_disk` methods returns true.
             // Also, as a sanity check, it expects that the corresponding query
             // invocation has been marked as green already.
-            pub fn load_from_on_disk_cache(&self, tcx: TyCtxt<'_, '_>) {
+            pub fn load_from_on_disk_cache(&self, tcx: TyCtxt<'_>) {
                 match self.kind {
                     $(DepKind::$dep_kind => {
                         debug_assert!(tcx.dep_graph
diff --git a/src/librustc/ty/query/values.rs b/src/librustc/ty/query/values.rs
index 5c6b2e172d3..0149f757164 100644
--- a/src/librustc/ty/query/values.rs
+++ b/src/librustc/ty/query/values.rs
@@ -4,36 +4,36 @@ use crate::ty::util::NeedsDrop;
 use syntax::symbol::InternedString;
 
 pub(super) trait Value<'tcx>: Sized {
-    fn from_cycle_error(tcx: TyCtxt<'tcx, 'tcx>) -> Self;
+    fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self;
 }
 
 impl<'tcx, T> Value<'tcx> for T {
-    default fn from_cycle_error(tcx: TyCtxt<'tcx, 'tcx>) -> T {
+    default fn from_cycle_error(tcx: TyCtxt<'tcx>) -> T {
         tcx.sess.abort_if_errors();
         bug!("Value::from_cycle_error called without errors");
     }
 }
 
 impl<'tcx> Value<'tcx> for Ty<'tcx> {
-    fn from_cycle_error(tcx: TyCtxt<'tcx, 'tcx>) -> Ty<'tcx> {
+    fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         tcx.types.err
     }
 }
 
 impl<'tcx> Value<'tcx> for ty::SymbolName {
-    fn from_cycle_error(_: TyCtxt<'tcx, 'tcx>) -> Self {
+    fn from_cycle_error(_: TyCtxt<'tcx>) -> Self {
         ty::SymbolName { name: InternedString::intern("<error>") }
     }
 }
 
 impl<'tcx> Value<'tcx> for NeedsDrop {
-    fn from_cycle_error(_: TyCtxt<'tcx, 'tcx>) -> Self {
+    fn from_cycle_error(_: TyCtxt<'tcx>) -> Self {
         NeedsDrop(false)
     }
 }
 
 impl<'tcx> Value<'tcx> for AdtSizedConstraint<'tcx> {
-    fn from_cycle_error(tcx: TyCtxt<'tcx, 'tcx>) -> Self {
+    fn from_cycle_error(tcx: TyCtxt<'tcx>) -> Self {
         AdtSizedConstraint(tcx.intern_type_list(&[tcx.types.err]))
     }
 }
diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs
index 2bd38ff70d4..98fd5d1a981 100644
--- a/src/librustc/ty/relate.rs
+++ b/src/librustc/ty/relate.rs
@@ -22,8 +22,8 @@ pub enum Cause {
     ExistentialRegionBound, // relating an existential region bound
 }
 
-pub trait TypeRelation<'gcx: 'tcx, 'tcx>: Sized {
-    fn tcx(&self) -> TyCtxt<'gcx, 'tcx>;
+pub trait TypeRelation<'tcx>: Sized {
+    fn tcx(&self) -> TyCtxt<'tcx>;
 
     /// Returns a static string we can use for printouts.
     fn tag(&self) -> &'static str;
@@ -94,27 +94,22 @@ pub trait TypeRelation<'gcx: 'tcx, 'tcx>: Sized {
 }
 
 pub trait Relate<'tcx>: TypeFoldable<'tcx> {
-    fn relate<'a, 'gcx, R>(relation: &mut R, a: &Self, b: &Self) -> RelateResult<'tcx, Self>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'a + 'tcx,
-        'tcx: 'a;
+    fn relate<R: TypeRelation<'tcx>>(
+        relation: &mut R,
+        a: &Self,
+        b: &Self,
+    ) -> RelateResult<'tcx, Self>;
 }
 
 ///////////////////////////////////////////////////////////////////////////
 // Relate impls
 
 impl<'tcx> Relate<'tcx> for ty::TypeAndMut<'tcx> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &ty::TypeAndMut<'tcx>,
         b: &ty::TypeAndMut<'tcx>,
-    ) -> RelateResult<'tcx, ty::TypeAndMut<'tcx>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'a + 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, ty::TypeAndMut<'tcx>> {
         debug!("{}.mts({:?}, {:?})",
                relation.tag(),
                a,
@@ -133,17 +128,12 @@ impl<'tcx> Relate<'tcx> for ty::TypeAndMut<'tcx> {
     }
 }
 
-pub fn relate_substs<'a, 'gcx, 'tcx, R>(
+pub fn relate_substs<R: TypeRelation<'tcx>>(
     relation: &mut R,
     variances: Option<&[ty::Variance]>,
     a_subst: SubstsRef<'tcx>,
     b_subst: SubstsRef<'tcx>,
-) -> RelateResult<'tcx, SubstsRef<'tcx>>
-where
-    R: TypeRelation<'gcx, 'tcx>,
-    'gcx: 'a + 'tcx,
-    'tcx: 'a,
-{
+) -> RelateResult<'tcx, SubstsRef<'tcx>> {
     let tcx = relation.tcx();
 
     let params = a_subst.iter().zip(b_subst).enumerate().map(|(i, (a, b))| {
@@ -155,16 +145,11 @@ where
 }
 
 impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &ty::FnSig<'tcx>,
         b: &ty::FnSig<'tcx>,
-    ) -> RelateResult<'tcx, ty::FnSig<'tcx>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'a + 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, ty::FnSig<'tcx>> {
         let tcx = relation.tcx();
 
         if a.c_variadic != b.c_variadic {
@@ -199,16 +184,11 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
 }
 
 impl<'tcx> Relate<'tcx> for ast::Unsafety {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &ast::Unsafety,
         b: &ast::Unsafety,
-    ) -> RelateResult<'tcx, ast::Unsafety>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'a + 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, ast::Unsafety> {
         if a != b {
             Err(TypeError::UnsafetyMismatch(expected_found(relation, a, b)))
         } else {
@@ -218,16 +198,11 @@ impl<'tcx> Relate<'tcx> for ast::Unsafety {
 }
 
 impl<'tcx> Relate<'tcx> for abi::Abi {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &abi::Abi,
         b: &abi::Abi,
-    ) -> RelateResult<'tcx, abi::Abi>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'a + 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, abi::Abi> {
         if a == b {
             Ok(*a)
         } else {
@@ -237,16 +212,11 @@ impl<'tcx> Relate<'tcx> for abi::Abi {
 }
 
 impl<'tcx> Relate<'tcx> for ty::ProjectionTy<'tcx> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &ty::ProjectionTy<'tcx>,
         b: &ty::ProjectionTy<'tcx>,
-    ) -> RelateResult<'tcx, ty::ProjectionTy<'tcx>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'a + 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, ty::ProjectionTy<'tcx>> {
         if a.item_def_id != b.item_def_id {
             Err(TypeError::ProjectionMismatched(
                 expected_found(relation, &a.item_def_id, &b.item_def_id)))
@@ -261,16 +231,11 @@ impl<'tcx> Relate<'tcx> for ty::ProjectionTy<'tcx> {
 }
 
 impl<'tcx> Relate<'tcx> for ty::ExistentialProjection<'tcx> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &ty::ExistentialProjection<'tcx>,
         b: &ty::ExistentialProjection<'tcx>,
-    ) -> RelateResult<'tcx, ty::ExistentialProjection<'tcx>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'a + 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, ty::ExistentialProjection<'tcx>> {
         if a.item_def_id != b.item_def_id {
             Err(TypeError::ProjectionMismatched(
                 expected_found(relation, &a.item_def_id, &b.item_def_id)))
@@ -287,16 +252,11 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialProjection<'tcx> {
 }
 
 impl<'tcx> Relate<'tcx> for Vec<ty::PolyExistentialProjection<'tcx>> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &Vec<ty::PolyExistentialProjection<'tcx>>,
         b: &Vec<ty::PolyExistentialProjection<'tcx>>,
-    ) -> RelateResult<'tcx, Vec<ty::PolyExistentialProjection<'tcx>>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'a + 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, Vec<ty::PolyExistentialProjection<'tcx>>> {
         // To be compatible, `a` and `b` must be for precisely the
         // same set of traits and item names. We always require that
         // projection bounds lists are sorted by trait-def-id and item-name,
@@ -314,16 +274,11 @@ impl<'tcx> Relate<'tcx> for Vec<ty::PolyExistentialProjection<'tcx>> {
 }
 
 impl<'tcx> Relate<'tcx> for ty::TraitRef<'tcx> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &ty::TraitRef<'tcx>,
         b: &ty::TraitRef<'tcx>,
-    ) -> RelateResult<'tcx, ty::TraitRef<'tcx>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'a + 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, ty::TraitRef<'tcx>> {
         // Different traits cannot be related
         if a.def_id != b.def_id {
             Err(TypeError::Traits(expected_found(relation, &a.def_id, &b.def_id)))
@@ -335,16 +290,11 @@ impl<'tcx> Relate<'tcx> for ty::TraitRef<'tcx> {
 }
 
 impl<'tcx> Relate<'tcx> for ty::ExistentialTraitRef<'tcx> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &ty::ExistentialTraitRef<'tcx>,
         b: &ty::ExistentialTraitRef<'tcx>,
-    ) -> RelateResult<'tcx, ty::ExistentialTraitRef<'tcx>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'a + 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, ty::ExistentialTraitRef<'tcx>> {
         // Different traits cannot be related
         if a.def_id != b.def_id {
             Err(TypeError::Traits(expected_found(relation, &a.def_id, &b.def_id)))
@@ -365,16 +315,11 @@ TupleStructTypeFoldableImpl! {
 }
 
 impl<'tcx> Relate<'tcx> for GeneratorWitness<'tcx> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &GeneratorWitness<'tcx>,
         b: &GeneratorWitness<'tcx>,
-    ) -> RelateResult<'tcx, GeneratorWitness<'tcx>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'a + 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, GeneratorWitness<'tcx>> {
         assert_eq!(a.0.len(), b.0.len());
         let tcx = relation.tcx();
         let types = tcx.mk_type_list(a.0.iter().zip(b.0).map(|(a, b)| relation.relate(a, b)))?;
@@ -383,16 +328,11 @@ impl<'tcx> Relate<'tcx> for GeneratorWitness<'tcx> {
 }
 
 impl<'tcx> Relate<'tcx> for Ty<'tcx> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &Ty<'tcx>,
         b: &Ty<'tcx>,
-    ) -> RelateResult<'tcx, Ty<'tcx>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'a + 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, Ty<'tcx>> {
         relation.tys(a, b)
     }
 }
@@ -400,16 +340,11 @@ impl<'tcx> Relate<'tcx> for Ty<'tcx> {
 /// The main "type relation" routine. Note that this does not handle
 /// inference artifacts, so you should filter those out before calling
 /// it.
-pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(
+pub fn super_relate_tys<R: TypeRelation<'tcx>>(
     relation: &mut R,
     a: Ty<'tcx>,
     b: Ty<'tcx>,
-) -> RelateResult<'tcx, Ty<'tcx>>
-where
-    R: TypeRelation<'gcx, 'tcx>,
-    'gcx: 'a + 'tcx,
-    'tcx: 'a,
-{
+) -> RelateResult<'tcx, Ty<'tcx>> {
     let tcx = relation.tcx();
     debug!("super_relate_tys: a={:?} b={:?}", a, b);
     match (&a.sty, &b.sty) {
@@ -604,16 +539,11 @@ where
 /// The main "const relation" routine. Note that this does not handle
 /// inference artifacts, so you should filter those out before calling
 /// it.
-pub fn super_relate_consts<'a, 'gcx, 'tcx, R>(
+pub fn super_relate_consts<R: TypeRelation<'tcx>>(
     relation: &mut R,
     a: &'tcx ty::Const<'tcx>,
     b: &'tcx ty::Const<'tcx>,
-) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>>
-where
-    R: TypeRelation<'gcx, 'tcx>,
-    'gcx: 'a + 'tcx,
-    'tcx: 'a,
-{
+) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
     let tcx = relation.tcx();
 
     let eagerly_eval = |x: &'tcx ty::Const<'tcx>| {
@@ -688,12 +618,11 @@ where
 }
 
 impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::ExistentialPredicate<'tcx>> {
-    fn relate<'a, 'gcx, R>(relation: &mut R, a: &Self, b: &Self) -> RelateResult<'tcx, Self>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'a + 'tcx,
-        'tcx: 'a,
-    {
+    fn relate<R: TypeRelation<'tcx>>(
+        relation: &mut R,
+        a: &Self,
+        b: &Self,
+    ) -> RelateResult<'tcx, Self> {
         if a.len() != b.len() {
             return Err(TypeError::ExistentialMismatch(expected_found(relation, a, b)));
         }
@@ -713,104 +642,73 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::ExistentialPredicate<'tcx>> {
 }
 
 impl<'tcx> Relate<'tcx> for ty::ClosureSubsts<'tcx> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &ty::ClosureSubsts<'tcx>,
         b: &ty::ClosureSubsts<'tcx>,
-    ) -> RelateResult<'tcx, ty::ClosureSubsts<'tcx>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'a + 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, ty::ClosureSubsts<'tcx>> {
         let substs = relate_substs(relation, None, a.substs, b.substs)?;
         Ok(ty::ClosureSubsts { substs })
     }
 }
 
 impl<'tcx> Relate<'tcx> for ty::GeneratorSubsts<'tcx> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &ty::GeneratorSubsts<'tcx>,
         b: &ty::GeneratorSubsts<'tcx>,
-    ) -> RelateResult<'tcx, ty::GeneratorSubsts<'tcx>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'a + 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, ty::GeneratorSubsts<'tcx>> {
         let substs = relate_substs(relation, None, a.substs, b.substs)?;
         Ok(ty::GeneratorSubsts { substs })
     }
 }
 
 impl<'tcx> Relate<'tcx> for SubstsRef<'tcx> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &SubstsRef<'tcx>,
         b: &SubstsRef<'tcx>,
-    ) -> RelateResult<'tcx, SubstsRef<'tcx>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'a + 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, SubstsRef<'tcx>> {
         relate_substs(relation, None, a, b)
     }
 }
 
 impl<'tcx> Relate<'tcx> for ty::Region<'tcx> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &ty::Region<'tcx>,
         b: &ty::Region<'tcx>,
-    ) -> RelateResult<'tcx, ty::Region<'tcx>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'a + 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, ty::Region<'tcx>> {
         relation.regions(*a, *b)
     }
 }
 
 impl<'tcx> Relate<'tcx> for &'tcx ty::Const<'tcx> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &&'tcx ty::Const<'tcx>,
         b: &&'tcx ty::Const<'tcx>,
-    ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'a + 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
         relation.consts(*a, *b)
     }
 }
 
 impl<'tcx, T: Relate<'tcx>> Relate<'tcx> for ty::Binder<T> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &ty::Binder<T>,
         b: &ty::Binder<T>,
-    ) -> RelateResult<'tcx, ty::Binder<T>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'a + 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, ty::Binder<T>> {
         relation.binders(a, b)
     }
 }
 
 impl<'tcx, T: Relate<'tcx>> Relate<'tcx> for Rc<T> {
-    fn relate<'a, 'gcx, R>(relation: &mut R, a: &Rc<T>, b: &Rc<T>) -> RelateResult<'tcx, Rc<T>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'a + 'tcx,
-        'tcx: 'a,
-    {
+    fn relate<R: TypeRelation<'tcx>>(
+        relation: &mut R,
+        a: &Rc<T>,
+        b: &Rc<T>,
+    ) -> RelateResult<'tcx, Rc<T>> {
         let a: &T = a;
         let b: &T = b;
         Ok(Rc::new(relation.relate(a, b)?))
@@ -818,12 +716,11 @@ impl<'tcx, T: Relate<'tcx>> Relate<'tcx> for Rc<T> {
 }
 
 impl<'tcx, T: Relate<'tcx>> Relate<'tcx> for Box<T> {
-    fn relate<'a, 'gcx, R>(relation: &mut R, a: &Box<T>, b: &Box<T>) -> RelateResult<'tcx, Box<T>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'a + 'tcx,
-        'tcx: 'a,
-    {
+    fn relate<R: TypeRelation<'tcx>>(
+        relation: &mut R,
+        a: &Box<T>,
+        b: &Box<T>,
+    ) -> RelateResult<'tcx, Box<T>> {
         let a: &T = a;
         let b: &T = b;
         Ok(Box::new(relation.relate(a, b)?))
@@ -831,16 +728,11 @@ impl<'tcx, T: Relate<'tcx>> Relate<'tcx> for Box<T> {
 }
 
 impl<'tcx> Relate<'tcx> for Kind<'tcx> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &Kind<'tcx>,
         b: &Kind<'tcx>,
-    ) -> RelateResult<'tcx, Kind<'tcx>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'a + 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, Kind<'tcx>> {
         match (a.unpack(), b.unpack()) {
             (UnpackedKind::Lifetime(a_lt), UnpackedKind::Lifetime(b_lt)) => {
                 Ok(relation.relate(&a_lt, &b_lt)?.into())
@@ -865,16 +757,11 @@ impl<'tcx> Relate<'tcx> for Kind<'tcx> {
 }
 
 impl<'tcx> Relate<'tcx> for ty::TraitPredicate<'tcx> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &ty::TraitPredicate<'tcx>,
         b: &ty::TraitPredicate<'tcx>,
-    ) -> RelateResult<'tcx, ty::TraitPredicate<'tcx>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, ty::TraitPredicate<'tcx>> {
         Ok(ty::TraitPredicate {
             trait_ref: relation.relate(&a.trait_ref, &b.trait_ref)?,
         })
@@ -882,16 +769,11 @@ impl<'tcx> Relate<'tcx> for ty::TraitPredicate<'tcx> {
 }
 
 impl<'tcx> Relate<'tcx> for ty::ProjectionPredicate<'tcx> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &ty::ProjectionPredicate<'tcx>,
         b: &ty::ProjectionPredicate<'tcx>,
-    ) -> RelateResult<'tcx, ty::ProjectionPredicate<'tcx>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, ty::ProjectionPredicate<'tcx>> {
         Ok(ty::ProjectionPredicate {
             projection_ty: relation.relate(&a.projection_ty, &b.projection_ty)?,
             ty: relation.relate(&a.ty, &b.ty)?,
@@ -900,16 +782,11 @@ impl<'tcx> Relate<'tcx> for ty::ProjectionPredicate<'tcx> {
 }
 
 impl<'tcx> Relate<'tcx> for traits::WhereClause<'tcx> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &traits::WhereClause<'tcx>,
         b: &traits::WhereClause<'tcx>,
-    ) -> RelateResult<'tcx, traits::WhereClause<'tcx>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, traits::WhereClause<'tcx>> {
         use crate::traits::WhereClause::*;
         match (a, b) {
             (Implemented(a_pred), Implemented(b_pred)) => {
@@ -940,16 +817,11 @@ impl<'tcx> Relate<'tcx> for traits::WhereClause<'tcx> {
 }
 
 impl<'tcx> Relate<'tcx> for traits::WellFormed<'tcx> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &traits::WellFormed<'tcx>,
         b: &traits::WellFormed<'tcx>,
-    ) -> RelateResult<'tcx, traits::WellFormed<'tcx>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'tcx,
-        'tcx: 'a,
-    {
+    ) -> 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)?)),
@@ -960,16 +832,11 @@ impl<'tcx> Relate<'tcx> for traits::WellFormed<'tcx> {
 }
 
 impl<'tcx> Relate<'tcx> for traits::FromEnv<'tcx> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &traits::FromEnv<'tcx>,
         b: &traits::FromEnv<'tcx>,
-    ) -> RelateResult<'tcx, traits::FromEnv<'tcx>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'tcx,
-        'tcx: 'a,
-    {
+    ) -> 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)?)),
@@ -980,16 +847,11 @@ impl<'tcx> Relate<'tcx> for traits::FromEnv<'tcx> {
 }
 
 impl<'tcx> Relate<'tcx> for traits::DomainGoal<'tcx> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &traits::DomainGoal<'tcx>,
         b: &traits::DomainGoal<'tcx>,
-    ) -> RelateResult<'tcx, traits::DomainGoal<'tcx>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'tcx,
-        'tcx: 'a,
-    {
+    ) -> 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)?)),
@@ -1006,16 +868,11 @@ impl<'tcx> Relate<'tcx> for traits::DomainGoal<'tcx> {
 }
 
 impl<'tcx> Relate<'tcx> for traits::Goal<'tcx> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &traits::Goal<'tcx>,
         b: &traits::Goal<'tcx>,
-    ) -> RelateResult<'tcx, traits::Goal<'tcx>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, traits::Goal<'tcx>> {
         use crate::traits::GoalKind::*;
         match (a, b) {
             (Implies(a_clauses, a_goal), Implies(b_clauses, b_goal)) => {
@@ -1055,16 +912,11 @@ impl<'tcx> Relate<'tcx> for traits::Goal<'tcx> {
 }
 
 impl<'tcx> Relate<'tcx> for traits::Goals<'tcx> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &traits::Goals<'tcx>,
         b: &traits::Goals<'tcx>,
-    ) -> RelateResult<'tcx, traits::Goals<'tcx>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, traits::Goals<'tcx>> {
         if a.len() != b.len() {
             return Err(TypeError::Mismatch);
         }
@@ -1076,16 +928,11 @@ impl<'tcx> Relate<'tcx> for traits::Goals<'tcx> {
 }
 
 impl<'tcx> Relate<'tcx> for traits::Clause<'tcx> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &traits::Clause<'tcx>,
         b: &traits::Clause<'tcx>,
-    ) -> RelateResult<'tcx, traits::Clause<'tcx>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, traits::Clause<'tcx>> {
         use crate::traits::Clause::*;
         match (a, b) {
             (Implies(a_clause), Implies(b_clause)) => {
@@ -1104,16 +951,11 @@ impl<'tcx> Relate<'tcx> for traits::Clause<'tcx> {
 }
 
 impl<'tcx> Relate<'tcx> for traits::Clauses<'tcx> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &traits::Clauses<'tcx>,
         b: &traits::Clauses<'tcx>,
-    ) -> RelateResult<'tcx, traits::Clauses<'tcx>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, traits::Clauses<'tcx>> {
         if a.len() != b.len() {
             return Err(TypeError::Mismatch);
         }
@@ -1125,16 +967,11 @@ impl<'tcx> Relate<'tcx> for traits::Clauses<'tcx> {
 }
 
 impl<'tcx> Relate<'tcx> for traits::ProgramClause<'tcx> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &traits::ProgramClause<'tcx>,
         b: &traits::ProgramClause<'tcx>,
-    ) -> RelateResult<'tcx, traits::ProgramClause<'tcx>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, traits::ProgramClause<'tcx>> {
         Ok(traits::ProgramClause {
             goal: relation.relate(&a.goal, &b.goal)?,
             hypotheses: relation.relate(&a.hypotheses, &b.hypotheses)?,
@@ -1144,16 +981,11 @@ impl<'tcx> Relate<'tcx> for traits::ProgramClause<'tcx> {
 }
 
 impl<'tcx> Relate<'tcx> for traits::Environment<'tcx> {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &traits::Environment<'tcx>,
         b: &traits::Environment<'tcx>,
-    ) -> RelateResult<'tcx, traits::Environment<'tcx>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, traits::Environment<'tcx>> {
         Ok(traits::Environment {
             clauses: relation.relate(&a.clauses, &b.clauses)?,
         })
@@ -1164,16 +996,11 @@ impl<'tcx, G> Relate<'tcx> for traits::InEnvironment<'tcx, G>
 where
     G: Relate<'tcx>,
 {
-    fn relate<'a, 'gcx, R>(
+    fn relate<R: TypeRelation<'tcx>>(
         relation: &mut R,
         a: &traits::InEnvironment<'tcx, G>,
         b: &traits::InEnvironment<'tcx, G>,
-    ) -> RelateResult<'tcx, traits::InEnvironment<'tcx, G>>
-    where
-        R: TypeRelation<'gcx, 'tcx>,
-        'gcx: 'tcx,
-        'tcx: 'a,
-    {
+    ) -> RelateResult<'tcx, traits::InEnvironment<'tcx, G>> {
         Ok(traits::InEnvironment {
             environment: relation.relate(&a.environment, &b.environment)?,
             goal: relation.relate(&a.goal, &b.goal)?,
@@ -1184,12 +1011,10 @@ where
 ///////////////////////////////////////////////////////////////////////////
 // Error handling
 
-pub fn expected_found<'a, 'gcx, 'tcx, R, T>(relation: &mut R, a: &T, b: &T) -> ExpectedFound<T>
+pub fn expected_found<R, T>(relation: &mut R, a: &T, b: &T) -> ExpectedFound<T>
 where
-    R: TypeRelation<'gcx, 'tcx>,
+    R: TypeRelation<'tcx>,
     T: Clone,
-    'gcx: 'a + 'tcx,
-    'tcx: 'a,
 {
     expected_found_bool(relation.a_is_expected(), a, b)
 }
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index 35c61f83fce..9756e9c872b 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -337,14 +337,14 @@ CloneTypeFoldableAndLiftImpls! {
 // FIXME(eddyb) replace all the uses of `Option::map` with `?`.
 impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>> Lift<'tcx> for (A, B) {
     type Lifted = (A::Lifted, B::Lifted);
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         tcx.lift(&self.0).and_then(|a| tcx.lift(&self.1).map(|b| (a, b)))
     }
 }
 
 impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>, C: Lift<'tcx>> Lift<'tcx> for (A, B, C) {
     type Lifted = (A::Lifted, B::Lifted, C::Lifted);
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         tcx.lift(&self.0).and_then(|a| {
             tcx.lift(&self.1).and_then(|b| tcx.lift(&self.2).map(|c| (a, b, c)))
         })
@@ -353,7 +353,7 @@ impl<'tcx, A: Lift<'tcx>, B: Lift<'tcx>, C: Lift<'tcx>> Lift<'tcx> for (A, B, C)
 
 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option<T> {
     type Lifted = Option<T::Lifted>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         match *self {
             Some(ref x) => tcx.lift(x).map(Some),
             None => Some(None)
@@ -363,7 +363,7 @@ impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option<T> {
 
 impl<'tcx, T: Lift<'tcx>, E: Lift<'tcx>> Lift<'tcx> for Result<T, E> {
     type Lifted = Result<T::Lifted, E::Lifted>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         match *self {
             Ok(ref x) => tcx.lift(x).map(Ok),
             Err(ref e) => tcx.lift(e).map(Err)
@@ -373,14 +373,14 @@ impl<'tcx, T: Lift<'tcx>, E: Lift<'tcx>> Lift<'tcx> for Result<T, E> {
 
 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Box<T> {
     type Lifted = Box<T::Lifted>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         tcx.lift(&**self).map(Box::new)
     }
 }
 
 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for [T] {
     type Lifted = Vec<T::Lifted>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         // type annotation needed to inform `projection_must_outlive`
         let mut result : Vec<<T as Lift<'tcx>>::Lifted>
             = Vec::with_capacity(self.len());
@@ -397,14 +397,14 @@ impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for [T] {
 
 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Vec<T> {
     type Lifted = Vec<T::Lifted>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         tcx.lift(&self[..])
     }
 }
 
 impl<'tcx, I: Idx, T: Lift<'tcx>> Lift<'tcx> for IndexVec<I, T> {
     type Lifted = IndexVec<I, T::Lifted>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         self.iter()
             .map(|e| tcx.lift(e))
             .collect()
@@ -413,7 +413,7 @@ impl<'tcx, I: Idx, T: Lift<'tcx>> Lift<'tcx> for IndexVec<I, T> {
 
 impl<'a, 'tcx> Lift<'tcx> for ty::TraitRef<'a> {
     type Lifted = ty::TraitRef<'tcx>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         tcx.lift(&self.substs).map(|substs| ty::TraitRef {
             def_id: self.def_id,
             substs,
@@ -423,7 +423,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::TraitRef<'a> {
 
 impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialTraitRef<'a> {
     type Lifted = ty::ExistentialTraitRef<'tcx>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         tcx.lift(&self.substs).map(|substs| ty::ExistentialTraitRef {
             def_id: self.def_id,
             substs,
@@ -433,7 +433,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialTraitRef<'a> {
 
 impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialPredicate<'a> {
     type Lifted = ty::ExistentialPredicate<'tcx>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         match self {
             ty::ExistentialPredicate::Trait(x) => {
                 tcx.lift(x).map(ty::ExistentialPredicate::Trait)
@@ -450,7 +450,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialPredicate<'a> {
 
 impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> {
     type Lifted = ty::TraitPredicate<'tcx>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<ty::TraitPredicate<'tcx>> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<ty::TraitPredicate<'tcx>> {
         tcx.lift(&self.trait_ref).map(|trait_ref| ty::TraitPredicate {
             trait_ref,
         })
@@ -459,7 +459,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> {
 
 impl<'a, 'tcx> Lift<'tcx> for ty::SubtypePredicate<'a> {
     type Lifted = ty::SubtypePredicate<'tcx>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<ty::SubtypePredicate<'tcx>> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<ty::SubtypePredicate<'tcx>> {
         tcx.lift(&(self.a, self.b)).map(|(a, b)| ty::SubtypePredicate {
             a_is_expected: self.a_is_expected,
             a,
@@ -470,14 +470,14 @@ impl<'a, 'tcx> Lift<'tcx> for ty::SubtypePredicate<'a> {
 
 impl<'tcx, A: Copy + Lift<'tcx>, B: Copy + Lift<'tcx>> Lift<'tcx> for ty::OutlivesPredicate<A, B> {
     type Lifted = ty::OutlivesPredicate<A::Lifted, B::Lifted>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         tcx.lift(&(self.0, self.1)).map(|(a, b)| ty::OutlivesPredicate(a, b))
     }
 }
 
 impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionTy<'a> {
     type Lifted = ty::ProjectionTy<'tcx>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<ty::ProjectionTy<'tcx>> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<ty::ProjectionTy<'tcx>> {
         tcx.lift(&self.substs).map(|substs| {
             ty::ProjectionTy {
                 item_def_id: self.item_def_id,
@@ -489,7 +489,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionTy<'a> {
 
 impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionPredicate<'a> {
     type Lifted = ty::ProjectionPredicate<'tcx>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<ty::ProjectionPredicate<'tcx>> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<ty::ProjectionPredicate<'tcx>> {
         tcx.lift(&(self.projection_ty, self.ty)).map(|(projection_ty, ty)| {
             ty::ProjectionPredicate {
                 projection_ty,
@@ -501,7 +501,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ProjectionPredicate<'a> {
 
 impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialProjection<'a> {
     type Lifted = ty::ExistentialProjection<'tcx>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         tcx.lift(&self.substs).map(|substs| {
             ty::ExistentialProjection {
                 substs,
@@ -514,7 +514,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialProjection<'a> {
 
 impl<'a, 'tcx> Lift<'tcx> for ty::Predicate<'a> {
     type Lifted = ty::Predicate<'tcx>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         match *self {
             ty::Predicate::Trait(ref binder) => {
                 tcx.lift(binder).map(ty::Predicate::Trait)
@@ -554,14 +554,14 @@ impl<'a, 'tcx> Lift<'tcx> for ty::Predicate<'a> {
 
 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder<T> {
     type Lifted = ty::Binder<T::Lifted>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         tcx.lift(self.skip_binder()).map(ty::Binder::bind)
     }
 }
 
 impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> {
     type Lifted = ty::ParamEnv<'tcx>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         tcx.lift(&self.caller_bounds).map(|caller_bounds| {
             ty::ParamEnv {
                 reveal: self.reveal,
@@ -574,7 +574,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> {
 
 impl<'a, 'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::ParamEnvAnd<'a, T> {
     type Lifted = ty::ParamEnvAnd<'tcx, T::Lifted>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         tcx.lift(&self.param_env).and_then(|param_env| {
             tcx.lift(&self.value).map(|value| {
                 ty::ParamEnvAnd {
@@ -588,7 +588,7 @@ impl<'a, 'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::ParamEnvAnd<'a, T> {
 
 impl<'a, 'tcx> Lift<'tcx> for ty::ClosureSubsts<'a> {
     type Lifted = ty::ClosureSubsts<'tcx>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         tcx.lift(&self.substs).map(|substs| {
             ty::ClosureSubsts { substs }
         })
@@ -597,7 +597,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ClosureSubsts<'a> {
 
 impl<'a, 'tcx> Lift<'tcx> for ty::GeneratorSubsts<'a> {
     type Lifted = ty::GeneratorSubsts<'tcx>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         tcx.lift(&self.substs).map(|substs| {
             ty::GeneratorSubsts { substs }
         })
@@ -606,7 +606,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::GeneratorSubsts<'a> {
 
 impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjustment<'a> {
     type Lifted = ty::adjustment::Adjustment<'tcx>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         tcx.lift(&self.kind).and_then(|kind| {
             tcx.lift(&self.target).map(|target| {
                 ty::adjustment::Adjustment { kind, target }
@@ -617,7 +617,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjustment<'a> {
 
 impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjust<'a> {
     type Lifted = ty::adjustment::Adjust<'tcx>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         match *self {
             ty::adjustment::Adjust::NeverToAny =>
                 Some(ty::adjustment::Adjust::NeverToAny),
@@ -635,7 +635,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::Adjust<'a> {
 
 impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::OverloadedDeref<'a> {
     type Lifted = ty::adjustment::OverloadedDeref<'tcx>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         tcx.lift(&self.region).map(|region| {
             ty::adjustment::OverloadedDeref {
                 region,
@@ -647,7 +647,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::OverloadedDeref<'a> {
 
 impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::AutoBorrow<'a> {
     type Lifted = ty::adjustment::AutoBorrow<'tcx>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         match *self {
             ty::adjustment::AutoBorrow::Ref(r, m) => {
                 tcx.lift(&r).map(|r| ty::adjustment::AutoBorrow::Ref(r, m))
@@ -661,7 +661,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::AutoBorrow<'a> {
 
 impl<'a, 'tcx> Lift<'tcx> for ty::GenSig<'a> {
     type Lifted = ty::GenSig<'tcx>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         tcx.lift(&(self.yield_ty, self.return_ty))
            .map(|(yield_ty, return_ty)| {
                ty::GenSig {
@@ -674,7 +674,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::GenSig<'a> {
 
 impl<'a, 'tcx> Lift<'tcx> for ty::FnSig<'a> {
     type Lifted = ty::FnSig<'tcx>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         tcx.lift(&self.inputs_and_output).map(|x| {
             ty::FnSig {
                 inputs_and_output: x,
@@ -688,7 +688,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::FnSig<'a> {
 
 impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::error::ExpectedFound<T> {
     type Lifted = ty::error::ExpectedFound<T::Lifted>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         tcx.lift(&self.expected).and_then(|expected| {
             tcx.lift(&self.found).map(|found| {
                 ty::error::ExpectedFound {
@@ -702,7 +702,7 @@ impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::error::ExpectedFound<T> {
 
 impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
     type Lifted = ty::error::TypeError<'tcx>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         use crate::ty::error::TypeError::*;
 
         Some(match *self {
@@ -739,7 +739,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
 
 impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> {
     type Lifted = ty::InstanceDef<'tcx>;
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         match *self {
             ty::InstanceDef::Item(def_id) =>
                 Some(ty::InstanceDef::Item(def_id)),
@@ -795,7 +795,7 @@ BraceStructLiftImpl! {
 
 /// AdtDefs are basically the same as a DefId.
 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::AdtDef {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, _folder: &mut F) -> Self {
         *self
     }
 
@@ -805,7 +805,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::AdtDef {
 }
 
 impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> (T, U) {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> (T, U) {
         (self.0.fold_with(folder), self.1.fold_with(folder))
     }
 
@@ -822,7 +822,7 @@ EnumTypeFoldableImpl! {
 }
 
 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         Rc::new((**self).fold_with(folder))
     }
 
@@ -832,7 +832,7 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
 }
 
 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         let content: T = (**self).fold_with(folder);
         box content
     }
@@ -843,7 +843,7 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> {
 }
 
 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         self.iter().map(|t| t.fold_with(folder)).collect()
     }
 
@@ -853,7 +853,7 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> {
 }
 
 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         self.iter().map(|t| t.fold_with(folder)).collect::<Vec<_>>().into_boxed_slice()
     }
 
@@ -863,11 +863,11 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> {
 }
 
 impl<'tcx, T:TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<T> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         self.map_bound_ref(|ty| ty.fold_with(folder))
     }
 
-    fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         folder.fold_binder(self)
     }
 
@@ -885,7 +885,7 @@ BraceStructTypeFoldableImpl! {
 }
 
 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::ExistentialPredicate<'tcx>> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         let v = self.iter().map(|p| p.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
         folder.tcx().intern_existential_predicates(&v)
     }
@@ -904,7 +904,7 @@ EnumTypeFoldableImpl! {
 }
 
 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    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_type_list(&v)
     }
@@ -915,7 +915,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
 }
 
 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    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_projs(&v)
     }
@@ -926,7 +926,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind> {
 }
 
 impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         use crate::ty::InstanceDef::*;
         Self {
             substs: self.substs.fold_with(folder),
@@ -976,7 +976,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> {
 }
 
 impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         Self {
             instance: self.instance.fold_with(folder),
             promoted: self.promoted
@@ -989,7 +989,7 @@ impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> {
 }
 
 impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         let sty = match self.sty {
             ty::RawPtr(tm) => ty::RawPtr(tm.fold_with(folder)),
             ty::Array(typ, sz) => ty::Array(typ.fold_with(folder), sz.fold_with(folder)),
@@ -1041,7 +1041,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
         }
     }
 
-    fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         folder.fold_ty(*self)
     }
 
@@ -1124,11 +1124,11 @@ BraceStructTypeFoldableImpl! {
 }
 
 impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, _folder: &mut F) -> Self {
         *self
     }
 
-    fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         folder.fold_region(*self)
     }
 
@@ -1189,7 +1189,7 @@ BraceStructTypeFoldableImpl! {
 }
 
 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         let v = self.iter().map(|p| p.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
         folder.tcx().intern_predicates(&v)
     }
@@ -1274,7 +1274,7 @@ BraceStructTypeFoldableImpl! {
 }
 
 impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         self.iter().map(|x| x.fold_with(folder)).collect()
     }
 
@@ -1310,7 +1310,7 @@ EnumTypeFoldableImpl! {
 }
 
 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         let ty = self.ty.fold_with(folder);
         let val = self.val.fold_with(folder);
         folder.tcx().mk_const(ty::Const {
@@ -1319,7 +1319,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> {
         })
     }
 
-    fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         folder.fold_const(*self)
     }
 
@@ -1333,7 +1333,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> {
 }
 
 impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         match *self {
             ConstValue::ByRef(ptr, alloc) => ConstValue::ByRef(ptr, alloc),
             ConstValue::Infer(ic) => ConstValue::Infer(ic.fold_with(folder)),
@@ -1360,7 +1360,7 @@ impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> {
 }
 
 impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, _folder: &mut F) -> Self {
         *self
     }
 
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index dc2d96ee8b9..ed4a2cd7a29 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -324,7 +324,7 @@ impl<'tcx> ClosureSubsts<'tcx> {
     /// Divides the closure substs into their respective
     /// components. Single source of truth with respect to the
     /// ordering.
-    fn split(self, def_id: DefId, tcx: TyCtxt<'_, '_>) -> SplitClosureSubsts<'tcx> {
+    fn split(self, def_id: DefId, tcx: TyCtxt<'_>) -> SplitClosureSubsts<'tcx> {
         let generics = tcx.generics_of(def_id);
         let parent_len = generics.parent_count;
         SplitClosureSubsts {
@@ -338,7 +338,7 @@ impl<'tcx> ClosureSubsts<'tcx> {
     pub fn upvar_tys(
         self,
         def_id: DefId,
-        tcx: TyCtxt<'_, '_>,
+        tcx: TyCtxt<'_>,
     ) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
         let SplitClosureSubsts { upvar_kinds, .. } = self.split(def_id, tcx);
         upvar_kinds.iter().map(|t| {
@@ -353,7 +353,7 @@ impl<'tcx> ClosureSubsts<'tcx> {
     /// Returns the closure kind for this closure; may return a type
     /// variable during inference. To get the closure kind during
     /// inference, use `infcx.closure_kind(def_id, substs)`.
-    pub fn closure_kind_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_>) -> Ty<'tcx> {
+    pub fn closure_kind_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> {
         self.split(def_id, tcx).closure_kind_ty
     }
 
@@ -361,7 +361,7 @@ impl<'tcx> ClosureSubsts<'tcx> {
     /// closure; may contain type variables during inference. To get
     /// the closure signature during inference, use
     /// `infcx.fn_sig(def_id)`.
-    pub fn closure_sig_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_>) -> Ty<'tcx> {
+    pub fn closure_sig_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> {
         self.split(def_id, tcx).closure_sig_ty
     }
 
@@ -370,7 +370,7 @@ impl<'tcx> ClosureSubsts<'tcx> {
     /// there are no type variables.
     ///
     /// If you have an inference context, use `infcx.closure_kind()`.
-    pub fn closure_kind(self, def_id: DefId, tcx: TyCtxt<'tcx, 'tcx>) -> ty::ClosureKind {
+    pub fn closure_kind(self, def_id: DefId, tcx: TyCtxt<'tcx>) -> ty::ClosureKind {
         self.split(def_id, tcx).closure_kind_ty.to_opt_closure_kind().unwrap()
     }
 
@@ -379,7 +379,7 @@ impl<'tcx> ClosureSubsts<'tcx> {
     /// there are no type variables.
     ///
     /// If you have an inference context, use `infcx.closure_sig()`.
-    pub fn closure_sig(self, def_id: DefId, tcx: TyCtxt<'tcx, 'tcx>) -> ty::PolyFnSig<'tcx> {
+    pub fn closure_sig(self, def_id: DefId, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> {
         let ty = self.closure_sig_ty(def_id, tcx);
         match ty.sty {
             ty::FnPtr(sig) => sig,
@@ -403,7 +403,7 @@ struct SplitGeneratorSubsts<'tcx> {
 }
 
 impl<'tcx> GeneratorSubsts<'tcx> {
-    fn split(self, def_id: DefId, tcx: TyCtxt<'_, '_>) -> SplitGeneratorSubsts<'tcx> {
+    fn split(self, def_id: DefId, tcx: TyCtxt<'_>) -> SplitGeneratorSubsts<'tcx> {
         let generics = tcx.generics_of(def_id);
         let parent_len = generics.parent_count;
         SplitGeneratorSubsts {
@@ -419,7 +419,7 @@ impl<'tcx> GeneratorSubsts<'tcx> {
     /// It contains a tuple of all the types that could end up on a generator frame.
     /// The state transformation MIR pass may only produce layouts which mention types
     /// in this tuple. Upvars are not counted here.
-    pub fn witness(self, def_id: DefId, tcx: TyCtxt<'_, '_>) -> Ty<'tcx> {
+    pub fn witness(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> {
         self.split(def_id, tcx).witness
     }
 
@@ -427,7 +427,7 @@ impl<'tcx> GeneratorSubsts<'tcx> {
     pub fn upvar_tys(
         self,
         def_id: DefId,
-        tcx: TyCtxt<'_, '_>,
+        tcx: TyCtxt<'_>,
     ) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
         let SplitGeneratorSubsts { upvar_kinds, .. } = self.split(def_id, tcx);
         upvar_kinds.iter().map(|t| {
@@ -440,12 +440,12 @@ impl<'tcx> GeneratorSubsts<'tcx> {
     }
 
     /// Returns the type representing the yield type of the generator.
-    pub fn yield_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_>) -> Ty<'tcx> {
+    pub fn yield_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> {
         self.split(def_id, tcx).yield_ty
     }
 
     /// Returns the type representing the return type of the generator.
-    pub fn return_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_>) -> Ty<'tcx> {
+    pub fn return_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> {
         self.split(def_id, tcx).return_ty
     }
 
@@ -455,13 +455,13 @@ impl<'tcx> GeneratorSubsts<'tcx> {
     /// N.B., some bits of the code prefers to see this wrapped in a
     /// binder, but it never contains bound regions. Probably this
     /// function should be removed.
-    pub fn poly_sig(self, def_id: DefId, tcx: TyCtxt<'_, '_>) -> PolyGenSig<'tcx> {
+    pub fn poly_sig(self, def_id: DefId, tcx: TyCtxt<'_>) -> PolyGenSig<'tcx> {
         ty::Binder::dummy(self.sig(def_id, tcx))
     }
 
     /// Returns the "generator signature", which consists of its yield
     /// and return types.
-    pub fn sig(self, def_id: DefId, tcx: TyCtxt<'_, '_>) -> GenSig<'tcx> {
+    pub fn sig(self, def_id: DefId, tcx: TyCtxt<'_>) -> GenSig<'tcx> {
         ty::GenSig {
             yield_ty: self.yield_ty(def_id, tcx),
             return_ty: self.return_ty(def_id, tcx),
@@ -469,7 +469,7 @@ impl<'tcx> GeneratorSubsts<'tcx> {
     }
 }
 
-impl<'gcx, 'tcx> GeneratorSubsts<'tcx> {
+impl<'tcx> GeneratorSubsts<'tcx> {
     /// Generator have not been resumed yet
     pub const UNRESUMED: usize = 0;
     /// Generator has returned / is completed
@@ -483,7 +483,7 @@ impl<'gcx, 'tcx> GeneratorSubsts<'tcx> {
 
     /// The valid variant indices of this Generator.
     #[inline]
-    pub fn variant_range(&self, def_id: DefId, tcx: TyCtxt<'gcx, 'tcx>) -> Range<VariantIdx> {
+    pub fn variant_range(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> Range<VariantIdx> {
         // FIXME requires optimized MIR
         let num_variants = tcx.generator_layout(def_id).variant_fields.len();
         (VariantIdx::new(0)..VariantIdx::new(num_variants))
@@ -495,7 +495,7 @@ impl<'gcx, 'tcx> GeneratorSubsts<'tcx> {
     pub fn discriminant_for_variant(
         &self,
         def_id: DefId,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         variant_index: VariantIdx,
     ) -> Discr<'tcx> {
         // Generators don't support explicit discriminant values, so they are
@@ -510,8 +510,8 @@ impl<'gcx, 'tcx> GeneratorSubsts<'tcx> {
     pub fn discriminants(
         &'tcx self,
         def_id: DefId,
-        tcx: TyCtxt<'gcx, 'tcx>,
-    ) -> impl Iterator<Item = (VariantIdx, Discr<'tcx>)> + Captures<'gcx> {
+        tcx: TyCtxt<'tcx>,
+    ) -> impl Iterator<Item = (VariantIdx, Discr<'tcx>)> + Captures<'tcx> {
         self.variant_range(def_id, tcx).map(move |index| {
             (index, Discr { val: index.as_usize() as u128, ty: self.discr_ty(tcx) })
         })
@@ -531,7 +531,7 @@ impl<'gcx, 'tcx> GeneratorSubsts<'tcx> {
 
     /// The type of the state discriminant used in the generator type.
     #[inline]
-    pub fn discr_ty(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Ty<'tcx> {
+    pub fn discr_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         tcx.types.u32
     }
 
@@ -545,8 +545,8 @@ impl<'gcx, 'tcx> GeneratorSubsts<'tcx> {
     pub fn state_tys(
         self,
         def_id: DefId,
-        tcx: TyCtxt<'gcx, 'tcx>,
-    ) -> impl Iterator<Item = impl Iterator<Item = Ty<'tcx>> + Captures<'gcx>> {
+        tcx: TyCtxt<'tcx>,
+    ) -> impl Iterator<Item = impl Iterator<Item = Ty<'tcx>> + Captures<'tcx>> {
         let layout = tcx.generator_layout(def_id);
         layout.variant_fields.iter().map(move |variant| {
             variant.iter().map(move |field| {
@@ -561,7 +561,7 @@ impl<'gcx, 'tcx> GeneratorSubsts<'tcx> {
     pub fn prefix_tys(
         self,
         def_id: DefId,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
     ) -> impl Iterator<Item = Ty<'tcx>> {
         self.upvar_tys(def_id, tcx)
     }
@@ -578,7 +578,7 @@ impl<'tcx> UpvarSubsts<'tcx> {
     pub fn upvar_tys(
         self,
         def_id: DefId,
-        tcx: TyCtxt<'_, '_>,
+        tcx: TyCtxt<'_>,
     ) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
         let upvar_kinds = match self {
             UpvarSubsts::Closure(substs) => substs.split(def_id, tcx).upvar_kinds,
@@ -605,10 +605,10 @@ pub enum ExistentialPredicate<'tcx> {
     AutoTrait(DefId),
 }
 
-impl<'gcx, 'tcx> ExistentialPredicate<'tcx> {
+impl<'tcx> ExistentialPredicate<'tcx> {
     /// Compares via an ordering that will not change if modules are reordered or other changes are
     /// made to the tree. In particular, this ordering is preserved across incremental compilations.
-    pub fn stable_cmp(&self, tcx: TyCtxt<'gcx, 'tcx>, other: &Self) -> Ordering {
+    pub fn stable_cmp(&self, tcx: TyCtxt<'tcx>, other: &Self) -> Ordering {
         use self::ExistentialPredicate::*;
         match (*self, *other) {
             (Trait(_), Trait(_)) => Ordering::Equal,
@@ -624,8 +624,8 @@ impl<'gcx, 'tcx> ExistentialPredicate<'tcx> {
     }
 }
 
-impl<'gcx, 'tcx> Binder<ExistentialPredicate<'tcx>> {
-    pub fn with_self_ty(&self, tcx: TyCtxt<'gcx, 'tcx>, self_ty: Ty<'tcx>) -> ty::Predicate<'tcx> {
+impl<'tcx> Binder<ExistentialPredicate<'tcx>> {
+    pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Predicate<'tcx> {
         use crate::ty::ToPredicate;
         match *self.skip_binder() {
             ExistentialPredicate::Trait(tr) => Binder(tr).with_self_ty(tcx, self_ty).to_predicate(),
@@ -757,7 +757,7 @@ impl<'tcx> TraitRef<'tcx> {
 
     /// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi`
     /// are the parameters defined on trait.
-    pub fn identity<'gcx>(tcx: TyCtxt<'gcx, 'tcx>, def_id: DefId) -> TraitRef<'tcx> {
+    pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> TraitRef<'tcx> {
         TraitRef {
             def_id,
             substs: InternalSubsts::identity_for_item(tcx, def_id),
@@ -778,7 +778,7 @@ impl<'tcx> TraitRef<'tcx> {
     }
 
     pub fn from_method(
-        tcx: TyCtxt<'_, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         trait_id: DefId,
         substs: SubstsRef<'tcx>,
     ) -> ty::TraitRef<'tcx> {
@@ -822,7 +822,7 @@ pub struct ExistentialTraitRef<'tcx> {
     pub substs: SubstsRef<'tcx>,
 }
 
-impl<'gcx, 'tcx> ExistentialTraitRef<'tcx> {
+impl<'tcx> ExistentialTraitRef<'tcx> {
     pub fn input_types<'b>(&'b self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> + 'b {
         // Select only the "input types" from a trait-reference. For
         // now this is all the types that appear in the
@@ -832,7 +832,7 @@ impl<'gcx, 'tcx> ExistentialTraitRef<'tcx> {
     }
 
     pub fn erase_self_ty(
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         trait_ref: ty::TraitRef<'tcx>,
     ) -> ty::ExistentialTraitRef<'tcx> {
         // Assert there is a Self.
@@ -848,7 +848,7 @@ impl<'gcx, 'tcx> ExistentialTraitRef<'tcx> {
     /// we convert the principal trait-ref into a normal trait-ref,
     /// you must give *some* self type. A common choice is `mk_err()`
     /// or some placeholder type.
-    pub fn with_self_ty(&self, tcx: TyCtxt<'gcx, 'tcx>, self_ty: Ty<'tcx>) -> ty::TraitRef<'tcx> {
+    pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::TraitRef<'tcx> {
         // otherwise the escaping vars would be captured by the binder
         // debug_assert!(!self_ty.has_escaping_bound_vars());
 
@@ -870,7 +870,7 @@ impl<'tcx> PolyExistentialTraitRef<'tcx> {
     /// we convert the principal trait-ref into a normal trait-ref,
     /// you must give *some* self type. A common choice is `mk_err()`
     /// or some placeholder type.
-    pub fn with_self_ty(&self, tcx: TyCtxt<'_, 'tcx>, self_ty: Ty<'tcx>) -> ty::PolyTraitRef<'tcx> {
+    pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::PolyTraitRef<'tcx> {
         self.map_bound(|trait_ref| trait_ref.with_self_ty(tcx, self_ty))
     }
 }
@@ -1004,7 +1004,7 @@ impl<'tcx> ProjectionTy<'tcx> {
     /// Construct a `ProjectionTy` by searching the trait from `trait_ref` for the
     /// associated item named `item_name`.
     pub fn from_ref_and_name(
-        tcx: TyCtxt<'_, '_>,
+        tcx: TyCtxt<'_>,
         trait_ref: ty::TraitRef<'tcx>,
         item_name: Ident,
     ) -> ProjectionTy<'tcx> {
@@ -1022,7 +1022,7 @@ impl<'tcx> ProjectionTy<'tcx> {
     /// Extracts the underlying trait reference from this projection.
     /// For example, if this is a projection of `<T as Iterator>::Item`,
     /// then this function would return a `T: Iterator` trait reference.
-    pub fn trait_ref(&self, tcx: TyCtxt<'_, '_>) -> ty::TraitRef<'tcx> {
+    pub fn trait_ref(&self, tcx: TyCtxt<'_>) -> ty::TraitRef<'tcx> {
         let def_id = tcx.associated_item(self.item_def_id).container.id();
         ty::TraitRef {
             def_id,
@@ -1126,7 +1126,7 @@ pub struct ParamTy {
     pub name: InternedString,
 }
 
-impl<'gcx, 'tcx> ParamTy {
+impl<'tcx> ParamTy {
     pub fn new(index: u32, name: InternedString) -> ParamTy {
         ParamTy { index, name: name }
     }
@@ -1139,7 +1139,7 @@ impl<'gcx, 'tcx> ParamTy {
         ParamTy::new(def.index, def.name)
     }
 
-    pub fn to_ty(self, tcx: TyCtxt<'gcx, 'tcx>) -> Ty<'tcx> {
+    pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         tcx.mk_ty_param(self.index, self.name)
     }
 
@@ -1158,7 +1158,7 @@ pub struct ParamConst {
     pub name: InternedString,
 }
 
-impl<'gcx, 'tcx> ParamConst {
+impl<'tcx> ParamConst {
     pub fn new(index: u32, name: InternedString) -> ParamConst {
         ParamConst { index, name }
     }
@@ -1167,7 +1167,7 @@ impl<'gcx, 'tcx> ParamConst {
         ParamConst::new(def.index, def.name)
     }
 
-    pub fn to_const(self, tcx: TyCtxt<'gcx, 'tcx>, ty: Ty<'tcx>) -> &'tcx Const<'tcx> {
+    pub fn to_const(self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> &'tcx Const<'tcx> {
         tcx.mk_const_param(self.index, self.name, ty)
     }
 }
@@ -1422,12 +1422,12 @@ pub struct ExistentialProjection<'tcx> {
 
 pub type PolyExistentialProjection<'tcx> = Binder<ExistentialProjection<'tcx>>;
 
-impl<'tcx, 'gcx> ExistentialProjection<'tcx> {
+impl<'tcx> ExistentialProjection<'tcx> {
     /// Extracts the underlying existential trait reference from this projection.
     /// For example, if this is a projection of `exists T. <T as Iterator>::Item == X`,
     /// then this function would return a `exists T. T: Iterator` existential trait
     /// reference.
-    pub fn trait_ref(&self, tcx: TyCtxt<'_, '_>) -> ty::ExistentialTraitRef<'tcx> {
+    pub fn trait_ref(&self, tcx: TyCtxt<'_>) -> ty::ExistentialTraitRef<'tcx> {
         let def_id = tcx.associated_item(self.item_def_id).container.id();
         ty::ExistentialTraitRef{
             def_id,
@@ -1437,7 +1437,7 @@ impl<'tcx, 'gcx> ExistentialProjection<'tcx> {
 
     pub fn with_self_ty(
         &self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         self_ty: Ty<'tcx>,
     ) -> ty::ProjectionPredicate<'tcx> {
         // otherwise the escaping regions would be captured by the binders
@@ -1453,10 +1453,10 @@ impl<'tcx, 'gcx> ExistentialProjection<'tcx> {
     }
 }
 
-impl<'tcx, 'gcx> PolyExistentialProjection<'tcx> {
+impl<'tcx> PolyExistentialProjection<'tcx> {
     pub fn with_self_ty(
         &self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         self_ty: Ty<'tcx>,
     ) -> ty::PolyProjectionPredicate<'tcx> {
         self.map_bound(|p| p.with_self_ty(tcx, self_ty))
@@ -1670,7 +1670,7 @@ impl RegionKind {
     /// of the impl, and for all the other highlighted regions, it
     /// would return the `DefId` of the function. In other cases (not shown), this
     /// function might return the `DefId` of a closure.
-    pub fn free_region_binding_scope(&self, tcx: TyCtxt<'_, '_>) -> DefId {
+    pub fn free_region_binding_scope(&self, tcx: TyCtxt<'_>) -> DefId {
         match self {
             ty::ReEarlyBound(br) => {
                 tcx.parent(br.def_id).unwrap()
@@ -1682,7 +1682,7 @@ impl RegionKind {
 }
 
 /// Type utilities
-impl<'gcx, 'tcx> TyS<'tcx> {
+impl<'tcx> TyS<'tcx> {
     #[inline]
     pub fn is_unit(&self) -> bool {
         match self.sty {
@@ -1705,7 +1705,7 @@ impl<'gcx, 'tcx> TyS<'tcx> {
     /// `ty.conservative_is_privately_uninhabited` implies that any value of type `ty`
     /// will be `Abi::Uninhabited`. (Note that uninhabited types may have nonzero
     /// size, to account for partial initialisation. See #49298 for details.)
-    pub fn conservative_is_privately_uninhabited(&self, tcx: TyCtxt<'gcx, 'tcx>) -> bool {
+    pub fn conservative_is_privately_uninhabited(&self, tcx: TyCtxt<'tcx>) -> bool {
         // FIXME(varkor): we can make this less conversative by substituting concrete
         // type arguments.
         match self.sty {
@@ -1817,7 +1817,7 @@ impl<'gcx, 'tcx> TyS<'tcx> {
         }
     }
 
-    pub fn sequence_element_type(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Ty<'tcx> {
+    pub fn sequence_element_type(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         match self.sty {
             Array(ty, _) | Slice(ty) => ty,
             Str => tcx.mk_mach_uint(ast::UintTy::U8),
@@ -1825,7 +1825,7 @@ impl<'gcx, 'tcx> TyS<'tcx> {
         }
     }
 
-    pub fn simd_type(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Ty<'tcx> {
+    pub fn simd_type(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         match self.sty {
             Adt(def, substs) => {
                 def.non_enum_variant().fields[0].ty(tcx, substs)
@@ -1834,7 +1834,7 @@ impl<'gcx, 'tcx> TyS<'tcx> {
         }
     }
 
-    pub fn simd_size(&self, _cx: TyCtxt<'_, '_>) -> usize {
+    pub fn simd_size(&self, _cx: TyCtxt<'_>) -> usize {
         match self.sty {
             Adt(def, _) => def.non_enum_variant().fields.len(),
             _ => bug!("simd_size called on invalid type")
@@ -2054,7 +2054,7 @@ impl<'gcx, 'tcx> TyS<'tcx> {
         }
     }
 
-    pub fn fn_sig(&self, tcx: TyCtxt<'gcx, 'tcx>) -> PolyFnSig<'tcx> {
+    pub fn fn_sig(&self, tcx: TyCtxt<'tcx>) -> PolyFnSig<'tcx> {
         match self.sty {
             FnDef(def_id, substs) => {
                 tcx.fn_sig(def_id).subst(tcx, substs)
@@ -2102,7 +2102,7 @@ impl<'gcx, 'tcx> TyS<'tcx> {
     /// If the type contains variants, returns the valid range of variant indices.
     /// FIXME This requires the optimized MIR in the case of generators.
     #[inline]
-    pub fn variant_range(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Range<VariantIdx>> {
+    pub fn variant_range(&self, tcx: TyCtxt<'tcx>) -> Option<Range<VariantIdx>> {
         match self.sty {
             TyKind::Adt(adt, _) => Some(adt.variant_range()),
             TyKind::Generator(def_id, substs, _) => Some(substs.variant_range(def_id, tcx)),
@@ -2116,7 +2116,7 @@ impl<'gcx, 'tcx> TyS<'tcx> {
     #[inline]
     pub fn discriminant_for_variant(
         &self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         variant_index: VariantIdx,
     ) -> Option<Discr<'tcx>> {
         match self.sty {
@@ -2207,7 +2207,7 @@ impl<'gcx, 'tcx> TyS<'tcx> {
     ///
     /// Returning true means the type is known to be sized. Returning
     /// `false` means nothing -- could be sized, might not be.
-    pub fn is_trivially_sized(&self, tcx: TyCtxt<'_, 'tcx>) -> bool {
+    pub fn is_trivially_sized(&self, tcx: TyCtxt<'tcx>) -> bool {
         match self.sty {
             ty::Infer(ty::IntVar(_)) | ty::Infer(ty::FloatVar(_)) |
             ty::Uint(_) | ty::Int(_) | ty::Bool | ty::Float(_) |
@@ -2257,7 +2257,7 @@ static_assert_size!(Const<'_>, 40);
 
 impl<'tcx> Const<'tcx> {
     #[inline]
-    pub fn from_scalar(tcx: TyCtxt<'_, 'tcx>, val: Scalar, ty: Ty<'tcx>) -> &'tcx Self {
+    pub fn from_scalar(tcx: TyCtxt<'tcx>, val: Scalar, ty: Ty<'tcx>) -> &'tcx Self {
         tcx.mk_const(Self {
             val: ConstValue::Scalar(val),
             ty,
@@ -2266,7 +2266,7 @@ impl<'tcx> Const<'tcx> {
 
     #[inline]
     pub fn from_bits(
-        tcx: TyCtxt<'_, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         bits: u128,
         ty: ParamEnvAnd<'tcx, Ty<'tcx>>,
     ) -> &'tcx Self {
@@ -2278,22 +2278,22 @@ impl<'tcx> Const<'tcx> {
     }
 
     #[inline]
-    pub fn zero_sized(tcx: TyCtxt<'_, 'tcx>, ty: Ty<'tcx>) -> &'tcx Self {
+    pub fn zero_sized(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> &'tcx Self {
         Self::from_scalar(tcx, Scalar::zst(), ty)
     }
 
     #[inline]
-    pub fn from_bool(tcx: TyCtxt<'_, 'tcx>, v: bool) -> &'tcx Self {
+    pub fn from_bool(tcx: TyCtxt<'tcx>, v: bool) -> &'tcx Self {
         Self::from_bits(tcx, v as u128, ParamEnv::empty().and(tcx.types.bool))
     }
 
     #[inline]
-    pub fn from_usize(tcx: TyCtxt<'_, 'tcx>, n: u64) -> &'tcx Self {
+    pub fn from_usize(tcx: TyCtxt<'tcx>, n: u64) -> &'tcx Self {
         Self::from_bits(tcx, n as u128, ParamEnv::empty().and(tcx.types.usize))
     }
 
     #[inline]
-    pub fn to_bits(&self, tcx: TyCtxt<'_, 'tcx>, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> Option<u128> {
+    pub fn to_bits(&self, tcx: TyCtxt<'tcx>, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> Option<u128> {
         if self.ty != ty.value {
             return None;
         }
@@ -2310,7 +2310,7 @@ impl<'tcx> Const<'tcx> {
     #[inline]
     pub fn assert_bits(
         &self,
-        tcx: TyCtxt<'_, '_>,
+        tcx: TyCtxt<'_>,
         ty: ParamEnvAnd<'tcx, Ty<'tcx>>,
     ) -> Option<u128> {
         assert_eq!(self.ty, ty.value);
@@ -2320,7 +2320,7 @@ impl<'tcx> Const<'tcx> {
     }
 
     #[inline]
-    pub fn assert_bool(&self, tcx: TyCtxt<'_, '_>) -> Option<bool> {
+    pub fn assert_bool(&self, tcx: TyCtxt<'_>) -> Option<bool> {
         self.assert_bits(tcx, ParamEnv::empty().and(tcx.types.bool)).and_then(|v| match v {
             0 => Some(false),
             1 => Some(true),
@@ -2329,18 +2329,18 @@ impl<'tcx> Const<'tcx> {
     }
 
     #[inline]
-    pub fn assert_usize(&self, tcx: TyCtxt<'_, '_>) -> Option<u64> {
+    pub fn assert_usize(&self, tcx: TyCtxt<'_>) -> Option<u64> {
         self.assert_bits(tcx, ParamEnv::empty().and(tcx.types.usize)).map(|v| v as u64)
     }
 
     #[inline]
-    pub fn unwrap_bits(&self, tcx: TyCtxt<'_, '_>, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> u128 {
+    pub fn unwrap_bits(&self, tcx: TyCtxt<'_>, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> u128 {
         self.assert_bits(tcx, ty).unwrap_or_else(||
             bug!("expected bits of {}, got {:#?}", ty.value, self))
     }
 
     #[inline]
-    pub fn unwrap_usize(&self, tcx: TyCtxt<'_, '_>) -> u64 {
+    pub fn unwrap_usize(&self, tcx: TyCtxt<'_>) -> u64 {
         self.assert_usize(tcx).unwrap_or_else(||
             bug!("expected constant usize, got {:#?}", self))
     }
diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs
index a47217138aa..5a97d8bb725 100644
--- a/src/librustc/ty/subst.rs
+++ b/src/librustc/ty/subst.rs
@@ -138,7 +138,7 @@ impl<'tcx> Kind<'tcx> {
 impl<'a, 'tcx> Lift<'tcx> for Kind<'a> {
     type Lifted = Kind<'tcx>;
 
-    fn lift_to_tcx<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Option<Self::Lifted> {
+    fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
         match self.unpack() {
             UnpackedKind::Lifetime(lt) => tcx.lift(&lt).map(|lt| lt.into()),
             UnpackedKind::Type(ty) => tcx.lift(&ty).map(|ty| ty.into()),
@@ -148,7 +148,7 @@ impl<'a, 'tcx> Lift<'tcx> for Kind<'a> {
 }
 
 impl<'tcx> TypeFoldable<'tcx> for Kind<'tcx> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         match self.unpack() {
             UnpackedKind::Lifetime(lt) => lt.fold_with(folder).into(),
             UnpackedKind::Type(ty) => ty.fold_with(folder).into(),
@@ -182,9 +182,9 @@ pub type InternalSubsts<'tcx> = List<Kind<'tcx>>;
 
 pub type SubstsRef<'tcx> = &'tcx InternalSubsts<'tcx>;
 
-impl<'a, 'gcx, 'tcx> InternalSubsts<'tcx> {
+impl<'a, 'tcx> InternalSubsts<'tcx> {
     /// Creates a `InternalSubsts` that maps each generic parameter to itself.
-    pub fn identity_for_item(tcx: TyCtxt<'gcx, 'tcx>, def_id: DefId) -> SubstsRef<'tcx> {
+    pub fn identity_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> SubstsRef<'tcx> {
         Self::for_item(tcx, def_id, |param, _| {
             tcx.mk_param_from_def(param)
         })
@@ -194,7 +194,7 @@ impl<'a, 'gcx, 'tcx> InternalSubsts<'tcx> {
     /// 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<'gcx, 'tcx>, def_id: DefId) -> SubstsRef<'tcx> {
+    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 { .. } => {
@@ -230,7 +230,7 @@ impl<'a, 'gcx, 'tcx> InternalSubsts<'tcx> {
     /// The closures get to observe the `InternalSubsts` as they're
     /// being built, which can be used to correctly
     /// substitute defaults of generic parameters.
-    pub fn for_item<F>(tcx: TyCtxt<'gcx, 'tcx>, def_id: DefId, mut mk_kind: F) -> SubstsRef<'tcx>
+    pub fn for_item<F>(tcx: TyCtxt<'tcx>, def_id: DefId, mut mk_kind: F) -> SubstsRef<'tcx>
     where
         F: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> Kind<'tcx>,
     {
@@ -243,7 +243,7 @@ impl<'a, 'gcx, 'tcx> InternalSubsts<'tcx> {
 
     pub fn extend_to<F>(
         &self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         def_id: DefId,
         mut mk_kind: F,
     ) -> SubstsRef<'tcx>
@@ -259,7 +259,7 @@ impl<'a, 'gcx, 'tcx> InternalSubsts<'tcx> {
 
     fn fill_item<F>(
         substs: &mut SmallVec<[Kind<'tcx>; 8]>,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         defs: &ty::Generics,
         mk_kind: &mut F,
     ) where
@@ -373,7 +373,7 @@ impl<'a, 'gcx, 'tcx> InternalSubsts<'tcx> {
     /// parameters (e.g., method parameters) on top of that base.
     pub fn rebase_onto(
         &self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         source_ancestor: DefId,
         target_substs: SubstsRef<'tcx>,
     ) -> SubstsRef<'tcx> {
@@ -381,13 +381,13 @@ impl<'a, 'gcx, 'tcx> InternalSubsts<'tcx> {
         tcx.mk_substs(target_substs.iter().chain(&self[defs.params.len()..]).cloned())
     }
 
-    pub fn truncate_to(&self, tcx: TyCtxt<'gcx, 'tcx>, generics: &ty::Generics) -> SubstsRef<'tcx> {
+    pub fn truncate_to(&self, tcx: TyCtxt<'tcx>, generics: &ty::Generics) -> SubstsRef<'tcx> {
         tcx.mk_substs(self.iter().take(generics.count()).cloned())
     }
 }
 
 impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         let params: SmallVec<[_; 8]> = self.iter().map(|k| k.fold_with(folder)).collect();
 
         // If folding doesn't change the substs, it's faster to avoid
@@ -414,22 +414,22 @@ impl<'tcx> serialize::UseSpecializedDecodable for SubstsRef<'tcx> {}
 // there is more information available (for better errors).
 
 pub trait Subst<'tcx>: Sized {
-    fn subst<'gcx>(&self, tcx: TyCtxt<'gcx, 'tcx>, substs: &[Kind<'tcx>]) -> Self {
+    fn subst(&self, tcx: TyCtxt<'tcx>, substs: &[Kind<'tcx>]) -> Self {
         self.subst_spanned(tcx, substs, None)
     }
 
-    fn subst_spanned<'gcx>(
+    fn subst_spanned(
         &self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         substs: &[Kind<'tcx>],
         span: Option<Span>,
     ) -> Self;
 }
 
 impl<'tcx, T: TypeFoldable<'tcx>> Subst<'tcx> for T {
-    fn subst_spanned<'gcx>(
+    fn subst_spanned(
         &self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         substs: &[Kind<'tcx>],
         span: Option<Span>,
     ) -> T {
@@ -446,8 +446,8 @@ impl<'tcx, T: TypeFoldable<'tcx>> Subst<'tcx> for T {
 ///////////////////////////////////////////////////////////////////////////
 // The actual substitution engine itself is a type folder.
 
-struct SubstFolder<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
-    tcx: TyCtxt<'gcx, 'tcx>,
+struct SubstFolder<'a, 'tcx> {
+    tcx: TyCtxt<'tcx>,
     substs: &'a [Kind<'tcx>],
 
     /// The location for which the substitution is performed, if available.
@@ -463,8 +463,8 @@ struct SubstFolder<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
     binders_passed: u32,
 }
 
-impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for SubstFolder<'a, 'gcx, 'tcx> {
-    fn tcx<'b>(&'b self) -> TyCtxt<'gcx, 'tcx> { self.tcx }
+impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
+    fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.tcx }
 
     fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T> {
         self.binders_passed += 1;
@@ -547,7 +547,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for SubstFolder<'a, 'gcx, 'tcx> {
     }
 }
 
-impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> SubstFolder<'a, 'tcx> {
     fn ty_for_param(&self, p: ty::ParamTy, source_ty: Ty<'tcx>) -> Ty<'tcx> {
         // Look up the type in the substitutions. It really should be in there.
         let opt_ty = self.substs.get(p.index as usize).map(|k| k.unpack());
diff --git a/src/librustc/ty/trait_def.rs b/src/librustc/ty/trait_def.rs
index 1f99d97605c..c40d4d5b9cc 100644
--- a/src/librustc/ty/trait_def.rs
+++ b/src/librustc/ty/trait_def.rs
@@ -46,7 +46,7 @@ pub struct TraitImpls {
     non_blanket_impls: FxHashMap<fast_reject::SimplifiedType, Vec<DefId>>,
 }
 
-impl<'gcx, 'tcx> TraitDef {
+impl<'tcx> TraitDef {
     pub fn new(def_id: DefId,
                unsafety: hir::Unsafety,
                paren_sugar: bool,
@@ -66,14 +66,14 @@ impl<'gcx, 'tcx> TraitDef {
 
     pub fn ancestors(
         &self,
-        tcx: TyCtxt<'gcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         of_impl: DefId,
-    ) -> specialization_graph::Ancestors<'gcx> {
+    ) -> specialization_graph::Ancestors<'tcx> {
         specialization_graph::ancestors(tcx, self.def_id, of_impl)
     }
 }
 
-impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
+impl<'tcx> TyCtxt<'tcx> {
     pub fn for_each_impl<F: FnMut(DefId)>(self, def_id: DefId, mut f: F) {
         let impls = self.trait_impls_of(def_id);
 
@@ -151,7 +151,7 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
 
 // Query provider for `trait_impls_of`.
 pub(super) fn trait_impls_of_provider<'tcx>(
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     trait_id: DefId,
 ) -> &'tcx TraitImpls {
     let mut impls = TraitImpls::default();
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index 57319db6340..8b1d9d97276 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -51,10 +51,10 @@ impl<'tcx> fmt::Display for Discr<'tcx> {
 
 impl<'tcx> Discr<'tcx> {
     /// Adds `1` to the value and wraps around if the maximum for the type is reached.
-    pub fn wrap_incr<'gcx>(self, tcx: TyCtxt<'gcx, 'tcx>) -> Self {
+    pub fn wrap_incr(self, tcx: TyCtxt<'tcx>) -> Self {
         self.checked_add(tcx, 1).0
     }
-    pub fn checked_add<'gcx>(self, tcx: TyCtxt<'gcx, 'tcx>, n: u128) -> (Self, bool) {
+    pub fn checked_add(self, tcx: TyCtxt<'tcx>, n: u128) -> (Self, bool) {
         let (int, signed) = match self.ty.sty {
             Int(ity) => (Integer::from_attr(&tcx, SignedInt(ity)), true),
             Uint(uty) => (Integer::from_attr(&tcx, UnsignedInt(uty)), false),
@@ -104,17 +104,17 @@ impl<'tcx> Discr<'tcx> {
 }
 
 pub trait IntTypeExt {
-    fn to_ty<'gcx, 'tcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Ty<'tcx>;
+    fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx>;
     fn disr_incr<'tcx>(
         &self,
-        tcx: TyCtxt<'tcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         val: Option<Discr<'tcx>>,
     ) -> Option<Discr<'tcx>>;
-    fn initial_discriminant<'tcx>(&self, tcx: TyCtxt<'tcx, 'tcx>) -> Discr<'tcx>;
+    fn initial_discriminant<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Discr<'tcx>;
 }
 
 impl IntTypeExt for attr::IntType {
-    fn to_ty<'gcx, 'tcx>(&self, tcx: TyCtxt<'gcx, 'tcx>) -> Ty<'tcx> {
+    fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
         match *self {
             SignedInt(ast::IntTy::I8)       => tcx.types.i8,
             SignedInt(ast::IntTy::I16)      => tcx.types.i16,
@@ -131,7 +131,7 @@ impl IntTypeExt for attr::IntType {
         }
     }
 
-    fn initial_discriminant<'tcx>(&self, tcx: TyCtxt<'tcx, 'tcx>) -> Discr<'tcx> {
+    fn initial_discriminant<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Discr<'tcx> {
         Discr {
             val: 0,
             ty: self.to_ty(tcx)
@@ -140,7 +140,7 @@ impl IntTypeExt for attr::IntType {
 
     fn disr_incr<'tcx>(
         &self,
-        tcx: TyCtxt<'tcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         val: Option<Discr<'tcx>>,
     ) -> Option<Discr<'tcx>> {
         if let Some(val) = val {
@@ -183,7 +183,7 @@ pub enum Representability {
 impl<'tcx> ty::ParamEnv<'tcx> {
     pub fn can_type_implement_copy(
         self,
-        tcx: TyCtxt<'tcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         self_type: Ty<'tcx>,
     ) -> Result<(), CopyImplementationError<'tcx>> {
         // FIXME: (@jroesch) float this code up
@@ -232,7 +232,7 @@ impl<'tcx> ty::ParamEnv<'tcx> {
     }
 }
 
-impl<'tcx> TyCtxt<'tcx, 'tcx> {
+impl<'tcx> TyCtxt<'tcx> {
     /// Creates a hash of the type `Ty` which will be the same no matter what crate
     /// context it's calculated within. This is used by the `type_id` intrinsic.
     pub fn type_id_hash(self, ty: Ty<'tcx>) -> u64 {
@@ -253,7 +253,7 @@ impl<'tcx> TyCtxt<'tcx, 'tcx> {
     }
 }
 
-impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
+impl<'tcx> TyCtxt<'tcx> {
     pub fn has_error_field(self, ty: Ty<'tcx>) -> bool {
         if let ty::Adt(def, substs) = ty.sty {
             for field in def.all_fields() {
@@ -628,7 +628,7 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
     ) -> Result<Ty<'tcx>, Ty<'tcx>> {
         use crate::ty::fold::TypeFolder;
 
-        struct OpaqueTypeExpander<'gcx, 'tcx> {
+        struct OpaqueTypeExpander<'tcx> {
             // Contains the DefIds of the opaque types that are currently being
             // expanded. When we expand an opaque type we insert the DefId of
             // that type, and when we finish expanding that type we remove the
@@ -636,10 +636,10 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
             seen_opaque_tys: FxHashSet<DefId>,
             primary_def_id: DefId,
             found_recursion: bool,
-            tcx: TyCtxt<'gcx, 'tcx>,
+            tcx: TyCtxt<'tcx>,
         }
 
-        impl<'gcx, 'tcx> OpaqueTypeExpander<'gcx, 'tcx> {
+        impl<'tcx> OpaqueTypeExpander<'tcx> {
             fn expand_opaque_ty(
                 &mut self,
                 def_id: DefId,
@@ -662,8 +662,8 @@ impl<'gcx, 'tcx> TyCtxt<'gcx, 'tcx> {
             }
         }
 
-        impl<'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpaqueTypeExpander<'gcx, 'tcx> {
-            fn tcx(&self) -> TyCtxt<'gcx, 'tcx> {
+        impl<'tcx> TypeFolder<'tcx> for OpaqueTypeExpander<'tcx> {
+            fn tcx(&self) -> TyCtxt<'tcx> {
                 self.tcx
             }
 
@@ -701,7 +701,7 @@ impl<'tcx> ty::TyS<'tcx> {
     /// winds up being reported as an error during NLL borrow check.
     pub fn is_copy_modulo_regions(
         &'tcx self,
-        tcx: TyCtxt<'tcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         span: Span,
     ) -> bool {
@@ -716,7 +716,7 @@ impl<'tcx> ty::TyS<'tcx> {
     /// actually carry lifetime requirements.
     pub fn is_sized(
         &'tcx self,
-        tcx_at: TyCtxtAt<'tcx, 'tcx>,
+        tcx_at: TyCtxtAt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
     ) -> bool {
         tcx_at.is_sized_raw(param_env.and(self))
@@ -731,7 +731,7 @@ impl<'tcx> ty::TyS<'tcx> {
     /// effectively an implementation detail.
     pub fn is_freeze(
         &'tcx self,
-        tcx: TyCtxt<'tcx, 'tcx>,
+        tcx: TyCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         span: Span,
     ) -> bool {
@@ -745,7 +745,7 @@ impl<'tcx> ty::TyS<'tcx> {
     /// (Note that this implies that if `ty` has a destructor attached,
     /// then `needs_drop` will definitely return `true` for `ty`.)
     #[inline]
-    pub fn needs_drop(&'tcx self, tcx: TyCtxt<'tcx, 'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
+    pub fn needs_drop(&'tcx self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
         tcx.needs_drop_raw(param_env.and(self)).0
     }
 
@@ -764,7 +764,7 @@ impl<'tcx> ty::TyS<'tcx> {
 
     /// Check whether a type is representable. This means it cannot contain unboxed
     /// structural recursion. This check is needed for structs and enums.
-    pub fn is_representable(&'tcx self, tcx: TyCtxt<'tcx, 'tcx>, sp: Span) -> Representability {
+    pub fn is_representable(&'tcx self, tcx: TyCtxt<'tcx>, sp: Span) -> Representability {
         // Iterate until something non-representable is found
         fn fold_repr<It: Iterator<Item=Representability>>(iter: It) -> Representability {
             iter.fold(Representability::Representable, |r1, r2| {
@@ -779,7 +779,7 @@ impl<'tcx> ty::TyS<'tcx> {
         }
 
         fn are_inner_types_recursive<'tcx>(
-            tcx: TyCtxt<'tcx, 'tcx>,
+            tcx: TyCtxt<'tcx>,
             sp: Span,
             seen: &mut Vec<Ty<'tcx>>,
             representable_cache: &mut FxHashMap<Ty<'tcx>, Representability>,
@@ -839,7 +839,7 @@ impl<'tcx> ty::TyS<'tcx> {
         // Does the type `ty` directly (without indirection through a pointer)
         // contain any types on stack `seen`?
         fn is_type_structurally_recursive<'tcx>(
-            tcx: TyCtxt<'tcx, 'tcx>,
+            tcx: TyCtxt<'tcx>,
             sp: Span,
             seen: &mut Vec<Ty<'tcx>>,
             representable_cache: &mut FxHashMap<Ty<'tcx>, Representability>,
@@ -860,7 +860,7 @@ impl<'tcx> ty::TyS<'tcx> {
         }
 
         fn is_type_structurally_recursive_inner<'tcx>(
-            tcx: TyCtxt<'tcx, 'tcx>,
+            tcx: TyCtxt<'tcx>,
             sp: Span,
             seen: &mut Vec<Ty<'tcx>>,
             representable_cache: &mut FxHashMap<Ty<'tcx>, Representability>,
@@ -937,7 +937,7 @@ impl<'tcx> ty::TyS<'tcx> {
     }
 }
 
-fn is_copy_raw<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
+fn is_copy_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
     let (param_env, ty) = query.into_parts();
     let trait_def_id = tcx.require_lang_item(lang_items::CopyTraitLangItem);
     tcx.infer_ctxt()
@@ -950,7 +950,7 @@ fn is_copy_raw<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'t
         ))
 }
 
-fn is_sized_raw<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
+fn is_sized_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
     let (param_env, ty) = query.into_parts();
     let trait_def_id = tcx.require_lang_item(lang_items::SizedTraitLangItem);
     tcx.infer_ctxt()
@@ -963,7 +963,7 @@ fn is_sized_raw<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'
         ))
 }
 
-fn is_freeze_raw<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
+fn is_freeze_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
     let (param_env, ty) = query.into_parts();
     let trait_def_id = tcx.require_lang_item(lang_items::FreezeTraitLangItem);
     tcx.infer_ctxt()
@@ -980,7 +980,7 @@ fn is_freeze_raw<'tcx>(tcx: TyCtxt<'tcx, 'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<
 pub struct NeedsDrop(pub bool);
 
 fn needs_drop_raw<'tcx>(
-    tcx: TyCtxt<'tcx, 'tcx>,
+    tcx: TyCtxt<'tcx>,
     query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
 ) -> NeedsDrop {
     let (param_env, ty) = query.into_parts();
diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs
index 1ed88f395a9..65feb4c08d9 100644
--- a/src/librustc/ty/wf.rs
+++ b/src/librustc/ty/wf.rs
@@ -15,7 +15,7 @@ use crate::mir::interpret::ConstValue;
 /// inference variable, returns `None`, because we are not able to
 /// make any progress at all. This is to prevent "livelock" where we
 /// say "$0 is WF if $0 is WF".
-pub fn obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
+pub fn obligations<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                                    param_env: ty::ParamEnv<'tcx>,
                                    body_id: hir::HirId,
                                    ty: Ty<'tcx>,
@@ -41,7 +41,7 @@ pub fn obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
 /// well-formed.  For example, if there is a trait `Set` defined like
 /// `trait Set<K:Eq>`, then the trait reference `Foo: Set<Bar>` is WF
 /// if `Bar: Eq`.
-pub fn trait_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
+pub fn trait_obligations<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                                          param_env: ty::ParamEnv<'tcx>,
                                          body_id: hir::HirId,
                                          trait_ref: &ty::TraitRef<'tcx>,
@@ -53,7 +53,7 @@ pub fn trait_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
     wf.normalize()
 }
 
-pub fn predicate_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
+pub fn predicate_obligations<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
                                              param_env: ty::ParamEnv<'tcx>,
                                              body_id: hir::HirId,
                                              predicate: &ty::Predicate<'tcx>,
@@ -101,8 +101,8 @@ pub fn predicate_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
     wf.normalize()
 }
 
-struct WfPredicates<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
-    infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
+struct WfPredicates<'a, 'tcx: 'a> {
+    infcx: &'a InferCtxt<'a, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     body_id: hir::HirId,
     span: Span,
@@ -138,7 +138,7 @@ enum Elaborate {
     None,
 }
 
-impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
+impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
     fn cause(&mut self, code: traits::ObligationCauseCode<'tcx>) -> traits::ObligationCause<'tcx> {
         traits::ObligationCause::new(self.span, self.body_id, code)
     }
@@ -508,8 +508,8 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
 /// they declare `trait SomeTrait : 'static`, for example, then
 /// `'static` would appear in the list. The hard work is done by
 /// `ty::required_region_bounds`, see that for more information.
-pub fn object_region_bounds<'gcx, 'tcx>(
-    tcx: TyCtxt<'gcx, 'tcx>,
+pub fn object_region_bounds<'tcx>(
+    tcx: TyCtxt<'tcx>,
     existential_predicates: ty::Binder<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>,
 ) -> Vec<ty::Region<'tcx>> {
     // Since we don't actually *know* the self type for an object,