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