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