]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_ast_lowering/src/item.rs
Rollup merge of #93827 - eholk:stabilize-const_fn-features, r=wesleywiser
[rust.git] / compiler / rustc_ast_lowering / src / item.rs
1 use super::{AnonymousLifetimeMode, LoweringContext, ParamMode};
2 use super::{ImplTraitContext, ImplTraitPosition};
3 use crate::{Arena, FnDeclKind};
4
5 use rustc_ast::ptr::P;
6 use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
7 use rustc_ast::*;
8 use rustc_data_structures::fx::FxHashSet;
9 use rustc_errors::struct_span_err;
10 use rustc_hir as hir;
11 use rustc_hir::def::{DefKind, Res};
12 use rustc_hir::def_id::LocalDefId;
13 use rustc_index::vec::Idx;
14 use rustc_span::source_map::{respan, DesugaringKind};
15 use rustc_span::symbol::{kw, sym, Ident};
16 use rustc_span::Span;
17 use rustc_target::spec::abi;
18 use smallvec::{smallvec, SmallVec};
19 use tracing::debug;
20
21 use std::iter;
22 use std::mem;
23
24 pub(super) struct ItemLowerer<'a, 'lowering, 'hir> {
25     pub(super) lctx: &'a mut LoweringContext<'lowering, 'hir>,
26 }
27
28 /// When we have a ty alias we *may* have two where clauses. To give the best diagnostics, we set the span
29 /// to the where clause that is prefered, if it exists. Otherwise, it sets the span to the other where
30 /// clause if it exists.
31 fn add_ty_alias_where_clause(
32     generics: &mut ast::Generics,
33     mut where_clauses: (TyAliasWhereClause, TyAliasWhereClause),
34     prefer_first: bool,
35 ) {
36     if !prefer_first {
37         where_clauses = (where_clauses.1, where_clauses.0);
38     }
39     if where_clauses.0.0 || !where_clauses.1.0 {
40         generics.where_clause.has_where_token = where_clauses.0.0;
41         generics.where_clause.span = where_clauses.0.1;
42     } else {
43         generics.where_clause.has_where_token = where_clauses.1.0;
44         generics.where_clause.span = where_clauses.1.1;
45     }
46 }
47
48 impl ItemLowerer<'_, '_, '_> {
49     fn with_trait_impl_ref<T>(
50         &mut self,
51         impl_ref: &Option<TraitRef>,
52         f: impl FnOnce(&mut Self) -> T,
53     ) -> T {
54         let old = self.lctx.is_in_trait_impl;
55         self.lctx.is_in_trait_impl = impl_ref.is_some();
56         let ret = f(self);
57         self.lctx.is_in_trait_impl = old;
58         ret
59     }
60 }
61
62 impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> {
63     fn visit_attribute(&mut self, _: &'a Attribute) {
64         // We do not want to lower expressions that appear in attributes,
65         // as they are not accessible to the rest of the HIR.
66     }
67
68     fn visit_item(&mut self, item: &'a Item) {
69         let hir_id = self.lctx.with_hir_id_owner(item.id, |lctx| {
70             let node = lctx.without_in_scope_lifetime_defs(|lctx| lctx.lower_item(item));
71             hir::OwnerNode::Item(node)
72         });
73
74         self.lctx.with_parent_item_lifetime_defs(hir_id, |this| {
75             let this = &mut ItemLowerer { lctx: this };
76             match item.kind {
77                 ItemKind::Impl(box Impl { ref of_trait, .. }) => {
78                     this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item));
79                 }
80                 _ => visit::walk_item(this, item),
81             }
82         });
83     }
84
85     fn visit_fn(&mut self, fk: FnKind<'a>, sp: Span, _: NodeId) {
86         match fk {
87             FnKind::Fn(FnCtxt::Foreign, _, sig, _, _) => {
88                 self.visit_fn_header(&sig.header);
89                 visit::walk_fn_decl(self, &sig.decl);
90                 // Don't visit the foreign function body even if it has one, since lowering the
91                 // body would have no meaning and will have already been caught as a parse error.
92             }
93             _ => visit::walk_fn(self, fk, sp),
94         }
95     }
96
97     fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
98         self.lctx.with_hir_id_owner(item.id, |lctx| match ctxt {
99             AssocCtxt::Trait => hir::OwnerNode::TraitItem(lctx.lower_trait_item(item)),
100             AssocCtxt::Impl => hir::OwnerNode::ImplItem(lctx.lower_impl_item(item)),
101         });
102
103         visit::walk_assoc_item(self, item, ctxt);
104     }
105
106     fn visit_foreign_item(&mut self, item: &'a ForeignItem) {
107         self.lctx.with_hir_id_owner(item.id, |lctx| {
108             hir::OwnerNode::ForeignItem(lctx.lower_foreign_item(item))
109         });
110
111         visit::walk_foreign_item(self, item);
112     }
113 }
114
115 impl<'hir> LoweringContext<'_, 'hir> {
116     // Same as the method above, but accepts `hir::GenericParam`s
117     // instead of `ast::GenericParam`s.
118     // This should only be used with generics that have already had their
119     // in-band lifetimes added. In practice, this means that this function is
120     // only used when lowering a child item of a trait or impl.
121     fn with_parent_item_lifetime_defs<T>(
122         &mut self,
123         parent_hir_id: LocalDefId,
124         f: impl FnOnce(&mut Self) -> T,
125     ) -> T {
126         let old_len = self.in_scope_lifetimes.len();
127
128         let parent_generics = match self.owners[parent_hir_id].unwrap().node().expect_item().kind {
129             hir::ItemKind::Impl(hir::Impl { ref generics, .. })
130             | hir::ItemKind::Trait(_, _, ref generics, ..) => generics.params,
131             _ => &[],
132         };
133         let lt_def_names = parent_generics.iter().filter_map(|param| match param.kind {
134             hir::GenericParamKind::Lifetime { .. } => Some(param.name.normalize_to_macros_2_0()),
135             _ => None,
136         });
137         self.in_scope_lifetimes.extend(lt_def_names);
138
139         let res = f(self);
140
141         self.in_scope_lifetimes.truncate(old_len);
142         res
143     }
144
145     // Clears (and restores) the `in_scope_lifetimes` field. Used when
146     // visiting nested items, which never inherit in-scope lifetimes
147     // from their surrounding environment.
148     fn without_in_scope_lifetime_defs<T>(&mut self, f: impl FnOnce(&mut Self) -> T) -> T {
149         let old_in_scope_lifetimes = mem::replace(&mut self.in_scope_lifetimes, vec![]);
150
151         // this vector is only used when walking over impl headers,
152         // input types, and the like, and should not be non-empty in
153         // between items
154         assert!(self.lifetimes_to_define.is_empty());
155
156         let res = f(self);
157
158         assert!(self.in_scope_lifetimes.is_empty());
159         self.in_scope_lifetimes = old_in_scope_lifetimes;
160
161         res
162     }
163
164     pub(super) fn lower_mod(&mut self, items: &[P<Item>], inner: Span) -> hir::Mod<'hir> {
165         hir::Mod {
166             inner: self.lower_span(inner),
167             item_ids: self.arena.alloc_from_iter(items.iter().flat_map(|x| self.lower_item_ref(x))),
168         }
169     }
170
171     pub(super) fn lower_item_ref(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> {
172         let mut node_ids = smallvec![hir::ItemId { def_id: self.resolver.local_def_id(i.id) }];
173         if let ItemKind::Use(ref use_tree) = &i.kind {
174             self.lower_item_id_use_tree(use_tree, i.id, &mut node_ids);
175         }
176         node_ids
177     }
178
179     fn lower_item_id_use_tree(
180         &mut self,
181         tree: &UseTree,
182         base_id: NodeId,
183         vec: &mut SmallVec<[hir::ItemId; 1]>,
184     ) {
185         match tree.kind {
186             UseTreeKind::Nested(ref nested_vec) => {
187                 for &(ref nested, id) in nested_vec {
188                     vec.push(hir::ItemId { def_id: self.resolver.local_def_id(id) });
189                     self.lower_item_id_use_tree(nested, id, vec);
190                 }
191             }
192             UseTreeKind::Glob => {}
193             UseTreeKind::Simple(_, id1, id2) => {
194                 for (_, &id) in
195                     iter::zip(self.expect_full_res_from_use(base_id).skip(1), &[id1, id2])
196                 {
197                     vec.push(hir::ItemId { def_id: self.resolver.local_def_id(id) });
198                 }
199             }
200         }
201     }
202
203     fn lower_item(&mut self, i: &Item) -> &'hir hir::Item<'hir> {
204         let mut ident = i.ident;
205         let mut vis = self.lower_visibility(&i.vis);
206         let hir_id = self.lower_node_id(i.id);
207         let attrs = self.lower_attrs(hir_id, &i.attrs);
208         let kind = self.lower_item_kind(i.span, i.id, hir_id, &mut ident, attrs, &mut vis, &i.kind);
209         let item = hir::Item {
210             def_id: hir_id.expect_owner(),
211             ident: self.lower_ident(ident),
212             kind,
213             vis,
214             span: self.lower_span(i.span),
215         };
216         self.arena.alloc(item)
217     }
218
219     fn lower_item_kind(
220         &mut self,
221         span: Span,
222         id: NodeId,
223         hir_id: hir::HirId,
224         ident: &mut Ident,
225         attrs: Option<&'hir [Attribute]>,
226         vis: &mut hir::Visibility<'hir>,
227         i: &ItemKind,
228     ) -> hir::ItemKind<'hir> {
229         match *i {
230             ItemKind::ExternCrate(orig_name) => hir::ItemKind::ExternCrate(orig_name),
231             ItemKind::Use(ref use_tree) => {
232                 // Start with an empty prefix.
233                 let prefix = Path { segments: vec![], span: use_tree.span, tokens: None };
234
235                 self.lower_use_tree(use_tree, &prefix, id, vis, ident, attrs)
236             }
237             ItemKind::Static(ref t, m, ref e) => {
238                 let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
239                 hir::ItemKind::Static(ty, m, body_id)
240             }
241             ItemKind::Const(_, ref t, ref e) => {
242                 let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
243                 hir::ItemKind::Const(ty, body_id)
244             }
245             ItemKind::Fn(box Fn {
246                 sig: FnSig { ref decl, header, span: fn_sig_span },
247                 ref generics,
248                 ref body,
249                 ..
250             }) => {
251                 let fn_def_id = self.resolver.local_def_id(id);
252                 self.with_new_scopes(|this| {
253                     this.current_item = Some(ident.span);
254
255                     // Note: we don't need to change the return type from `T` to
256                     // `impl Future<Output = T>` here because lower_body
257                     // only cares about the input argument patterns in the function
258                     // declaration (decl), not the return types.
259                     let asyncness = header.asyncness;
260                     let body_id =
261                         this.lower_maybe_async_body(span, &decl, asyncness, body.as_deref());
262
263                     let (generics, decl) = this.add_in_band_defs(
264                         generics,
265                         fn_def_id,
266                         AnonymousLifetimeMode::PassThrough,
267                         |this, idty| {
268                             let ret_id = asyncness.opt_return_id();
269                             this.lower_fn_decl(
270                                 &decl,
271                                 Some((fn_def_id, idty)),
272                                 FnDeclKind::Fn,
273                                 ret_id,
274                             )
275                         },
276                     );
277                     let sig = hir::FnSig {
278                         decl,
279                         header: this.lower_fn_header(header),
280                         span: this.lower_span(fn_sig_span),
281                     };
282                     hir::ItemKind::Fn(sig, generics, body_id)
283                 })
284             }
285             ItemKind::Mod(_, ref mod_kind) => match mod_kind {
286                 ModKind::Loaded(items, _, inner_span) => {
287                     hir::ItemKind::Mod(self.lower_mod(items, *inner_span))
288                 }
289                 ModKind::Unloaded => panic!("`mod` items should have been loaded by now"),
290             },
291             ItemKind::ForeignMod(ref fm) => hir::ItemKind::ForeignMod {
292                 abi: fm.abi.map_or(abi::Abi::FALLBACK, |abi| self.lower_abi(abi)),
293                 items: self
294                     .arena
295                     .alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
296             },
297             ItemKind::GlobalAsm(ref asm) => {
298                 hir::ItemKind::GlobalAsm(self.lower_inline_asm(span, asm))
299             }
300             ItemKind::TyAlias(box TyAlias {
301                 ref generics,
302                 where_clauses,
303                 ty: Some(ref ty),
304                 ..
305             }) => {
306                 // We lower
307                 //
308                 // type Foo = impl Trait
309                 //
310                 // to
311                 //
312                 // type Foo = Foo1
313                 // opaque type Foo1: Trait
314                 let ty = self.lower_ty(
315                     ty,
316                     ImplTraitContext::TypeAliasesOpaqueTy {
317                         capturable_lifetimes: &mut FxHashSet::default(),
318                     },
319                 );
320                 let mut generics = generics.clone();
321                 add_ty_alias_where_clause(&mut generics, where_clauses, true);
322                 let generics = self.lower_generics(
323                     &generics,
324                     ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
325                 );
326                 hir::ItemKind::TyAlias(ty, generics)
327             }
328             ItemKind::TyAlias(box TyAlias {
329                 ref generics, ref where_clauses, ty: None, ..
330             }) => {
331                 let ty = self.arena.alloc(self.ty(span, hir::TyKind::Err));
332                 let mut generics = generics.clone();
333                 add_ty_alias_where_clause(&mut generics, *where_clauses, true);
334                 let generics = self.lower_generics(
335                     &generics,
336                     ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
337                 );
338                 hir::ItemKind::TyAlias(ty, generics)
339             }
340             ItemKind::Enum(ref enum_definition, ref generics) => hir::ItemKind::Enum(
341                 hir::EnumDef {
342                     variants: self.arena.alloc_from_iter(
343                         enum_definition.variants.iter().map(|x| self.lower_variant(x)),
344                     ),
345                 },
346                 self.lower_generics(
347                     generics,
348                     ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
349                 ),
350             ),
351             ItemKind::Struct(ref struct_def, ref generics) => {
352                 let struct_def = self.lower_variant_data(hir_id, struct_def);
353                 hir::ItemKind::Struct(
354                     struct_def,
355                     self.lower_generics(
356                         generics,
357                         ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
358                     ),
359                 )
360             }
361             ItemKind::Union(ref vdata, ref generics) => {
362                 let vdata = self.lower_variant_data(hir_id, vdata);
363                 hir::ItemKind::Union(
364                     vdata,
365                     self.lower_generics(
366                         generics,
367                         ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
368                     ),
369                 )
370             }
371             ItemKind::Impl(box Impl {
372                 unsafety,
373                 polarity,
374                 defaultness,
375                 constness,
376                 generics: ref ast_generics,
377                 of_trait: ref trait_ref,
378                 self_ty: ref ty,
379                 items: ref impl_items,
380             }) => {
381                 // Lower the "impl header" first. This ordering is important
382                 // for in-band lifetimes! Consider `'a` here:
383                 //
384                 //     impl Foo<'a> for u32 {
385                 //         fn method(&'a self) { .. }
386                 //     }
387                 //
388                 // Because we start by lowering the `Foo<'a> for u32`
389                 // part, we will add `'a` to the list of generics on
390                 // the impl. When we then encounter it later in the
391                 // method, it will not be considered an in-band
392                 // lifetime to be added, but rather a reference to a
393                 // parent lifetime.
394                 let lowered_trait_def_id = hir_id.expect_owner();
395                 let (generics, (trait_ref, lowered_ty)) = self.add_in_band_defs(
396                     ast_generics,
397                     lowered_trait_def_id,
398                     AnonymousLifetimeMode::CreateParameter,
399                     |this, _| {
400                         let trait_ref = trait_ref.as_ref().map(|trait_ref| {
401                             this.lower_trait_ref(
402                                 trait_ref,
403                                 ImplTraitContext::Disallowed(ImplTraitPosition::Trait),
404                             )
405                         });
406
407                         let lowered_ty = this
408                             .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
409
410                         (trait_ref, lowered_ty)
411                     },
412                 );
413
414                 let new_impl_items =
415                     self.with_in_scope_lifetime_defs(&ast_generics.params, |this| {
416                         this.arena.alloc_from_iter(
417                             impl_items.iter().map(|item| this.lower_impl_item_ref(item)),
418                         )
419                     });
420
421                 // `defaultness.has_value()` is never called for an `impl`, always `true` in order
422                 // to not cause an assertion failure inside the `lower_defaultness` function.
423                 let has_val = true;
424                 let (defaultness, defaultness_span) = self.lower_defaultness(defaultness, has_val);
425                 let polarity = match polarity {
426                     ImplPolarity::Positive => ImplPolarity::Positive,
427                     ImplPolarity::Negative(s) => ImplPolarity::Negative(self.lower_span(s)),
428                 };
429                 hir::ItemKind::Impl(hir::Impl {
430                     unsafety: self.lower_unsafety(unsafety),
431                     polarity,
432                     defaultness,
433                     defaultness_span,
434                     constness: self.lower_constness(constness),
435                     generics,
436                     of_trait: trait_ref,
437                     self_ty: lowered_ty,
438                     items: new_impl_items,
439                 })
440             }
441             ItemKind::Trait(box Trait {
442                 is_auto,
443                 unsafety,
444                 ref generics,
445                 ref bounds,
446                 ref items,
447             }) => {
448                 let bounds = self.lower_param_bounds(
449                     bounds,
450                     ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
451                 );
452                 let items = self
453                     .arena
454                     .alloc_from_iter(items.iter().map(|item| self.lower_trait_item_ref(item)));
455                 hir::ItemKind::Trait(
456                     is_auto,
457                     self.lower_unsafety(unsafety),
458                     self.lower_generics(
459                         generics,
460                         ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
461                     ),
462                     bounds,
463                     items,
464                 )
465             }
466             ItemKind::TraitAlias(ref generics, ref bounds) => hir::ItemKind::TraitAlias(
467                 self.lower_generics(
468                     generics,
469                     ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
470                 ),
471                 self.lower_param_bounds(
472                     bounds,
473                     ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
474                 ),
475             ),
476             ItemKind::MacroDef(MacroDef { ref body, macro_rules }) => {
477                 let body = P(self.lower_mac_args(body));
478                 let macro_kind = self.resolver.decl_macro_kind(self.resolver.local_def_id(id));
479                 hir::ItemKind::Macro(ast::MacroDef { body, macro_rules }, macro_kind)
480             }
481             ItemKind::MacCall(..) => {
482                 panic!("`TyMac` should have been expanded by now")
483             }
484         }
485     }
486
487     fn lower_const_item(
488         &mut self,
489         ty: &Ty,
490         span: Span,
491         body: Option<&Expr>,
492     ) -> (&'hir hir::Ty<'hir>, hir::BodyId) {
493         let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
494         (ty, self.lower_const_body(span, body))
495     }
496
497     fn lower_use_tree(
498         &mut self,
499         tree: &UseTree,
500         prefix: &Path,
501         id: NodeId,
502         vis: &mut hir::Visibility<'hir>,
503         ident: &mut Ident,
504         attrs: Option<&'hir [Attribute]>,
505     ) -> hir::ItemKind<'hir> {
506         debug!("lower_use_tree(tree={:?})", tree);
507         debug!("lower_use_tree: vis = {:?}", vis);
508
509         let path = &tree.prefix;
510         let segments = prefix.segments.iter().chain(path.segments.iter()).cloned().collect();
511
512         match tree.kind {
513             UseTreeKind::Simple(rename, id1, id2) => {
514                 *ident = tree.ident();
515
516                 // First, apply the prefix to the path.
517                 let mut path = Path { segments, span: path.span, tokens: None };
518
519                 // Correctly resolve `self` imports.
520                 if path.segments.len() > 1
521                     && path.segments.last().unwrap().ident.name == kw::SelfLower
522                 {
523                     let _ = path.segments.pop();
524                     if rename.is_none() {
525                         *ident = path.segments.last().unwrap().ident;
526                     }
527                 }
528
529                 let mut resolutions = self.expect_full_res_from_use(id).fuse();
530                 // We want to return *something* from this function, so hold onto the first item
531                 // for later.
532                 let ret_res = self.lower_res(resolutions.next().unwrap_or(Res::Err));
533
534                 // Here, we are looping over namespaces, if they exist for the definition
535                 // being imported. We only handle type and value namespaces because we
536                 // won't be dealing with macros in the rest of the compiler.
537                 // Essentially a single `use` which imports two names is desugared into
538                 // two imports.
539                 for new_node_id in [id1, id2] {
540                     let new_id = self.resolver.local_def_id(new_node_id);
541                     let Some(res) = resolutions.next() else {
542                         // Associate an HirId to both ids even if there is no resolution.
543                         self.owners.ensure_contains_elem(new_id, || hir::MaybeOwner::Phantom);
544                         let _old = std::mem::replace(
545                             &mut self.owners[new_id],
546                             hir::MaybeOwner::NonOwner(hir::HirId::make_owner(new_id)),
547                         );
548                         debug_assert!(matches!(_old, hir::MaybeOwner::Phantom));
549                         continue;
550                     };
551                     let ident = *ident;
552                     let mut path = path.clone();
553                     for seg in &mut path.segments {
554                         seg.id = self.resolver.next_node_id();
555                     }
556                     let span = path.span;
557
558                     self.with_hir_id_owner(new_node_id, |this| {
559                         let res = this.lower_res(res);
560                         let path = this.lower_path_extra(res, &path, ParamMode::Explicit);
561                         let kind = hir::ItemKind::Use(path, hir::UseKind::Single);
562                         let vis = this.rebuild_vis(&vis);
563                         if let Some(attrs) = attrs {
564                             this.attrs.insert(hir::ItemLocalId::new(0), attrs);
565                         }
566
567                         let item = hir::Item {
568                             def_id: new_id,
569                             ident: this.lower_ident(ident),
570                             kind,
571                             vis,
572                             span: this.lower_span(span),
573                         };
574                         hir::OwnerNode::Item(this.arena.alloc(item))
575                     });
576                 }
577
578                 let path = self.lower_path_extra(ret_res, &path, ParamMode::Explicit);
579                 hir::ItemKind::Use(path, hir::UseKind::Single)
580             }
581             UseTreeKind::Glob => {
582                 let path = self.lower_path(
583                     id,
584                     &Path { segments, span: path.span, tokens: None },
585                     ParamMode::Explicit,
586                 );
587                 hir::ItemKind::Use(path, hir::UseKind::Glob)
588             }
589             UseTreeKind::Nested(ref trees) => {
590                 // Nested imports are desugared into simple imports.
591                 // So, if we start with
592                 //
593                 // ```
594                 // pub(x) use foo::{a, b};
595                 // ```
596                 //
597                 // we will create three items:
598                 //
599                 // ```
600                 // pub(x) use foo::a;
601                 // pub(x) use foo::b;
602                 // pub(x) use foo::{}; // <-- this is called the `ListStem`
603                 // ```
604                 //
605                 // The first two are produced by recursively invoking
606                 // `lower_use_tree` (and indeed there may be things
607                 // like `use foo::{a::{b, c}}` and so forth).  They
608                 // wind up being directly added to
609                 // `self.items`. However, the structure of this
610                 // function also requires us to return one item, and
611                 // for that we return the `{}` import (called the
612                 // `ListStem`).
613
614                 let prefix = Path { segments, span: prefix.span.to(path.span), tokens: None };
615
616                 // Add all the nested `PathListItem`s to the HIR.
617                 for &(ref use_tree, id) in trees {
618                     let new_hir_id = self.resolver.local_def_id(id);
619
620                     let mut prefix = prefix.clone();
621
622                     // Give the segments new node-ids since they are being cloned.
623                     for seg in &mut prefix.segments {
624                         seg.id = self.resolver.next_node_id();
625                     }
626
627                     // Each `use` import is an item and thus are owners of the
628                     // names in the path. Up to this point the nested import is
629                     // the current owner, since we want each desugared import to
630                     // own its own names, we have to adjust the owner before
631                     // lowering the rest of the import.
632                     self.with_hir_id_owner(id, |this| {
633                         let mut vis = this.rebuild_vis(&vis);
634                         let mut ident = *ident;
635
636                         let kind =
637                             this.lower_use_tree(use_tree, &prefix, id, &mut vis, &mut ident, attrs);
638                         if let Some(attrs) = attrs {
639                             this.attrs.insert(hir::ItemLocalId::new(0), attrs);
640                         }
641
642                         let item = hir::Item {
643                             def_id: new_hir_id,
644                             ident: this.lower_ident(ident),
645                             kind,
646                             vis,
647                             span: this.lower_span(use_tree.span),
648                         };
649                         hir::OwnerNode::Item(this.arena.alloc(item))
650                     });
651                 }
652
653                 // Subtle and a bit hacky: we lower the privacy level
654                 // of the list stem to "private" most of the time, but
655                 // not for "restricted" paths. The key thing is that
656                 // we don't want it to stay as `pub` (with no caveats)
657                 // because that affects rustdoc and also the lints
658                 // about `pub` items. But we can't *always* make it
659                 // private -- particularly not for restricted paths --
660                 // because it contains node-ids that would then be
661                 // unused, failing the check that HirIds are "densely
662                 // assigned".
663                 match vis.node {
664                     hir::VisibilityKind::Public
665                     | hir::VisibilityKind::Crate(_)
666                     | hir::VisibilityKind::Inherited => {
667                         *vis = respan(
668                             self.lower_span(prefix.span.shrink_to_lo()),
669                             hir::VisibilityKind::Inherited,
670                         );
671                     }
672                     hir::VisibilityKind::Restricted { .. } => {
673                         // Do nothing here, as described in the comment on the match.
674                     }
675                 }
676
677                 let res = self.expect_full_res_from_use(id).next().unwrap_or(Res::Err);
678                 let res = self.lower_res(res);
679                 let path = self.lower_path_extra(res, &prefix, ParamMode::Explicit);
680                 hir::ItemKind::Use(path, hir::UseKind::ListStem)
681             }
682         }
683     }
684
685     /// Paths like the visibility path in `pub(super) use foo::{bar, baz}` are repeated
686     /// many times in the HIR tree; for each occurrence, we need to assign distinct
687     /// `NodeId`s. (See, e.g., #56128.)
688     fn rebuild_use_path(&mut self, path: &hir::Path<'hir>) -> &'hir hir::Path<'hir> {
689         debug!("rebuild_use_path(path = {:?})", path);
690         let segments =
691             self.arena.alloc_from_iter(path.segments.iter().map(|seg| hir::PathSegment {
692                 ident: seg.ident,
693                 hir_id: seg.hir_id.map(|_| self.next_id()),
694                 res: seg.res,
695                 args: None,
696                 infer_args: seg.infer_args,
697             }));
698         self.arena.alloc(hir::Path { span: path.span, res: path.res, segments })
699     }
700
701     fn rebuild_vis(&mut self, vis: &hir::Visibility<'hir>) -> hir::Visibility<'hir> {
702         let vis_kind = match vis.node {
703             hir::VisibilityKind::Public => hir::VisibilityKind::Public,
704             hir::VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar),
705             hir::VisibilityKind::Inherited => hir::VisibilityKind::Inherited,
706             hir::VisibilityKind::Restricted { ref path, hir_id: _ } => {
707                 hir::VisibilityKind::Restricted {
708                     path: self.rebuild_use_path(path),
709                     hir_id: self.next_id(),
710                 }
711             }
712         };
713         respan(self.lower_span(vis.span), vis_kind)
714     }
715
716     fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> {
717         let hir_id = self.lower_node_id(i.id);
718         let def_id = hir_id.expect_owner();
719         self.lower_attrs(hir_id, &i.attrs);
720         let item = hir::ForeignItem {
721             def_id,
722             ident: self.lower_ident(i.ident),
723             kind: match i.kind {
724                 ForeignItemKind::Fn(box Fn { ref sig, ref generics, .. }) => {
725                     let fdec = &sig.decl;
726                     let (generics, (fn_dec, fn_args)) = self.add_in_band_defs(
727                         generics,
728                         def_id,
729                         AnonymousLifetimeMode::PassThrough,
730                         |this, _| {
731                             (
732                                 // Disallow `impl Trait` in foreign items.
733                                 this.lower_fn_decl(fdec, None, FnDeclKind::ExternFn, None),
734                                 this.lower_fn_params_to_names(fdec),
735                             )
736                         },
737                     );
738
739                     hir::ForeignItemKind::Fn(fn_dec, fn_args, generics)
740                 }
741                 ForeignItemKind::Static(ref t, m, _) => {
742                     let ty =
743                         self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
744                     hir::ForeignItemKind::Static(ty, m)
745                 }
746                 ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type,
747                 ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"),
748             },
749             vis: self.lower_visibility(&i.vis),
750             span: self.lower_span(i.span),
751         };
752         self.arena.alloc(item)
753     }
754
755     fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemRef {
756         hir::ForeignItemRef {
757             id: hir::ForeignItemId { def_id: self.resolver.local_def_id(i.id) },
758             ident: self.lower_ident(i.ident),
759             span: self.lower_span(i.span),
760         }
761     }
762
763     fn lower_variant(&mut self, v: &Variant) -> hir::Variant<'hir> {
764         let id = self.lower_node_id(v.id);
765         self.lower_attrs(id, &v.attrs);
766         hir::Variant {
767             id,
768             data: self.lower_variant_data(id, &v.data),
769             disr_expr: v.disr_expr.as_ref().map(|e| self.lower_anon_const(e)),
770             ident: self.lower_ident(v.ident),
771             span: self.lower_span(v.span),
772         }
773     }
774
775     fn lower_variant_data(
776         &mut self,
777         parent_id: hir::HirId,
778         vdata: &VariantData,
779     ) -> hir::VariantData<'hir> {
780         match *vdata {
781             VariantData::Struct(ref fields, recovered) => hir::VariantData::Struct(
782                 self.arena
783                     .alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_field_def(f))),
784                 recovered,
785             ),
786             VariantData::Tuple(ref fields, id) => {
787                 let ctor_id = self.lower_node_id(id);
788                 self.alias_attrs(ctor_id, parent_id);
789                 hir::VariantData::Tuple(
790                     self.arena.alloc_from_iter(
791                         fields.iter().enumerate().map(|f| self.lower_field_def(f)),
792                     ),
793                     ctor_id,
794                 )
795             }
796             VariantData::Unit(id) => {
797                 let ctor_id = self.lower_node_id(id);
798                 self.alias_attrs(ctor_id, parent_id);
799                 hir::VariantData::Unit(ctor_id)
800             }
801         }
802     }
803
804     fn lower_field_def(&mut self, (index, f): (usize, &FieldDef)) -> hir::FieldDef<'hir> {
805         let ty = if let TyKind::Path(ref qself, ref path) = f.ty.kind {
806             let t = self.lower_path_ty(
807                 &f.ty,
808                 qself,
809                 path,
810                 ParamMode::ExplicitNamed, // no `'_` in declarations (Issue #61124)
811                 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
812             );
813             self.arena.alloc(t)
814         } else {
815             self.lower_ty(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type))
816         };
817         let hir_id = self.lower_node_id(f.id);
818         self.lower_attrs(hir_id, &f.attrs);
819         hir::FieldDef {
820             span: self.lower_span(f.span),
821             hir_id,
822             ident: match f.ident {
823                 Some(ident) => self.lower_ident(ident),
824                 // FIXME(jseyfried): positional field hygiene.
825                 None => Ident::new(sym::integer(index), self.lower_span(f.span)),
826             },
827             vis: self.lower_visibility(&f.vis),
828             ty,
829         }
830     }
831
832     fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
833         let hir_id = self.lower_node_id(i.id);
834         let trait_item_def_id = hir_id.expect_owner();
835
836         let (generics, kind) = match i.kind {
837             AssocItemKind::Const(_, ref ty, ref default) => {
838                 let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
839                 let body = default.as_ref().map(|x| self.lower_const_body(i.span, Some(x)));
840                 (hir::Generics::empty(), hir::TraitItemKind::Const(ty, body))
841             }
842             AssocItemKind::Fn(box Fn { ref sig, ref generics, body: None, .. }) => {
843                 let names = self.lower_fn_params_to_names(&sig.decl);
844                 let (generics, sig) = self.lower_method_sig(
845                     generics,
846                     sig,
847                     trait_item_def_id,
848                     FnDeclKind::Trait,
849                     None,
850                 );
851                 (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)))
852             }
853             AssocItemKind::Fn(box Fn { ref sig, ref generics, body: Some(ref body), .. }) => {
854                 let asyncness = sig.header.asyncness;
855                 let body_id =
856                     self.lower_maybe_async_body(i.span, &sig.decl, asyncness, Some(&body));
857                 let (generics, sig) = self.lower_method_sig(
858                     generics,
859                     sig,
860                     trait_item_def_id,
861                     FnDeclKind::Trait,
862                     asyncness.opt_return_id(),
863                 );
864                 (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)))
865             }
866             AssocItemKind::TyAlias(box TyAlias {
867                 ref generics,
868                 where_clauses,
869                 ref bounds,
870                 ref ty,
871                 ..
872             }) => {
873                 let ty = ty.as_ref().map(|x| {
874                     self.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Type))
875                 });
876                 let mut generics = generics.clone();
877                 add_ty_alias_where_clause(&mut generics, where_clauses, false);
878                 let generics = self.lower_generics(
879                     &generics,
880                     ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
881                 );
882                 let kind = hir::TraitItemKind::Type(
883                     self.lower_param_bounds(
884                         bounds,
885                         ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
886                     ),
887                     ty,
888                 );
889
890                 (generics, kind)
891             }
892             AssocItemKind::MacCall(..) => panic!("macro item shouldn't exist at this point"),
893         };
894
895         self.lower_attrs(hir_id, &i.attrs);
896         let item = hir::TraitItem {
897             def_id: trait_item_def_id,
898             ident: self.lower_ident(i.ident),
899             generics,
900             kind,
901             span: self.lower_span(i.span),
902         };
903         self.arena.alloc(item)
904     }
905
906     fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef {
907         let (kind, has_default) = match &i.kind {
908             AssocItemKind::Const(_, _, default) => (hir::AssocItemKind::Const, default.is_some()),
909             AssocItemKind::TyAlias(box TyAlias { ty, .. }) => {
910                 (hir::AssocItemKind::Type, ty.is_some())
911             }
912             AssocItemKind::Fn(box Fn { sig, body, .. }) => {
913                 (hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }, body.is_some())
914             }
915             AssocItemKind::MacCall(..) => unimplemented!(),
916         };
917         let id = hir::TraitItemId { def_id: self.resolver.local_def_id(i.id) };
918         let defaultness = hir::Defaultness::Default { has_value: has_default };
919         hir::TraitItemRef {
920             id,
921             ident: self.lower_ident(i.ident),
922             span: self.lower_span(i.span),
923             defaultness,
924             kind,
925         }
926     }
927
928     /// Construct `ExprKind::Err` for the given `span`.
929     crate fn expr_err(&mut self, span: Span) -> hir::Expr<'hir> {
930         self.expr(span, hir::ExprKind::Err, AttrVec::new())
931     }
932
933     fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
934         let impl_item_def_id = self.resolver.local_def_id(i.id);
935
936         let (generics, kind) = match &i.kind {
937             AssocItemKind::Const(_, ty, expr) => {
938                 let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
939                 (
940                     hir::Generics::empty(),
941                     hir::ImplItemKind::Const(ty, self.lower_const_body(i.span, expr.as_deref())),
942                 )
943             }
944             AssocItemKind::Fn(box Fn { sig, generics, body, .. }) => {
945                 self.current_item = Some(i.span);
946                 let asyncness = sig.header.asyncness;
947                 let body_id =
948                     self.lower_maybe_async_body(i.span, &sig.decl, asyncness, body.as_deref());
949                 let (generics, sig) = self.lower_method_sig(
950                     generics,
951                     sig,
952                     impl_item_def_id,
953                     if self.is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent },
954                     asyncness.opt_return_id(),
955                 );
956
957                 (generics, hir::ImplItemKind::Fn(sig, body_id))
958             }
959             AssocItemKind::TyAlias(box TyAlias { generics, where_clauses, ty, .. }) => {
960                 let mut generics = generics.clone();
961                 add_ty_alias_where_clause(&mut generics, *where_clauses, false);
962                 let generics = self.lower_generics(
963                     &generics,
964                     ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
965                 );
966                 let kind = match ty {
967                     None => {
968                         let ty = self.arena.alloc(self.ty(i.span, hir::TyKind::Err));
969                         hir::ImplItemKind::TyAlias(ty)
970                     }
971                     Some(ty) => {
972                         let ty = self.lower_ty(
973                             ty,
974                             ImplTraitContext::TypeAliasesOpaqueTy {
975                                 capturable_lifetimes: &mut FxHashSet::default(),
976                             },
977                         );
978                         hir::ImplItemKind::TyAlias(ty)
979                     }
980                 };
981                 (generics, kind)
982             }
983             AssocItemKind::MacCall(..) => panic!("`TyMac` should have been expanded by now"),
984         };
985
986         let hir_id = self.lower_node_id(i.id);
987         self.lower_attrs(hir_id, &i.attrs);
988         let item = hir::ImplItem {
989             def_id: hir_id.expect_owner(),
990             ident: self.lower_ident(i.ident),
991             generics,
992             vis: self.lower_visibility(&i.vis),
993             kind,
994             span: self.lower_span(i.span),
995         };
996         self.arena.alloc(item)
997     }
998
999     fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef {
1000         // Since `default impl` is not yet implemented, this is always true in impls.
1001         let has_value = true;
1002         let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
1003         hir::ImplItemRef {
1004             id: hir::ImplItemId { def_id: self.resolver.local_def_id(i.id) },
1005             ident: self.lower_ident(i.ident),
1006             span: self.lower_span(i.span),
1007             defaultness,
1008             kind: match &i.kind {
1009                 AssocItemKind::Const(..) => hir::AssocItemKind::Const,
1010                 AssocItemKind::TyAlias(..) => hir::AssocItemKind::Type,
1011                 AssocItemKind::Fn(box Fn { sig, .. }) => {
1012                     hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }
1013                 }
1014                 AssocItemKind::MacCall(..) => unimplemented!(),
1015             },
1016             trait_item_def_id: self.resolver.get_partial_res(i.id).map(|r| r.base_res().def_id()),
1017         }
1018     }
1019
1020     /// If an `explicit_owner` is given, this method allocates the `HirId` in
1021     /// the address space of that item instead of the item currently being
1022     /// lowered. This can happen during `lower_impl_item_ref()` where we need to
1023     /// lower a `Visibility` value although we haven't lowered the owning
1024     /// `ImplItem` in question yet.
1025     fn lower_visibility(&mut self, v: &Visibility) -> hir::Visibility<'hir> {
1026         let node = match v.kind {
1027             VisibilityKind::Public => hir::VisibilityKind::Public,
1028             VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar),
1029             VisibilityKind::Restricted { ref path, id } => {
1030                 debug!("lower_visibility: restricted path id = {:?}", id);
1031                 let lowered_id = self.lower_node_id(id);
1032                 hir::VisibilityKind::Restricted {
1033                     path: self.lower_path(id, path, ParamMode::Explicit),
1034                     hir_id: lowered_id,
1035                 }
1036             }
1037             VisibilityKind::Inherited => hir::VisibilityKind::Inherited,
1038         };
1039         respan(self.lower_span(v.span), node)
1040     }
1041
1042     fn lower_defaultness(
1043         &self,
1044         d: Defaultness,
1045         has_value: bool,
1046     ) -> (hir::Defaultness, Option<Span>) {
1047         match d {
1048             Defaultness::Default(sp) => {
1049                 (hir::Defaultness::Default { has_value }, Some(self.lower_span(sp)))
1050             }
1051             Defaultness::Final => {
1052                 assert!(has_value);
1053                 (hir::Defaultness::Final, None)
1054             }
1055         }
1056     }
1057
1058     fn record_body(
1059         &mut self,
1060         params: &'hir [hir::Param<'hir>],
1061         value: hir::Expr<'hir>,
1062     ) -> hir::BodyId {
1063         let body = hir::Body { generator_kind: self.generator_kind, params, value };
1064         let id = body.id();
1065         debug_assert_eq!(id.hir_id.owner, self.current_hir_id_owner);
1066         self.bodies.push((id.hir_id.local_id, self.arena.alloc(body)));
1067         id
1068     }
1069
1070     pub(super) fn lower_body(
1071         &mut self,
1072         f: impl FnOnce(&mut Self) -> (&'hir [hir::Param<'hir>], hir::Expr<'hir>),
1073     ) -> hir::BodyId {
1074         let prev_gen_kind = self.generator_kind.take();
1075         let task_context = self.task_context.take();
1076         let (parameters, result) = f(self);
1077         let body_id = self.record_body(parameters, result);
1078         self.task_context = task_context;
1079         self.generator_kind = prev_gen_kind;
1080         body_id
1081     }
1082
1083     fn lower_param(&mut self, param: &Param) -> hir::Param<'hir> {
1084         let hir_id = self.lower_node_id(param.id);
1085         self.lower_attrs(hir_id, &param.attrs);
1086         hir::Param {
1087             hir_id,
1088             pat: self.lower_pat(&param.pat),
1089             ty_span: self.lower_span(param.ty.span),
1090             span: self.lower_span(param.span),
1091         }
1092     }
1093
1094     pub(super) fn lower_fn_body(
1095         &mut self,
1096         decl: &FnDecl,
1097         body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
1098     ) -> hir::BodyId {
1099         self.lower_body(|this| {
1100             (
1101                 this.arena.alloc_from_iter(decl.inputs.iter().map(|x| this.lower_param(x))),
1102                 body(this),
1103             )
1104         })
1105     }
1106
1107     fn lower_fn_body_block(
1108         &mut self,
1109         span: Span,
1110         decl: &FnDecl,
1111         body: Option<&Block>,
1112     ) -> hir::BodyId {
1113         self.lower_fn_body(decl, |this| this.lower_block_expr_opt(span, body))
1114     }
1115
1116     fn lower_block_expr_opt(&mut self, span: Span, block: Option<&Block>) -> hir::Expr<'hir> {
1117         match block {
1118             Some(block) => self.lower_block_expr(block),
1119             None => self.expr_err(span),
1120         }
1121     }
1122
1123     pub(super) fn lower_const_body(&mut self, span: Span, expr: Option<&Expr>) -> hir::BodyId {
1124         self.lower_body(|this| {
1125             (
1126                 &[],
1127                 match expr {
1128                     Some(expr) => this.lower_expr_mut(expr),
1129                     None => this.expr_err(span),
1130                 },
1131             )
1132         })
1133     }
1134
1135     fn lower_maybe_async_body(
1136         &mut self,
1137         span: Span,
1138         decl: &FnDecl,
1139         asyncness: Async,
1140         body: Option<&Block>,
1141     ) -> hir::BodyId {
1142         let closure_id = match asyncness {
1143             Async::Yes { closure_id, .. } => closure_id,
1144             Async::No => return self.lower_fn_body_block(span, decl, body),
1145         };
1146
1147         self.lower_body(|this| {
1148             let mut parameters: Vec<hir::Param<'_>> = Vec::new();
1149             let mut statements: Vec<hir::Stmt<'_>> = Vec::new();
1150
1151             // Async function parameters are lowered into the closure body so that they are
1152             // captured and so that the drop order matches the equivalent non-async functions.
1153             //
1154             // from:
1155             //
1156             //     async fn foo(<pattern>: <ty>, <pattern>: <ty>, <pattern>: <ty>) {
1157             //         <body>
1158             //     }
1159             //
1160             // into:
1161             //
1162             //     fn foo(__arg0: <ty>, __arg1: <ty>, __arg2: <ty>) {
1163             //       async move {
1164             //         let __arg2 = __arg2;
1165             //         let <pattern> = __arg2;
1166             //         let __arg1 = __arg1;
1167             //         let <pattern> = __arg1;
1168             //         let __arg0 = __arg0;
1169             //         let <pattern> = __arg0;
1170             //         drop-temps { <body> } // see comments later in fn for details
1171             //       }
1172             //     }
1173             //
1174             // If `<pattern>` is a simple ident, then it is lowered to a single
1175             // `let <pattern> = <pattern>;` statement as an optimization.
1176             //
1177             // Note that the body is embedded in `drop-temps`; an
1178             // equivalent desugaring would be `return { <body>
1179             // };`. The key point is that we wish to drop all the
1180             // let-bound variables and temporaries created in the body
1181             // (and its tail expression!) before we drop the
1182             // parameters (c.f. rust-lang/rust#64512).
1183             for (index, parameter) in decl.inputs.iter().enumerate() {
1184                 let parameter = this.lower_param(parameter);
1185                 let span = parameter.pat.span;
1186
1187                 // Check if this is a binding pattern, if so, we can optimize and avoid adding a
1188                 // `let <pat> = __argN;` statement. In this case, we do not rename the parameter.
1189                 let (ident, is_simple_parameter) = match parameter.pat.kind {
1190                     hir::PatKind::Binding(
1191                         hir::BindingAnnotation::Unannotated | hir::BindingAnnotation::Mutable,
1192                         _,
1193                         ident,
1194                         _,
1195                     ) => (ident, true),
1196                     // For `ref mut` or wildcard arguments, we can't reuse the binding, but
1197                     // we can keep the same name for the parameter.
1198                     // This lets rustdoc render it correctly in documentation.
1199                     hir::PatKind::Binding(_, _, ident, _) => (ident, false),
1200                     hir::PatKind::Wild => {
1201                         (Ident::with_dummy_span(rustc_span::symbol::kw::Underscore), false)
1202                     }
1203                     _ => {
1204                         // Replace the ident for bindings that aren't simple.
1205                         let name = format!("__arg{}", index);
1206                         let ident = Ident::from_str(&name);
1207
1208                         (ident, false)
1209                     }
1210                 };
1211
1212                 let desugared_span = this.mark_span_with_reason(DesugaringKind::Async, span, None);
1213
1214                 // Construct a parameter representing `__argN: <ty>` to replace the parameter of the
1215                 // async function.
1216                 //
1217                 // If this is the simple case, this parameter will end up being the same as the
1218                 // original parameter, but with a different pattern id.
1219                 let stmt_attrs = this.attrs.get(&parameter.hir_id.local_id).copied();
1220                 let (new_parameter_pat, new_parameter_id) = this.pat_ident(desugared_span, ident);
1221                 let new_parameter = hir::Param {
1222                     hir_id: parameter.hir_id,
1223                     pat: new_parameter_pat,
1224                     ty_span: this.lower_span(parameter.ty_span),
1225                     span: this.lower_span(parameter.span),
1226                 };
1227
1228                 if is_simple_parameter {
1229                     // If this is the simple case, then we only insert one statement that is
1230                     // `let <pat> = <pat>;`. We re-use the original argument's pattern so that
1231                     // `HirId`s are densely assigned.
1232                     let expr = this.expr_ident(desugared_span, ident, new_parameter_id);
1233                     let stmt = this.stmt_let_pat(
1234                         stmt_attrs,
1235                         desugared_span,
1236                         Some(expr),
1237                         parameter.pat,
1238                         hir::LocalSource::AsyncFn,
1239                     );
1240                     statements.push(stmt);
1241                 } else {
1242                     // If this is not the simple case, then we construct two statements:
1243                     //
1244                     // ```
1245                     // let __argN = __argN;
1246                     // let <pat> = __argN;
1247                     // ```
1248                     //
1249                     // The first statement moves the parameter into the closure and thus ensures
1250                     // that the drop order is correct.
1251                     //
1252                     // The second statement creates the bindings that the user wrote.
1253
1254                     // Construct the `let mut __argN = __argN;` statement. It must be a mut binding
1255                     // because the user may have specified a `ref mut` binding in the next
1256                     // statement.
1257                     let (move_pat, move_id) = this.pat_ident_binding_mode(
1258                         desugared_span,
1259                         ident,
1260                         hir::BindingAnnotation::Mutable,
1261                     );
1262                     let move_expr = this.expr_ident(desugared_span, ident, new_parameter_id);
1263                     let move_stmt = this.stmt_let_pat(
1264                         None,
1265                         desugared_span,
1266                         Some(move_expr),
1267                         move_pat,
1268                         hir::LocalSource::AsyncFn,
1269                     );
1270
1271                     // Construct the `let <pat> = __argN;` statement. We re-use the original
1272                     // parameter's pattern so that `HirId`s are densely assigned.
1273                     let pattern_expr = this.expr_ident(desugared_span, ident, move_id);
1274                     let pattern_stmt = this.stmt_let_pat(
1275                         stmt_attrs,
1276                         desugared_span,
1277                         Some(pattern_expr),
1278                         parameter.pat,
1279                         hir::LocalSource::AsyncFn,
1280                     );
1281
1282                     statements.push(move_stmt);
1283                     statements.push(pattern_stmt);
1284                 };
1285
1286                 parameters.push(new_parameter);
1287             }
1288
1289             let body_span = body.map_or(span, |b| b.span);
1290             let async_expr = this.make_async_expr(
1291                 CaptureBy::Value,
1292                 closure_id,
1293                 None,
1294                 body_span,
1295                 hir::AsyncGeneratorKind::Fn,
1296                 |this| {
1297                     // Create a block from the user's function body:
1298                     let user_body = this.lower_block_expr_opt(body_span, body);
1299
1300                     // Transform into `drop-temps { <user-body> }`, an expression:
1301                     let desugared_span =
1302                         this.mark_span_with_reason(DesugaringKind::Async, user_body.span, None);
1303                     let user_body = this.expr_drop_temps(
1304                         desugared_span,
1305                         this.arena.alloc(user_body),
1306                         AttrVec::new(),
1307                     );
1308
1309                     // As noted above, create the final block like
1310                     //
1311                     // ```
1312                     // {
1313                     //   let $param_pattern = $raw_param;
1314                     //   ...
1315                     //   drop-temps { <user-body> }
1316                     // }
1317                     // ```
1318                     let body = this.block_all(
1319                         desugared_span,
1320                         this.arena.alloc_from_iter(statements),
1321                         Some(user_body),
1322                     );
1323
1324                     this.expr_block(body, AttrVec::new())
1325                 },
1326             );
1327
1328             (
1329                 this.arena.alloc_from_iter(parameters),
1330                 this.expr(body_span, async_expr, AttrVec::new()),
1331             )
1332         })
1333     }
1334
1335     fn lower_method_sig(
1336         &mut self,
1337         generics: &Generics,
1338         sig: &FnSig,
1339         fn_def_id: LocalDefId,
1340         kind: FnDeclKind,
1341         is_async: Option<NodeId>,
1342     ) -> (hir::Generics<'hir>, hir::FnSig<'hir>) {
1343         let header = self.lower_fn_header(sig.header);
1344         let (generics, decl) = self.add_in_band_defs(
1345             generics,
1346             fn_def_id,
1347             AnonymousLifetimeMode::PassThrough,
1348             |this, idty| this.lower_fn_decl(&sig.decl, Some((fn_def_id, idty)), kind, is_async),
1349         );
1350         (generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
1351     }
1352
1353     fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader {
1354         hir::FnHeader {
1355             unsafety: self.lower_unsafety(h.unsafety),
1356             asyncness: self.lower_asyncness(h.asyncness),
1357             constness: self.lower_constness(h.constness),
1358             abi: self.lower_extern(h.ext),
1359         }
1360     }
1361
1362     pub(super) fn lower_abi(&mut self, abi: StrLit) -> abi::Abi {
1363         abi::lookup(abi.symbol_unescaped.as_str()).unwrap_or_else(|| {
1364             self.error_on_invalid_abi(abi);
1365             abi::Abi::Rust
1366         })
1367     }
1368
1369     pub(super) fn lower_extern(&mut self, ext: Extern) -> abi::Abi {
1370         match ext {
1371             Extern::None => abi::Abi::Rust,
1372             Extern::Implicit => abi::Abi::FALLBACK,
1373             Extern::Explicit(abi) => self.lower_abi(abi),
1374         }
1375     }
1376
1377     fn error_on_invalid_abi(&self, abi: StrLit) {
1378         struct_span_err!(self.sess, abi.span, E0703, "invalid ABI: found `{}`", abi.symbol)
1379             .span_label(abi.span, "invalid ABI")
1380             .help(&format!("valid ABIs: {}", abi::all_names().join(", ")))
1381             .emit();
1382     }
1383
1384     fn lower_asyncness(&mut self, a: Async) -> hir::IsAsync {
1385         match a {
1386             Async::Yes { .. } => hir::IsAsync::Async,
1387             Async::No => hir::IsAsync::NotAsync,
1388         }
1389     }
1390
1391     fn lower_constness(&mut self, c: Const) -> hir::Constness {
1392         match c {
1393             Const::Yes(_) => hir::Constness::Const,
1394             Const::No => hir::Constness::NotConst,
1395         }
1396     }
1397
1398     pub(super) fn lower_unsafety(&mut self, u: Unsafe) -> hir::Unsafety {
1399         match u {
1400             Unsafe::Yes(_) => hir::Unsafety::Unsafe,
1401             Unsafe::No => hir::Unsafety::Normal,
1402         }
1403     }
1404
1405     pub(super) fn lower_generics_mut(
1406         &mut self,
1407         generics: &Generics,
1408         itctx: ImplTraitContext<'_, 'hir>,
1409     ) -> GenericsCtor<'hir> {
1410         // Error if `?Trait` bounds in where clauses don't refer directly to type parameters.
1411         // Note: we used to clone these bounds directly onto the type parameter (and avoid lowering
1412         // these into hir when we lower thee where clauses), but this makes it quite difficult to
1413         // keep track of the Span info. Now, `add_implicitly_sized` in `AstConv` checks both param bounds and
1414         // where clauses for `?Sized`.
1415         for pred in &generics.where_clause.predicates {
1416             let WherePredicate::BoundPredicate(ref bound_pred) = *pred else {
1417                 continue;
1418             };
1419             let compute_is_param = || {
1420                 // Check if the where clause type is a plain type parameter.
1421                 match self
1422                     .resolver
1423                     .get_partial_res(bound_pred.bounded_ty.id)
1424                     .map(|d| (d.base_res(), d.unresolved_segments()))
1425                 {
1426                     Some((Res::Def(DefKind::TyParam, def_id), 0))
1427                         if bound_pred.bound_generic_params.is_empty() =>
1428                     {
1429                         generics
1430                             .params
1431                             .iter()
1432                             .any(|p| def_id == self.resolver.local_def_id(p.id).to_def_id())
1433                     }
1434                     // Either the `bounded_ty` is not a plain type parameter, or
1435                     // it's not found in the generic type parameters list.
1436                     _ => false,
1437                 }
1438             };
1439             // We only need to compute this once per `WherePredicate`, but don't
1440             // need to compute this at all unless there is a Maybe bound.
1441             let mut is_param: Option<bool> = None;
1442             for bound in &bound_pred.bounds {
1443                 if !matches!(*bound, GenericBound::Trait(_, TraitBoundModifier::Maybe)) {
1444                     continue;
1445                 }
1446                 let is_param = *is_param.get_or_insert_with(compute_is_param);
1447                 if !is_param {
1448                     self.diagnostic().span_err(
1449                         bound.span(),
1450                         "`?Trait` bounds are only permitted at the \
1451                         point where a type parameter is declared",
1452                     );
1453                 }
1454             }
1455         }
1456
1457         GenericsCtor {
1458             params: self.lower_generic_params_mut(&generics.params, itctx).collect(),
1459             where_clause: self.lower_where_clause(&generics.where_clause),
1460             span: self.lower_span(generics.span),
1461         }
1462     }
1463
1464     pub(super) fn lower_generics(
1465         &mut self,
1466         generics: &Generics,
1467         itctx: ImplTraitContext<'_, 'hir>,
1468     ) -> hir::Generics<'hir> {
1469         let generics_ctor = self.lower_generics_mut(generics, itctx);
1470         generics_ctor.into_generics(self.arena)
1471     }
1472
1473     fn lower_where_clause(&mut self, wc: &WhereClause) -> hir::WhereClause<'hir> {
1474         self.with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| {
1475             hir::WhereClause {
1476                 predicates: this.arena.alloc_from_iter(
1477                     wc.predicates.iter().map(|predicate| this.lower_where_predicate(predicate)),
1478                 ),
1479                 span: this.lower_span(wc.span),
1480             }
1481         })
1482     }
1483
1484     fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> {
1485         match *pred {
1486             WherePredicate::BoundPredicate(WhereBoundPredicate {
1487                 ref bound_generic_params,
1488                 ref bounded_ty,
1489                 ref bounds,
1490                 span,
1491             }) => self.with_in_scope_lifetime_defs(&bound_generic_params, |this| {
1492                 hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
1493                     bound_generic_params: this.lower_generic_params(
1494                         bound_generic_params,
1495                         ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
1496                     ),
1497                     bounded_ty: this.lower_ty(
1498                         bounded_ty,
1499                         ImplTraitContext::Disallowed(ImplTraitPosition::Type),
1500                     ),
1501                     bounds: this.arena.alloc_from_iter(bounds.iter().map(|bound| {
1502                         this.lower_param_bound(
1503                             bound,
1504                             ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
1505                         )
1506                     })),
1507                     span: this.lower_span(span),
1508                 })
1509             }),
1510             WherePredicate::RegionPredicate(WhereRegionPredicate {
1511                 ref lifetime,
1512                 ref bounds,
1513                 span,
1514             }) => hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
1515                 span: self.lower_span(span),
1516                 lifetime: self.lower_lifetime(lifetime),
1517                 bounds: self.lower_param_bounds(
1518                     bounds,
1519                     ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
1520                 ),
1521             }),
1522             WherePredicate::EqPredicate(WhereEqPredicate { id, ref lhs_ty, ref rhs_ty, span }) => {
1523                 hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
1524                     hir_id: self.lower_node_id(id),
1525                     lhs_ty: self
1526                         .lower_ty(lhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type)),
1527                     rhs_ty: self
1528                         .lower_ty(rhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type)),
1529                     span: self.lower_span(span),
1530                 })
1531             }
1532         }
1533     }
1534 }
1535
1536 /// Helper struct for delayed construction of Generics.
1537 pub(super) struct GenericsCtor<'hir> {
1538     pub(super) params: SmallVec<[hir::GenericParam<'hir>; 4]>,
1539     where_clause: hir::WhereClause<'hir>,
1540     span: Span,
1541 }
1542
1543 impl<'hir> GenericsCtor<'hir> {
1544     pub(super) fn into_generics(self, arena: &'hir Arena<'hir>) -> hir::Generics<'hir> {
1545         hir::Generics {
1546             params: arena.alloc_from_iter(self.params),
1547             where_clause: self.where_clause,
1548             span: self.span,
1549         }
1550     }
1551 }