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