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