]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_ast_lowering/src/lib.rs
Extract create_and_capture_lifetime_defs function
[rust.git] / compiler / rustc_ast_lowering / src / lib.rs
index d4b41aad08ca4ba6e839168eb05e7bd15d2f6062..9009ae7a0510f2407a48fb1070205db6276aa975 100644 (file)
@@ -957,7 +957,7 @@ fn lower_assoc_ty_constraint(
         let kind = match constraint.kind {
             AssocConstraintKind::Equality { ref term } => {
                 let term = match term {
-                    Term::Ty(ref ty) => self.lower_ty(ty, itctx).into(),
+                    Term::Ty(ref ty) => self.lower_ty(ty, itctx, true).into(),
                     Term::Const(ref c) => self.lower_anon_const(c).into(),
                 };
                 hir::TypeBindingKind::Equality { term }
@@ -1022,6 +1022,7 @@ fn lower_assoc_ty_constraint(
                                 tokens: None,
                             },
                             itctx,
+                            true,
                         );
 
                         hir::TypeBindingKind::Equality { term: ty.into() }
@@ -1029,7 +1030,7 @@ fn lower_assoc_ty_constraint(
                 } else {
                     // Desugar `AssocTy: Bounds` into a type binding where the
                     // later desugars into a trait predicate.
-                    let bounds = self.lower_param_bounds(bounds, itctx);
+                    let bounds = self.lower_param_bounds(bounds, itctx, true);
 
                     hir::TypeBindingKind::Constraint { bounds }
                 }
@@ -1088,7 +1089,7 @@ fn lower_generic_arg(
         itctx: ImplTraitContext,
     ) -> hir::GenericArg<'hir> {
         match arg {
-            ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(&lt)),
+            ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(&lt, true)),
             ast::GenericArg::Type(ty) => {
                 match ty.kind {
                     TyKind::Infer if self.tcx.features().generic_arg_infer => {
@@ -1137,7 +1138,7 @@ fn lower_generic_arg(
                     }
                     _ => {}
                 }
-                GenericArg::Type(self.lower_ty_direct(&ty, itctx))
+                GenericArg::Type(self.lower_ty_direct(&ty, itctx, true))
             }
             ast::GenericArg::Const(ct) => GenericArg::Const(ConstArg {
                 value: self.lower_anon_const(&ct),
@@ -1147,8 +1148,8 @@ fn lower_generic_arg(
     }
 
     #[instrument(level = "debug", skip(self))]
-    fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> &'hir hir::Ty<'hir> {
-        self.arena.alloc(self.lower_ty_direct(t, itctx))
+    fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext, captures: bool) -> &'hir hir::Ty<'hir> {
+        self.arena.alloc(self.lower_ty_direct(t, itctx, captures))
     }
 
     fn lower_path_ty(
@@ -1158,6 +1159,7 @@ fn lower_path_ty(
         path: &Path,
         param_mode: ParamMode,
         itctx: ImplTraitContext,
+        captures: bool,
     ) -> hir::Ty<'hir> {
         // Check whether we should interpret this as a bare trait object.
         // This check mirrors the one in late resolution.  We only introduce this special case in
@@ -1177,6 +1179,7 @@ fn lower_path_ty(
                         span: t.span
                     },
                     itctx,
+                    captures,
                 );
                 let bounds = this.arena.alloc_from_iter([bound]);
                 let lifetime_bound = this.elided_dyn_bound(t.span);
@@ -1187,7 +1190,7 @@ fn lower_path_ty(
         }
 
         let id = self.lower_node_id(t.id);
-        let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx);
+        let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx, true);
         self.ty_path(id, t.span, qpath)
     }
 
@@ -1199,11 +1202,16 @@ fn ty_tup(&mut self, span: Span, tys: &'hir [hir::Ty<'hir>]) -> hir::Ty<'hir> {
         self.ty(span, hir::TyKind::Tup(tys))
     }
 
-    fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
+    fn lower_ty_direct(
+        &mut self,
+        t: &Ty,
+        itctx: ImplTraitContext,
+        captures: bool,
+    ) -> hir::Ty<'hir> {
         let kind = match t.kind {
             TyKind::Infer => hir::TyKind::Infer,
             TyKind::Err => hir::TyKind::Err,
-            TyKind::Slice(ref ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
+            TyKind::Slice(ref ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx, captures)),
             TyKind::Ptr(ref mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
             TyKind::Rptr(ref region, ref mt) => {
                 let region = region.unwrap_or_else(|| {
@@ -1218,7 +1226,7 @@ fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir>
                     let span = self.tcx.sess.source_map().next_point(t.span.shrink_to_lo());
                     Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id }
                 });
-                let lifetime = self.lower_lifetime(&region);
+                let lifetime = self.lower_lifetime(&region, captures);
                 hir::TyKind::Rptr(lifetime, self.lower_mt(mt, itctx))
             }
             TyKind::BareFn(ref f) => {
@@ -1233,14 +1241,16 @@ fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir>
                 })
             }
             TyKind::Never => hir::TyKind::Never,
-            TyKind::Tup(ref tys) => hir::TyKind::Tup(
-                self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx))),
-            ),
+            TyKind::Tup(ref tys) => {
+                hir::TyKind::Tup(self.arena.alloc_from_iter(
+                    tys.iter().map(|ty| self.lower_ty_direct(ty, itctx, captures)),
+                ))
+            }
             TyKind::Paren(ref ty) => {
-                return self.lower_ty_direct(ty, itctx);
+                return self.lower_ty_direct(ty, itctx, captures);
             }
             TyKind::Path(ref qself, ref path) => {
-                return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx);
+                return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx, captures);
             }
             TyKind::ImplicitSelf => {
                 let res = self.expect_full_res(t.id);
@@ -1256,9 +1266,10 @@ fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir>
                     }),
                 ))
             }
-            TyKind::Array(ref ty, ref length) => {
-                hir::TyKind::Array(self.lower_ty(ty, itctx), self.lower_array_length(length))
-            }
+            TyKind::Array(ref ty, ref length) => hir::TyKind::Array(
+                self.lower_ty(ty, itctx, captures),
+                self.lower_array_length(length),
+            ),
             TyKind::Typeof(ref expr) => hir::TyKind::Typeof(self.lower_anon_const(expr)),
             TyKind::TraitObject(ref bounds, kind) => {
                 let mut lifetime_bound = None;
@@ -1269,7 +1280,7 @@ fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir>
                                 GenericBound::Trait(
                                     ref ty,
                                     TraitBoundModifier::None | TraitBoundModifier::MaybeConst,
-                                ) => Some(this.lower_poly_trait_ref(ty, itctx)),
+                                ) => Some(this.lower_poly_trait_ref(ty, itctx, captures)),
                                 // `~const ?Bound` will cause an error during AST validation
                                 // anyways, so treat it like `?Bound` as compilation proceeds.
                                 GenericBound::Trait(
@@ -1278,7 +1289,7 @@ fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir>
                                 ) => None,
                                 GenericBound::Outlives(ref lifetime) => {
                                     if lifetime_bound.is_none() {
-                                        lifetime_bound = Some(this.lower_lifetime(lifetime));
+                                        lifetime_bound = Some(this.lower_lifetime(lifetime, true));
                                     }
                                     None
                                 }
@@ -1293,17 +1304,17 @@ fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir>
             TyKind::ImplTrait(def_node_id, ref bounds) => {
                 let span = t.span;
                 match itctx {
-                    ImplTraitContext::ReturnPositionOpaqueTy { origin } => self
-                        .lower_opaque_impl_trait(span, origin, def_node_id, |this| {
-                            this.lower_param_bounds(bounds, itctx)
-                        }),
+                    ImplTraitContext::ReturnPositionOpaqueTy { origin } => {
+                        self.lower_opaque_impl_trait(span, origin, def_node_id, bounds, itctx)
+                    }
                     ImplTraitContext::TypeAliasesOpaqueTy => {
                         let nested_itctx = ImplTraitContext::TypeAliasesOpaqueTy;
                         self.lower_opaque_impl_trait(
                             span,
                             hir::OpaqueTyOrigin::TyAlias,
                             def_node_id,
-                            |this| this.lower_param_bounds(bounds, nested_itctx),
+                            bounds,
+                            nested_itctx,
                         )
                     }
                     ImplTraitContext::Universal => {
@@ -1343,13 +1354,14 @@ fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir>
         hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.lower_node_id(t.id) }
     }
 
-    #[tracing::instrument(level = "debug", skip(self, lower_bounds))]
+    #[tracing::instrument(level = "debug", skip(self))]
     fn lower_opaque_impl_trait(
         &mut self,
         span: Span,
         origin: hir::OpaqueTyOrigin,
         opaque_ty_node_id: NodeId,
-        lower_bounds: impl FnOnce(&mut Self) -> hir::GenericBounds<'hir>,
+        bounds: &GenericBounds,
+        itctx: ImplTraitContext,
     ) -> hir::TyKind<'hir> {
         // Make sure we know that some funky desugaring has been going on here.
         // This is a first: there is code in other places like for loop
@@ -1363,13 +1375,32 @@ fn lower_opaque_impl_trait(
         let mut collected_lifetimes = FxHashMap::default();
         self.with_hir_id_owner(opaque_ty_node_id, |lctx| {
             let hir_bounds = if origin == hir::OpaqueTyOrigin::TyAlias {
-                lower_bounds(lctx)
+                lctx.lower_param_bounds(bounds, itctx, true)
             } else {
-                lctx.while_capturing_lifetimes(
-                    opaque_ty_def_id,
-                    &mut collected_lifetimes,
-                    lower_bounds,
-                )
+                debug!(?lctx.captured_lifetimes);
+
+                let lifetime_stash = std::mem::replace(
+                    &mut lctx.captured_lifetimes,
+                    Some(LifetimeCaptureContext {
+                        parent_def_id: opaque_ty_def_id,
+                        captures: std::mem::take(&mut collected_lifetimes),
+                        binders_to_ignore: Default::default(),
+                    }),
+                );
+
+                let (lifetimes_in_bounds, binders_to_ignore) = ast::lifetimes_in_bounds(bounds);
+                debug!(?lifetimes_in_bounds);
+                debug!(?binders_to_ignore);
+
+                lctx.create_and_capture_lifetime_defs(&lifetimes_in_bounds, &binders_to_ignore);
+
+                let ret = lctx.lower_param_bounds(bounds, itctx, false);
+
+                let ctxt = std::mem::replace(&mut lctx.captured_lifetimes, lifetime_stash).unwrap();
+
+                collected_lifetimes = ctxt.captures;
+
+                ret
             };
             debug!(?collected_lifetimes);
 
@@ -1417,7 +1448,7 @@ fn lower_opaque_impl_trait(
             |(_, (span, _, p_name, res))| {
                 let id = self.next_node_id();
                 let ident = Ident::new(p_name.ident().name, span);
-                let l = self.new_named_lifetime_with_res(id, span, ident, res);
+                let l = self.new_named_lifetime_with_res(id, span, ident, res, true);
                 hir::GenericArg::Lifetime(l)
             },
         ));
@@ -1450,6 +1481,86 @@ fn generate_opaque_type(
         hir::OwnerNode::Item(self.arena.alloc(opaque_ty_item))
     }
 
+    fn create_and_capture_lifetime_defs(
+        &mut self,
+        lifetimes_in_bounds: &[&Lifetime],
+        binders_to_ignore: &FxHashMap<NodeId, Vec<NodeId>>,
+    ) {
+        for lifetime in lifetimes_in_bounds {
+            let ident = lifetime.ident;
+            let span = ident.span;
+
+            let res = self.resolver.get_lifetime_res(lifetime.id).unwrap_or(LifetimeRes::Error);
+            debug!(?res);
+
+            if let Some(mut captured_lifetimes) = self.captured_lifetimes.take() {
+                match res {
+                    LifetimeRes::Param { param, binder } => {
+                        if !captured_lifetimes.binders_to_ignore.contains(&binder)
+                            && !binders_to_ignore
+                                .get(&lifetime.id)
+                                .unwrap_or(&Vec::new())
+                                .contains(&binder)
+                        {
+                            match captured_lifetimes.captures.entry(param) {
+                                Entry::Occupied(_) => {}
+                                Entry::Vacant(v) => {
+                                    let node_id = self.next_node_id();
+                                    let name = ParamName::Plain(ident);
+
+                                    self.create_def(
+                                        captured_lifetimes.parent_def_id,
+                                        node_id,
+                                        DefPathData::LifetimeNs(name.ident().name),
+                                    );
+
+                                    v.insert((span, node_id, name, res));
+                                }
+                            }
+                        }
+                    }
+
+                    LifetimeRes::Fresh { param, binder } => {
+                        debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
+                        if !captured_lifetimes.binders_to_ignore.contains(&binder)
+                            && !binders_to_ignore
+                                .get(&lifetime.id)
+                                .unwrap_or(&Vec::new())
+                                .contains(&binder)
+                        {
+                            let param = self.local_def_id(param);
+                            match captured_lifetimes.captures.entry(param) {
+                                Entry::Occupied(_) => {}
+                                Entry::Vacant(v) => {
+                                    let node_id = self.next_node_id();
+
+                                    let name = ParamName::Fresh;
+
+                                    self.create_def(
+                                        captured_lifetimes.parent_def_id,
+                                        node_id,
+                                        DefPathData::LifetimeNs(kw::UnderscoreLifetime),
+                                    );
+
+                                    v.insert((span, node_id, name, res));
+                                }
+                            }
+                        }
+                    }
+
+                    LifetimeRes::Infer | LifetimeRes::Static | LifetimeRes::Error => {}
+
+                    res => panic!(
+                        "Unexpected lifetime resolution {:?} for {:?} at {:?}",
+                        res, lifetime.ident, lifetime.ident.span
+                    ),
+                }
+
+                self.captured_lifetimes = Some(captured_lifetimes);
+            }
+        }
+    }
+
     fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Ident] {
         // Skip the `...` (`CVarArgs`) trailing arguments from the AST,
         // as they are not explicit in HIR/Ty function signatures.
@@ -1495,7 +1606,7 @@ fn lower_fn_decl(
         }
         let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {
             if fn_node_id.is_some() {
-                self.lower_ty_direct(&param.ty, ImplTraitContext::Universal)
+                self.lower_ty_direct(&param.ty, ImplTraitContext::Universal, true)
             } else {
                 self.lower_ty_direct(
                     &param.ty,
@@ -1509,6 +1620,7 @@ fn lower_fn_decl(
                         FnDeclKind::Trait => ImplTraitPosition::TraitParam,
                         FnDeclKind::Impl => ImplTraitPosition::ImplParam,
                     }),
+                    true,
                 )
             }
         }));
@@ -1540,7 +1652,7 @@ fn lower_fn_decl(
                             FnDeclKind::Impl => ImplTraitPosition::ImplReturn,
                         }),
                     };
-                    hir::FnRetTy::Return(self.lower_ty(ty, context))
+                    hir::FnRetTy::Return(self.lower_ty(ty, context, true))
                 }
                 FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(span)),
             }
@@ -1582,11 +1694,9 @@ fn lower_fn_decl(
     //
     //     type OpaqueTy<generics_from_parent_fn> = impl Future<Output = T>;
     //
-    // `inputs`: lowered types of parameters to the function (used to collect lifetimes)
     // `output`: unlowered output type (`T` in `-> T`)
     // `fn_def_id`: `DefId` of the parent function (used to create child impl trait definition)
     // `opaque_ty_node_id`: `NodeId` of the opaque `impl Trait` type that should be created
-    // `elided_lt_replacement`: replacement for elided lifetimes in the return type
     #[tracing::instrument(level = "debug", skip(self))]
     fn lower_async_fn_ret_ty(
         &mut self,
@@ -1748,7 +1858,7 @@ fn lower_async_fn_ret_ty(
             self.arena.alloc_from_iter(captures.into_iter().map(|(_, (span, _, p_name, res))| {
                 let id = self.next_node_id();
                 let ident = Ident::new(p_name.ident().name, span);
-                let l = self.new_named_lifetime_with_res(id, span, ident, res);
+                let l = self.new_named_lifetime_with_res(id, span, ident, res, true);
                 hir::GenericArg::Lifetime(l)
             }));
 
@@ -1778,7 +1888,7 @@ fn lower_async_fn_output_type_to_future_bound(
                 let context = ImplTraitContext::ReturnPositionOpaqueTy {
                     origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
                 };
-                self.lower_ty(ty, context)
+                self.lower_ty(ty, context, true)
             }
             FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),
         };
@@ -1805,23 +1915,24 @@ fn lower_param_bound(
         &mut self,
         tpb: &GenericBound,
         itctx: ImplTraitContext,
+        captures: bool,
     ) -> hir::GenericBound<'hir> {
         match tpb {
             GenericBound::Trait(p, modifier) => hir::GenericBound::Trait(
-                self.lower_poly_trait_ref(p, itctx),
+                self.lower_poly_trait_ref(p, itctx, captures),
                 self.lower_trait_bound_modifier(*modifier),
             ),
             GenericBound::Outlives(lifetime) => {
-                hir::GenericBound::Outlives(self.lower_lifetime(lifetime))
+                hir::GenericBound::Outlives(self.lower_lifetime(lifetime, captures))
             }
         }
     }
 
-    fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime {
+    fn lower_lifetime(&mut self, l: &Lifetime, captures: bool) -> hir::Lifetime {
         let span = self.lower_span(l.ident.span);
         let ident = self.lower_ident(l.ident);
         let res = self.resolver.get_lifetime_res(l.id).unwrap_or(LifetimeRes::Error);
-        self.new_named_lifetime_with_res(l.id, span, ident, res)
+        self.new_named_lifetime_with_res(l.id, span, ident, res, captures)
     }
 
     #[tracing::instrument(level = "debug", skip(self))]
@@ -1831,35 +1942,45 @@ fn new_named_lifetime_with_res(
         span: Span,
         ident: Ident,
         res: LifetimeRes,
+        captures: bool,
     ) -> hir::Lifetime {
         debug!(?self.captured_lifetimes);
+
         let name = match res {
             LifetimeRes::Param { mut param, binder } => {
                 let p_name = ParamName::Plain(ident);
                 if let Some(mut captured_lifetimes) = self.captured_lifetimes.take() {
-                    if !captured_lifetimes.binders_to_ignore.contains(&binder) {
-                        match captured_lifetimes.captures.entry(param) {
-                            Entry::Occupied(o) => param = self.local_def_id(o.get().1),
-                            Entry::Vacant(v) => {
-                                let p_id = self.next_node_id();
-                                let p_def_id = self.create_def(
-                                    captured_lifetimes.parent_def_id,
-                                    p_id,
-                                    DefPathData::LifetimeNs(p_name.ident().name),
-                                );
-
-                                v.insert((span, p_id, p_name, res));
-                                param = p_def_id;
+                    if captures {
+                        if !captured_lifetimes.binders_to_ignore.contains(&binder) {
+                            match captured_lifetimes.captures.entry(param) {
+                                Entry::Occupied(o) => param = self.local_def_id(o.get().1),
+                                Entry::Vacant(v) => {
+                                    let p_id = self.next_node_id();
+
+                                    let p_def_id = self.create_def(
+                                        captured_lifetimes.parent_def_id,
+                                        p_id,
+                                        DefPathData::LifetimeNs(p_name.ident().name),
+                                    );
+
+                                    v.insert((span, p_id, p_name, res));
+                                    param = p_def_id;
+                                }
                             }
                         }
+                    } else {
+                        if let Entry::Occupied(o) = captured_lifetimes.captures.entry(param) {
+                            param = self.local_def_id(o.get().1);
+                        }
                     }
-
                     self.captured_lifetimes = Some(captured_lifetimes);
                 }
+
                 hir::LifetimeName::Param(param, p_name)
             }
             LifetimeRes::Fresh { param, binder } => {
                 debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
+
                 let mut param = self.local_def_id(param);
                 if let Some(mut captured_lifetimes) = self.captured_lifetimes.take() {
                     if !captured_lifetimes.binders_to_ignore.contains(&binder) {
@@ -1867,6 +1988,7 @@ fn new_named_lifetime_with_res(
                             Entry::Occupied(o) => param = self.local_def_id(o.get().1),
                             Entry::Vacant(v) => {
                                 let p_id = self.next_node_id();
+
                                 let p_def_id = self.create_def(
                                     captured_lifetimes.parent_def_id,
                                     p_id,
@@ -1883,29 +2005,7 @@ fn new_named_lifetime_with_res(
                 }
                 hir::LifetimeName::Param(param, ParamName::Fresh)
             }
-            LifetimeRes::Anonymous { binder, elided } => {
-                let mut l_name = None;
-                if let Some(mut captured_lifetimes) = self.captured_lifetimes.take() {
-                    if !captured_lifetimes.binders_to_ignore.contains(&binder) {
-                        let p_id = self.next_node_id();
-                        let p_def_id = self.create_def(
-                            captured_lifetimes.parent_def_id,
-                            p_id,
-                            DefPathData::LifetimeNs(kw::UnderscoreLifetime),
-                        );
-                        captured_lifetimes
-                            .captures
-                            .insert(p_def_id, (span, p_id, ParamName::Fresh, res));
-                        l_name = Some(hir::LifetimeName::Param(p_def_id, ParamName::Fresh));
-                    }
-                    self.captured_lifetimes = Some(captured_lifetimes);
-                };
-                l_name.unwrap_or(if elided {
-                    hir::LifetimeName::Implicit
-                } else {
-                    hir::LifetimeName::Underscore
-                })
-            }
+            LifetimeRes::Infer => hir::LifetimeName::Infer,
             LifetimeRes::Static => hir::LifetimeName::Static,
             LifetimeRes::Error => hir::LifetimeName::Error,
             res => panic!("Unexpected lifetime resolution {:?} for {:?} at {:?}", res, ident, span),
@@ -1965,7 +2065,11 @@ fn lower_generic_param_kind(
             GenericParamKind::Type { ref default, .. } => {
                 let kind = hir::GenericParamKind::Type {
                     default: default.as_ref().map(|x| {
-                        self.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Type))
+                        self.lower_ty(
+                            x,
+                            ImplTraitContext::Disallowed(ImplTraitPosition::Type),
+                            true,
+                        )
                     }),
                     synthetic: false,
                 };
@@ -1973,7 +2077,8 @@ fn lower_generic_param_kind(
                 (hir::ParamName::Plain(self.lower_ident(param.ident)), kind)
             }
             GenericParamKind::Const { ref ty, kw_span: _, ref default } => {
-                let ty = self.lower_ty(&ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
+                let ty =
+                    self.lower_ty(&ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type), true);
                 let default = default.as_ref().map(|def| self.lower_anon_const(def));
                 (
                     hir::ParamName::Plain(self.lower_ident(param.ident)),
@@ -1983,8 +2088,20 @@ fn lower_generic_param_kind(
         }
     }
 
-    fn lower_trait_ref(&mut self, p: &TraitRef, itctx: ImplTraitContext) -> hir::TraitRef<'hir> {
-        let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx) {
+    fn lower_trait_ref(
+        &mut self,
+        p: &TraitRef,
+        itctx: ImplTraitContext,
+        captures: bool,
+    ) -> hir::TraitRef<'hir> {
+        let path = match self.lower_qpath(
+            p.ref_id,
+            &None,
+            &p.path,
+            ParamMode::Explicit,
+            itctx,
+            captures,
+        ) {
             hir::QPath::Resolved(None, path) => path,
             qpath => panic!("lower_trait_ref: unexpected QPath `{:?}`", qpath),
         };
@@ -1996,35 +2113,38 @@ fn lower_poly_trait_ref(
         &mut self,
         p: &PolyTraitRef,
         itctx: ImplTraitContext,
+        captures: bool,
     ) -> hir::PolyTraitRef<'hir> {
         self.with_lifetime_binder(
             p.trait_ref.ref_id,
             &p.bound_generic_params,
             |this, bound_generic_params| {
-                let trait_ref = this.lower_trait_ref(&p.trait_ref, itctx);
+                let trait_ref = this.lower_trait_ref(&p.trait_ref, itctx, captures);
                 hir::PolyTraitRef { bound_generic_params, trait_ref, span: this.lower_span(p.span) }
             },
         )
     }
 
     fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> {
-        hir::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl }
+        hir::MutTy { ty: self.lower_ty(&mt.ty, itctx, true), mutbl: mt.mutbl }
     }
 
     fn lower_param_bounds(
         &mut self,
         bounds: &[GenericBound],
         itctx: ImplTraitContext,
+        captures: bool,
     ) -> hir::GenericBounds<'hir> {
-        self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, itctx))
+        self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, itctx, captures))
     }
 
     fn lower_param_bounds_mut<'s>(
         &'s mut self,
         bounds: &'s [GenericBound],
         itctx: ImplTraitContext,
+        captures: bool,
     ) -> impl Iterator<Item = hir::GenericBound<'hir>> + Captures<'s> + Captures<'a> {
-        bounds.iter().map(move |bound| self.lower_param_bound(bound, itctx))
+        bounds.iter().map(move |bound| self.lower_param_bound(bound, itctx, captures))
     }
 
     fn lower_generic_and_bounds(
@@ -2037,7 +2157,6 @@ fn lower_generic_and_bounds(
         // Add a definition for the in-band `Param`.
         let def_id = self.local_def_id(node_id);
 
-        let hir_bounds = self.lower_param_bounds(bounds, ImplTraitContext::Universal);
         // Set the name to `impl Bound1 + Bound2`.
         let param = hir::GenericParam {
             hir_id: self.lower_node_id(node_id),
@@ -2052,7 +2171,8 @@ fn lower_generic_and_bounds(
             ident,
             node_id,
             &GenericParamKind::Type { default: None },
-            hir_bounds,
+            bounds,
+            ImplTraitContext::Universal,
             hir::PredicateOrigin::ImplTrait,
         );