]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_ast_lowering/src/lib.rs
Rollup merge of #99103 - TaKO8Ki:avoid-&str-to-string-conversions, r=oli-obk
[rust.git] / compiler / rustc_ast_lowering / src / lib.rs
1 //! Lowers the AST to the HIR.
2 //!
3 //! Since the AST and HIR are fairly similar, this is mostly a simple procedure,
4 //! much like a fold. Where lowering involves a bit more work things get more
5 //! interesting and there are some invariants you should know about. These mostly
6 //! concern spans and IDs.
7 //!
8 //! Spans are assigned to AST nodes during parsing and then are modified during
9 //! expansion to indicate the origin of a node and the process it went through
10 //! being expanded. IDs are assigned to AST nodes just before lowering.
11 //!
12 //! For the simpler lowering steps, IDs and spans should be preserved. Unlike
13 //! expansion we do not preserve the process of lowering in the spans, so spans
14 //! should not be modified here. When creating a new node (as opposed to
15 //! "folding" an existing one), create a new ID using `next_id()`.
16 //!
17 //! You must ensure that IDs are unique. That means that you should only use the
18 //! ID from an AST node in a single HIR node (you can assume that AST node-IDs
19 //! are unique). Every new node must have a unique ID. Avoid cloning HIR nodes.
20 //! If you do, you must then set the new node's ID to a fresh one.
21 //!
22 //! Spans are used for error messages and for tools to map semantics back to
23 //! source code. It is therefore not as important with spans as IDs to be strict
24 //! about use (you can't break the compiler by screwing up a span). Obviously, a
25 //! HIR node can only have a single span. But multiple nodes can have the same
26 //! span and spans don't need to be kept in order, etc. Where code is preserved
27 //! by lowering, it should have the same span as in the AST. Where HIR nodes are
28 //! new it is probably best to give a span for the whole AST node being lowered.
29 //! All nodes should have real spans; don't use dummy spans. Tools are likely to
30 //! get confused if the spans from leaf AST nodes occur in multiple places
31 //! in the HIR, especially for multiple identifiers.
32
33 #![feature(box_patterns)]
34 #![feature(let_chains)]
35 #![feature(let_else)]
36 #![feature(never_type)]
37 #![recursion_limit = "256"]
38 #![allow(rustc::potential_query_instability)]
39
40 #[macro_use]
41 extern crate tracing;
42
43 use rustc_ast::visit;
44 use rustc_ast::{self as ast, *};
45 use rustc_ast_pretty::pprust;
46 use rustc_data_structures::captures::Captures;
47 use rustc_data_structures::fingerprint::Fingerprint;
48 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
49 use rustc_data_structures::sorted_map::SortedMap;
50 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
51 use rustc_data_structures::sync::Lrc;
52 use rustc_errors::{struct_span_err, Applicability, Handler};
53 use rustc_hir as hir;
54 use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res};
55 use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
56 use rustc_hir::definitions::DefPathData;
57 use rustc_hir::{ConstArg, GenericArg, ItemLocalId, ParamName, TraitCandidate};
58 use rustc_index::vec::{Idx, IndexVec};
59 use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
60 use rustc_session::parse::feature_err;
61 use rustc_span::hygiene::MacroKind;
62 use rustc_span::source_map::DesugaringKind;
63 use rustc_span::symbol::{kw, sym, Ident, Symbol};
64 use rustc_span::{Span, DUMMY_SP};
65
66 use smallvec::SmallVec;
67 use std::collections::hash_map::Entry;
68
69 macro_rules! arena_vec {
70     ($this:expr; $($x:expr),*) => (
71         $this.arena.alloc_from_iter([$($x),*])
72     );
73 }
74
75 mod asm;
76 mod block;
77 mod expr;
78 mod index;
79 mod item;
80 mod pat;
81 mod path;
82
83 struct LoweringContext<'a, 'hir> {
84     tcx: TyCtxt<'hir>,
85     resolver: &'a mut ResolverAstLowering,
86
87     /// Used to allocate HIR nodes.
88     arena: &'hir hir::Arena<'hir>,
89
90     /// Bodies inside the owner being lowered.
91     bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>,
92     /// Attributes inside the owner being lowered.
93     attrs: SortedMap<hir::ItemLocalId, &'hir [Attribute]>,
94     /// Collect items that were created by lowering the current owner.
95     children: FxHashMap<LocalDefId, hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>>>,
96
97     generator_kind: Option<hir::GeneratorKind>,
98
99     /// When inside an `async` context, this is the `HirId` of the
100     /// `task_context` local bound to the resume argument of the generator.
101     task_context: Option<hir::HirId>,
102
103     /// Used to get the current `fn`'s def span to point to when using `await`
104     /// outside of an `async fn`.
105     current_item: Option<Span>,
106
107     catch_scope: Option<NodeId>,
108     loop_scope: Option<NodeId>,
109     is_in_loop_condition: bool,
110     is_in_trait_impl: bool,
111     is_in_dyn_type: bool,
112
113     /// Used to handle lifetimes appearing in impl-traits.
114     captured_lifetimes: Option<LifetimeCaptureContext>,
115
116     current_hir_id_owner: LocalDefId,
117     item_local_id_counter: hir::ItemLocalId,
118     local_id_to_def_id: SortedMap<ItemLocalId, LocalDefId>,
119     trait_map: FxHashMap<ItemLocalId, Box<[TraitCandidate]>>,
120
121     impl_trait_defs: Vec<hir::GenericParam<'hir>>,
122     impl_trait_bounds: Vec<hir::WherePredicate<'hir>>,
123
124     /// NodeIds that are lowered inside the current HIR owner.
125     node_id_to_local_id: FxHashMap<NodeId, hir::ItemLocalId>,
126
127     allow_try_trait: Option<Lrc<[Symbol]>>,
128     allow_gen_future: Option<Lrc<[Symbol]>>,
129     allow_into_future: Option<Lrc<[Symbol]>>,
130 }
131
132 /// When we lower a lifetime, it is inserted in `captures`, and the resolution is modified so
133 /// to point to the lifetime parameter impl-trait will generate.
134 /// When traversing `for<...>` binders, they are inserted in `binders_to_ignore` so we know *not*
135 /// to rebind the introduced lifetimes.
136 #[derive(Debug)]
137 struct LifetimeCaptureContext {
138     /// parent def_id for new definitions
139     parent_def_id: LocalDefId,
140     /// Set of lifetimes to rebind.
141     captures: FxHashMap<
142         LocalDefId, // original parameter id
143         (
144             Span,        // Span
145             NodeId,      // synthetized parameter id
146             ParamName,   // parameter name
147             LifetimeRes, // original resolution
148         ),
149     >,
150     /// Traversed binders.  The ids in this set should *not* be rebound.
151     binders_to_ignore: FxHashSet<NodeId>,
152 }
153
154 trait ResolverAstLoweringExt {
155     fn legacy_const_generic_args(&self, expr: &Expr) -> Option<Vec<usize>>;
156     fn get_partial_res(&self, id: NodeId) -> Option<PartialRes>;
157     fn get_import_res(&self, id: NodeId) -> PerNS<Option<Res<NodeId>>>;
158     fn get_label_res(&self, id: NodeId) -> Option<NodeId>;
159     fn get_lifetime_res(&self, id: NodeId) -> Option<LifetimeRes>;
160     fn take_extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)>;
161     fn decl_macro_kind(&self, def_id: LocalDefId) -> MacroKind;
162 }
163
164 impl ResolverAstLoweringExt for ResolverAstLowering {
165     fn legacy_const_generic_args(&self, expr: &Expr) -> Option<Vec<usize>> {
166         if let ExprKind::Path(None, path) = &expr.kind {
167             // Don't perform legacy const generics rewriting if the path already
168             // has generic arguments.
169             if path.segments.last().unwrap().args.is_some() {
170                 return None;
171             }
172
173             let partial_res = self.partial_res_map.get(&expr.id)?;
174             if partial_res.unresolved_segments() != 0 {
175                 return None;
176             }
177
178             if let Res::Def(DefKind::Fn, def_id) = partial_res.base_res() {
179                 // We only support cross-crate argument rewriting. Uses
180                 // within the same crate should be updated to use the new
181                 // const generics style.
182                 if def_id.is_local() {
183                     return None;
184                 }
185
186                 if let Some(v) = self.legacy_const_generic_args.get(&def_id) {
187                     return v.clone();
188                 }
189             }
190         }
191
192         None
193     }
194
195     /// Obtains resolution for a `NodeId` with a single resolution.
196     fn get_partial_res(&self, id: NodeId) -> Option<PartialRes> {
197         self.partial_res_map.get(&id).copied()
198     }
199
200     /// Obtains per-namespace resolutions for `use` statement with the given `NodeId`.
201     fn get_import_res(&self, id: NodeId) -> PerNS<Option<Res<NodeId>>> {
202         self.import_res_map.get(&id).copied().unwrap_or_default()
203     }
204
205     /// Obtains resolution for a label with the given `NodeId`.
206     fn get_label_res(&self, id: NodeId) -> Option<NodeId> {
207         self.label_res_map.get(&id).copied()
208     }
209
210     /// Obtains resolution for a lifetime with the given `NodeId`.
211     fn get_lifetime_res(&self, id: NodeId) -> Option<LifetimeRes> {
212         self.lifetimes_res_map.get(&id).copied()
213     }
214
215     /// Obtain the list of lifetimes parameters to add to an item.
216     ///
217     /// Extra lifetime parameters should only be added in places that can appear
218     /// as a `binder` in `LifetimeRes`.
219     ///
220     /// The extra lifetimes that appear from the parenthesized `Fn`-trait desugaring
221     /// should appear at the enclosing `PolyTraitRef`.
222     fn take_extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)> {
223         self.extra_lifetime_params_map.remove(&id).unwrap_or_default()
224     }
225
226     fn decl_macro_kind(&self, def_id: LocalDefId) -> MacroKind {
227         self.builtin_macro_kinds.get(&def_id).copied().unwrap_or(MacroKind::Bang)
228     }
229 }
230
231 /// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,
232 /// and if so, what meaning it has.
233 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
234 enum ImplTraitContext {
235     /// Treat `impl Trait` as shorthand for a new universal generic parameter.
236     /// Example: `fn foo(x: impl Debug)`, where `impl Debug` is conceptually
237     /// equivalent to a fresh universal parameter like `fn foo<T: Debug>(x: T)`.
238     ///
239     /// Newly generated parameters should be inserted into the given `Vec`.
240     Universal,
241
242     /// Treat `impl Trait` as shorthand for a new opaque type.
243     /// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
244     /// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`.
245     ///
246     ReturnPositionOpaqueTy {
247         /// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn,
248         origin: hir::OpaqueTyOrigin,
249     },
250     /// Impl trait in type aliases.
251     TypeAliasesOpaqueTy,
252     /// `impl Trait` is not accepted in this position.
253     Disallowed(ImplTraitPosition),
254 }
255
256 /// Position in which `impl Trait` is disallowed.
257 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
258 enum ImplTraitPosition {
259     Path,
260     Variable,
261     Type,
262     Trait,
263     AsyncBlock,
264     Bound,
265     Generic,
266     ExternFnParam,
267     ClosureParam,
268     PointerParam,
269     FnTraitParam,
270     TraitParam,
271     ImplParam,
272     ExternFnReturn,
273     ClosureReturn,
274     PointerReturn,
275     FnTraitReturn,
276     TraitReturn,
277     ImplReturn,
278 }
279
280 impl std::fmt::Display for ImplTraitPosition {
281     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
282         let name = match self {
283             ImplTraitPosition::Path => "path",
284             ImplTraitPosition::Variable => "variable binding",
285             ImplTraitPosition::Type => "type",
286             ImplTraitPosition::Trait => "trait",
287             ImplTraitPosition::AsyncBlock => "async block",
288             ImplTraitPosition::Bound => "bound",
289             ImplTraitPosition::Generic => "generic",
290             ImplTraitPosition::ExternFnParam => "`extern fn` param",
291             ImplTraitPosition::ClosureParam => "closure param",
292             ImplTraitPosition::PointerParam => "`fn` pointer param",
293             ImplTraitPosition::FnTraitParam => "`Fn` trait param",
294             ImplTraitPosition::TraitParam => "trait method param",
295             ImplTraitPosition::ImplParam => "`impl` method param",
296             ImplTraitPosition::ExternFnReturn => "`extern fn` return",
297             ImplTraitPosition::ClosureReturn => "closure return",
298             ImplTraitPosition::PointerReturn => "`fn` pointer return",
299             ImplTraitPosition::FnTraitReturn => "`Fn` trait return",
300             ImplTraitPosition::TraitReturn => "trait method return",
301             ImplTraitPosition::ImplReturn => "`impl` method return",
302         };
303
304         write!(f, "{}", name)
305     }
306 }
307
308 #[derive(Debug)]
309 enum FnDeclKind {
310     Fn,
311     Inherent,
312     ExternFn,
313     Closure,
314     Pointer,
315     Trait,
316     Impl,
317 }
318
319 impl FnDeclKind {
320     fn impl_trait_return_allowed(&self) -> bool {
321         match self {
322             FnDeclKind::Fn | FnDeclKind::Inherent => true,
323             _ => false,
324         }
325     }
326 }
327
328 #[derive(Copy, Clone)]
329 enum AstOwner<'a> {
330     NonOwner,
331     Crate(&'a ast::Crate),
332     Item(&'a ast::Item),
333     AssocItem(&'a ast::AssocItem, visit::AssocCtxt),
334     ForeignItem(&'a ast::ForeignItem),
335 }
336
337 fn index_crate<'a>(
338     node_id_to_def_id: &FxHashMap<NodeId, LocalDefId>,
339     krate: &'a Crate,
340 ) -> IndexVec<LocalDefId, AstOwner<'a>> {
341     let mut indexer = Indexer { node_id_to_def_id, index: IndexVec::new() };
342     indexer.index.ensure_contains_elem(CRATE_DEF_ID, || AstOwner::NonOwner);
343     indexer.index[CRATE_DEF_ID] = AstOwner::Crate(krate);
344     visit::walk_crate(&mut indexer, krate);
345     return indexer.index;
346
347     struct Indexer<'s, 'a> {
348         node_id_to_def_id: &'s FxHashMap<NodeId, LocalDefId>,
349         index: IndexVec<LocalDefId, AstOwner<'a>>,
350     }
351
352     impl<'a> visit::Visitor<'a> for Indexer<'_, 'a> {
353         fn visit_attribute(&mut self, _: &'a Attribute) {
354             // We do not want to lower expressions that appear in attributes,
355             // as they are not accessible to the rest of the HIR.
356         }
357
358         fn visit_item(&mut self, item: &'a ast::Item) {
359             let def_id = self.node_id_to_def_id[&item.id];
360             self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner);
361             self.index[def_id] = AstOwner::Item(item);
362             visit::walk_item(self, item)
363         }
364
365         fn visit_assoc_item(&mut self, item: &'a ast::AssocItem, ctxt: visit::AssocCtxt) {
366             let def_id = self.node_id_to_def_id[&item.id];
367             self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner);
368             self.index[def_id] = AstOwner::AssocItem(item, ctxt);
369             visit::walk_assoc_item(self, item, ctxt);
370         }
371
372         fn visit_foreign_item(&mut self, item: &'a ast::ForeignItem) {
373             let def_id = self.node_id_to_def_id[&item.id];
374             self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner);
375             self.index[def_id] = AstOwner::ForeignItem(item);
376             visit::walk_foreign_item(self, item);
377         }
378     }
379 }
380
381 /// Compute the hash for the HIR of the full crate.
382 /// This hash will then be part of the crate_hash which is stored in the metadata.
383 fn compute_hir_hash(
384     tcx: TyCtxt<'_>,
385     owners: &IndexVec<LocalDefId, hir::MaybeOwner<&hir::OwnerInfo<'_>>>,
386 ) -> Fingerprint {
387     let mut hir_body_nodes: Vec<_> = owners
388         .iter_enumerated()
389         .filter_map(|(def_id, info)| {
390             let info = info.as_owner()?;
391             let def_path_hash = tcx.hir().def_path_hash(def_id);
392             Some((def_path_hash, info))
393         })
394         .collect();
395     hir_body_nodes.sort_unstable_by_key(|bn| bn.0);
396
397     tcx.with_stable_hashing_context(|mut hcx| {
398         let mut stable_hasher = StableHasher::new();
399         hir_body_nodes.hash_stable(&mut hcx, &mut stable_hasher);
400         stable_hasher.finish()
401     })
402 }
403
404 pub fn lower_to_hir<'hir>(tcx: TyCtxt<'hir>, (): ()) -> hir::Crate<'hir> {
405     let sess = tcx.sess;
406     let krate = tcx.untracked_crate.steal();
407     let mut resolver = tcx.resolver_for_lowering(()).steal();
408
409     let ast_index = index_crate(&resolver.node_id_to_def_id, &krate);
410     let mut owners = IndexVec::from_fn_n(
411         |_| hir::MaybeOwner::Phantom,
412         tcx.definitions_untracked().def_index_count(),
413     );
414
415     for def_id in ast_index.indices() {
416         item::ItemLowerer {
417             tcx,
418             resolver: &mut resolver,
419             ast_index: &ast_index,
420             owners: &mut owners,
421         }
422         .lower_node(def_id);
423     }
424
425     // Drop AST to free memory
426     std::mem::drop(ast_index);
427     sess.time("drop_ast", || std::mem::drop(krate));
428
429     // Discard hygiene data, which isn't required after lowering to HIR.
430     if !sess.opts.debugging_opts.keep_hygiene_data {
431         rustc_span::hygiene::clear_syntax_context_map();
432     }
433
434     let hir_hash = compute_hir_hash(tcx, &owners);
435     hir::Crate { owners, hir_hash }
436 }
437
438 #[derive(Copy, Clone, PartialEq, Debug)]
439 enum ParamMode {
440     /// Any path in a type context.
441     Explicit,
442     /// Path in a type definition, where the anonymous lifetime `'_` is not allowed.
443     ExplicitNamed,
444     /// The `module::Type` in `module::Type::method` in an expression.
445     Optional,
446 }
447
448 enum ParenthesizedGenericArgs {
449     Ok,
450     Err,
451 }
452
453 impl<'a, 'hir> LoweringContext<'a, 'hir> {
454     fn create_def(
455         &mut self,
456         parent: LocalDefId,
457         node_id: ast::NodeId,
458         data: DefPathData,
459     ) -> LocalDefId {
460         debug_assert_ne!(node_id, ast::DUMMY_NODE_ID);
461         assert!(
462             self.opt_local_def_id(node_id).is_none(),
463             "adding a def'n for node-id {:?} and data {:?} but a previous def'n exists: {:?}",
464             node_id,
465             data,
466             self.tcx.hir().def_key(self.local_def_id(node_id)),
467         );
468
469         let def_id = self.tcx.create_def(parent, data);
470
471         debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id);
472         self.resolver.node_id_to_def_id.insert(node_id, def_id);
473
474         def_id
475     }
476
477     fn next_node_id(&mut self) -> NodeId {
478         let start = self.resolver.next_node_id;
479         let next = start.as_u32().checked_add(1).expect("input too large; ran out of NodeIds");
480         self.resolver.next_node_id = ast::NodeId::from_u32(next);
481         start
482     }
483
484     fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> {
485         self.resolver.node_id_to_def_id.get(&node).copied()
486     }
487
488     fn local_def_id(&self, node: NodeId) -> LocalDefId {
489         self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{:?}`", node))
490     }
491
492     /// Freshen the `LoweringContext` and ready it to lower a nested item.
493     /// The lowered item is registered into `self.children`.
494     ///
495     /// This function sets up `HirId` lowering infrastructure,
496     /// and stashes the shared mutable state to avoid pollution by the closure.
497     #[instrument(level = "debug", skip(self, f))]
498     fn with_hir_id_owner(
499         &mut self,
500         owner: NodeId,
501         f: impl FnOnce(&mut Self) -> hir::OwnerNode<'hir>,
502     ) {
503         let def_id = self.local_def_id(owner);
504
505         let current_attrs = std::mem::take(&mut self.attrs);
506         let current_bodies = std::mem::take(&mut self.bodies);
507         let current_node_ids = std::mem::take(&mut self.node_id_to_local_id);
508         let current_id_to_def_id = std::mem::take(&mut self.local_id_to_def_id);
509         let current_trait_map = std::mem::take(&mut self.trait_map);
510         let current_owner = std::mem::replace(&mut self.current_hir_id_owner, def_id);
511         let current_local_counter =
512             std::mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1));
513         let current_impl_trait_defs = std::mem::take(&mut self.impl_trait_defs);
514         let current_impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds);
515
516         // Do not reset `next_node_id` and `node_id_to_def_id`:
517         // we want `f` to be able to refer to the `LocalDefId`s that the caller created.
518         // and the caller to refer to some of the subdefinitions' nodes' `LocalDefId`s.
519
520         // Always allocate the first `HirId` for the owner itself.
521         let _old = self.node_id_to_local_id.insert(owner, hir::ItemLocalId::new(0));
522         debug_assert_eq!(_old, None);
523
524         let item = f(self);
525         debug_assert_eq!(def_id, item.def_id());
526         // `f` should have consumed all the elements in these vectors when constructing `item`.
527         debug_assert!(self.impl_trait_defs.is_empty());
528         debug_assert!(self.impl_trait_bounds.is_empty());
529         let info = self.make_owner_info(item);
530
531         self.attrs = current_attrs;
532         self.bodies = current_bodies;
533         self.node_id_to_local_id = current_node_ids;
534         self.local_id_to_def_id = current_id_to_def_id;
535         self.trait_map = current_trait_map;
536         self.current_hir_id_owner = current_owner;
537         self.item_local_id_counter = current_local_counter;
538         self.impl_trait_defs = current_impl_trait_defs;
539         self.impl_trait_bounds = current_impl_trait_bounds;
540
541         let _old = self.children.insert(def_id, hir::MaybeOwner::Owner(info));
542         debug_assert!(_old.is_none())
543     }
544
545     fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> &'hir hir::OwnerInfo<'hir> {
546         let attrs = std::mem::take(&mut self.attrs);
547         let mut bodies = std::mem::take(&mut self.bodies);
548         let local_id_to_def_id = std::mem::take(&mut self.local_id_to_def_id);
549         let trait_map = std::mem::take(&mut self.trait_map);
550
551         #[cfg(debug_assertions)]
552         for (id, attrs) in attrs.iter() {
553             // Verify that we do not store empty slices in the map.
554             if attrs.is_empty() {
555                 panic!("Stored empty attributes for {:?}", id);
556             }
557         }
558
559         bodies.sort_by_key(|(k, _)| *k);
560         let bodies = SortedMap::from_presorted_elements(bodies);
561         let (hash_including_bodies, hash_without_bodies) = self.hash_owner(node, &bodies);
562         let (nodes, parenting) =
563             index::index_hir(self.tcx.sess, &*self.tcx.definitions_untracked(), node, &bodies);
564         let nodes = hir::OwnerNodes {
565             hash_including_bodies,
566             hash_without_bodies,
567             nodes,
568             bodies,
569             local_id_to_def_id,
570         };
571         let attrs = {
572             let hash = self.tcx.with_stable_hashing_context(|mut hcx| {
573                 let mut stable_hasher = StableHasher::new();
574                 attrs.hash_stable(&mut hcx, &mut stable_hasher);
575                 stable_hasher.finish()
576             });
577             hir::AttributeMap { map: attrs, hash }
578         };
579
580         self.arena.alloc(hir::OwnerInfo { nodes, parenting, attrs, trait_map })
581     }
582
583     /// Hash the HIR node twice, one deep and one shallow hash.  This allows to differentiate
584     /// queries which depend on the full HIR tree and those which only depend on the item signature.
585     fn hash_owner(
586         &mut self,
587         node: hir::OwnerNode<'hir>,
588         bodies: &SortedMap<hir::ItemLocalId, &'hir hir::Body<'hir>>,
589     ) -> (Fingerprint, Fingerprint) {
590         self.tcx.with_stable_hashing_context(|mut hcx| {
591             let mut stable_hasher = StableHasher::new();
592             hcx.with_hir_bodies(true, node.def_id(), bodies, |hcx| {
593                 node.hash_stable(hcx, &mut stable_hasher)
594             });
595             let hash_including_bodies = stable_hasher.finish();
596             let mut stable_hasher = StableHasher::new();
597             hcx.with_hir_bodies(false, node.def_id(), bodies, |hcx| {
598                 node.hash_stable(hcx, &mut stable_hasher)
599             });
600             let hash_without_bodies = stable_hasher.finish();
601             (hash_including_bodies, hash_without_bodies)
602         })
603     }
604
605     /// This method allocates a new `HirId` for the given `NodeId` and stores it in
606     /// the `LoweringContext`'s `NodeId => HirId` map.
607     /// Take care not to call this method if the resulting `HirId` is then not
608     /// actually used in the HIR, as that would trigger an assertion in the
609     /// `HirIdValidator` later on, which makes sure that all `NodeId`s got mapped
610     /// properly. Calling the method twice with the same `NodeId` is fine though.
611     fn lower_node_id(&mut self, ast_node_id: NodeId) -> hir::HirId {
612         assert_ne!(ast_node_id, DUMMY_NODE_ID);
613
614         match self.node_id_to_local_id.entry(ast_node_id) {
615             Entry::Occupied(o) => {
616                 hir::HirId { owner: self.current_hir_id_owner, local_id: *o.get() }
617             }
618             Entry::Vacant(v) => {
619                 // Generate a new `HirId`.
620                 let owner = self.current_hir_id_owner;
621                 let local_id = self.item_local_id_counter;
622                 let hir_id = hir::HirId { owner, local_id };
623
624                 v.insert(local_id);
625                 self.item_local_id_counter.increment_by(1);
626
627                 assert_ne!(local_id, hir::ItemLocalId::new(0));
628                 if let Some(def_id) = self.opt_local_def_id(ast_node_id) {
629                     // Do not override a `MaybeOwner::Owner` that may already here.
630                     self.children.entry(def_id).or_insert(hir::MaybeOwner::NonOwner(hir_id));
631                     self.local_id_to_def_id.insert(local_id, def_id);
632                 }
633
634                 if let Some(traits) = self.resolver.trait_map.remove(&ast_node_id) {
635                     self.trait_map.insert(hir_id.local_id, traits.into_boxed_slice());
636                 }
637
638                 hir_id
639             }
640         }
641     }
642
643     /// Generate a new `HirId` without a backing `NodeId`.
644     fn next_id(&mut self) -> hir::HirId {
645         let owner = self.current_hir_id_owner;
646         let local_id = self.item_local_id_counter;
647         assert_ne!(local_id, hir::ItemLocalId::new(0));
648         self.item_local_id_counter.increment_by(1);
649         hir::HirId { owner, local_id }
650     }
651
652     #[instrument(level = "trace", skip(self))]
653     fn lower_res(&mut self, res: Res<NodeId>) -> Res {
654         let res: Result<Res, ()> = res.apply_id(|id| {
655             let owner = self.current_hir_id_owner;
656             let local_id = self.node_id_to_local_id.get(&id).copied().ok_or(())?;
657             Ok(hir::HirId { owner, local_id })
658         });
659         trace!(?res);
660
661         // We may fail to find a HirId when the Res points to a Local from an enclosing HIR owner.
662         // This can happen when trying to lower the return type `x` in erroneous code like
663         //   async fn foo(x: u8) -> x {}
664         // In that case, `x` is lowered as a function parameter, and the return type is lowered as
665         // an opaque type as a synthesized HIR owner.
666         res.unwrap_or(Res::Err)
667     }
668
669     fn expect_full_res(&mut self, id: NodeId) -> Res<NodeId> {
670         self.resolver.get_partial_res(id).map_or(Res::Err, |pr| {
671             if pr.unresolved_segments() != 0 {
672                 panic!("path not fully resolved: {:?}", pr);
673             }
674             pr.base_res()
675         })
676     }
677
678     fn expect_full_res_from_use(&mut self, id: NodeId) -> impl Iterator<Item = Res<NodeId>> {
679         self.resolver.get_import_res(id).present_items()
680     }
681
682     fn diagnostic(&self) -> &Handler {
683         self.tcx.sess.diagnostic()
684     }
685
686     /// Reuses the span but adds information like the kind of the desugaring and features that are
687     /// allowed inside this span.
688     fn mark_span_with_reason(
689         &self,
690         reason: DesugaringKind,
691         span: Span,
692         allow_internal_unstable: Option<Lrc<[Symbol]>>,
693     ) -> Span {
694         self.tcx.with_stable_hashing_context(|hcx| {
695             span.mark_with_reason(allow_internal_unstable, reason, self.tcx.sess.edition(), hcx)
696         })
697     }
698
699     /// Intercept all spans entering HIR.
700     /// Mark a span as relative to the current owning item.
701     fn lower_span(&self, span: Span) -> Span {
702         if self.tcx.sess.opts.debugging_opts.incremental_relative_spans {
703             span.with_parent(Some(self.current_hir_id_owner))
704         } else {
705             // Do not make spans relative when not using incremental compilation.
706             span
707         }
708     }
709
710     fn lower_ident(&self, ident: Ident) -> Ident {
711         Ident::new(ident.name, self.lower_span(ident.span))
712     }
713
714     /// Converts a lifetime into a new generic parameter.
715     #[tracing::instrument(level = "debug", skip(self))]
716     fn lifetime_res_to_generic_param(
717         &mut self,
718         ident: Ident,
719         node_id: NodeId,
720         res: LifetimeRes,
721     ) -> Option<hir::GenericParam<'hir>> {
722         let (name, kind) = match res {
723             LifetimeRes::Param { .. } => {
724                 (hir::ParamName::Plain(ident), hir::LifetimeParamKind::Explicit)
725             }
726             LifetimeRes::Fresh { param, .. } => {
727                 // Late resolution delegates to us the creation of the `LocalDefId`.
728                 let _def_id = self.create_def(
729                     self.current_hir_id_owner,
730                     param,
731                     DefPathData::LifetimeNs(kw::UnderscoreLifetime),
732                 );
733                 debug!(?_def_id);
734
735                 (hir::ParamName::Fresh, hir::LifetimeParamKind::Elided)
736             }
737             LifetimeRes::Static | LifetimeRes::Error => return None,
738             res => panic!(
739                 "Unexpected lifetime resolution {:?} for {:?} at {:?}",
740                 res, ident, ident.span
741             ),
742         };
743         let hir_id = self.lower_node_id(node_id);
744         Some(hir::GenericParam {
745             hir_id,
746             name,
747             span: self.lower_span(ident.span),
748             pure_wrt_drop: false,
749             kind: hir::GenericParamKind::Lifetime { kind },
750             colon_span: None,
751         })
752     }
753
754     /// Setup lifetime capture for and impl-trait.
755     /// The captures will be added to `captures`.
756     fn while_capturing_lifetimes<T>(
757         &mut self,
758         parent_def_id: LocalDefId,
759         captures: &mut FxHashMap<LocalDefId, (Span, NodeId, ParamName, LifetimeRes)>,
760         f: impl FnOnce(&mut Self) -> T,
761     ) -> T {
762         let lifetime_stash = std::mem::replace(
763             &mut self.captured_lifetimes,
764             Some(LifetimeCaptureContext {
765                 parent_def_id,
766                 captures: std::mem::take(captures),
767                 binders_to_ignore: Default::default(),
768             }),
769         );
770
771         let ret = f(self);
772
773         let ctxt = std::mem::replace(&mut self.captured_lifetimes, lifetime_stash).unwrap();
774         *captures = ctxt.captures;
775
776         ret
777     }
778
779     /// Register a binder to be ignored for lifetime capture.
780     #[tracing::instrument(level = "debug", skip(self, f))]
781     #[inline]
782     fn with_lifetime_binder<T>(
783         &mut self,
784         binder: NodeId,
785         generic_params: &[GenericParam],
786         f: impl FnOnce(&mut Self, &'hir [hir::GenericParam<'hir>]) -> T,
787     ) -> T {
788         let mut generic_params: Vec<_> = self.lower_generic_params_mut(generic_params).collect();
789         let extra_lifetimes = self.resolver.take_extra_lifetime_params(binder);
790         debug!(?extra_lifetimes);
791         generic_params.extend(extra_lifetimes.into_iter().filter_map(|(ident, node_id, res)| {
792             self.lifetime_res_to_generic_param(ident, node_id, res)
793         }));
794         let generic_params = self.arena.alloc_from_iter(generic_params);
795         debug!(?generic_params);
796
797         if let Some(ctxt) = &mut self.captured_lifetimes {
798             ctxt.binders_to_ignore.insert(binder);
799         }
800         let ret = f(self, generic_params);
801         if let Some(ctxt) = &mut self.captured_lifetimes {
802             ctxt.binders_to_ignore.remove(&binder);
803         }
804         ret
805     }
806
807     fn with_dyn_type_scope<T>(&mut self, in_scope: bool, f: impl FnOnce(&mut Self) -> T) -> T {
808         let was_in_dyn_type = self.is_in_dyn_type;
809         self.is_in_dyn_type = in_scope;
810
811         let result = f(self);
812
813         self.is_in_dyn_type = was_in_dyn_type;
814
815         result
816     }
817
818     fn with_new_scopes<T>(&mut self, f: impl FnOnce(&mut Self) -> T) -> T {
819         let was_in_loop_condition = self.is_in_loop_condition;
820         self.is_in_loop_condition = false;
821
822         let catch_scope = self.catch_scope.take();
823         let loop_scope = self.loop_scope.take();
824         let ret = f(self);
825         self.catch_scope = catch_scope;
826         self.loop_scope = loop_scope;
827
828         self.is_in_loop_condition = was_in_loop_condition;
829
830         ret
831     }
832
833     fn lower_attrs(&mut self, id: hir::HirId, attrs: &[Attribute]) -> Option<&'hir [Attribute]> {
834         if attrs.is_empty() {
835             None
836         } else {
837             debug_assert_eq!(id.owner, self.current_hir_id_owner);
838             let ret = self.arena.alloc_from_iter(attrs.iter().map(|a| self.lower_attr(a)));
839             debug_assert!(!ret.is_empty());
840             self.attrs.insert(id.local_id, ret);
841             Some(ret)
842         }
843     }
844
845     fn lower_attr(&self, attr: &Attribute) -> Attribute {
846         // Note that we explicitly do not walk the path. Since we don't really
847         // lower attributes (we use the AST version) there is nowhere to keep
848         // the `HirId`s. We don't actually need HIR version of attributes anyway.
849         // Tokens are also not needed after macro expansion and parsing.
850         let kind = match attr.kind {
851             AttrKind::Normal(ref item, _) => AttrKind::Normal(
852                 AttrItem {
853                     path: item.path.clone(),
854                     args: self.lower_mac_args(&item.args),
855                     tokens: None,
856                 },
857                 None,
858             ),
859             AttrKind::DocComment(comment_kind, data) => AttrKind::DocComment(comment_kind, data),
860         };
861
862         Attribute { kind, id: attr.id, style: attr.style, span: self.lower_span(attr.span) }
863     }
864
865     fn alias_attrs(&mut self, id: hir::HirId, target_id: hir::HirId) {
866         debug_assert_eq!(id.owner, self.current_hir_id_owner);
867         debug_assert_eq!(target_id.owner, self.current_hir_id_owner);
868         if let Some(&a) = self.attrs.get(&target_id.local_id) {
869             debug_assert!(!a.is_empty());
870             self.attrs.insert(id.local_id, a);
871         }
872     }
873
874     fn lower_mac_args(&self, args: &MacArgs) -> MacArgs {
875         match *args {
876             MacArgs::Empty => MacArgs::Empty,
877             MacArgs::Delimited(dspan, delim, ref tokens) => {
878                 // This is either a non-key-value attribute, or a `macro_rules!` body.
879                 // We either not have any nonterminals present (in the case of an attribute),
880                 // or have tokens available for all nonterminals in the case of a nested
881                 // `macro_rules`: e.g:
882                 //
883                 // ```rust
884                 // macro_rules! outer {
885                 //     ($e:expr) => {
886                 //         macro_rules! inner {
887                 //             () => { $e }
888                 //         }
889                 //     }
890                 // }
891                 // ```
892                 //
893                 // In both cases, we don't want to synthesize any tokens
894                 MacArgs::Delimited(dspan, delim, tokens.flattened())
895             }
896             // This is an inert key-value attribute - it will never be visible to macros
897             // after it gets lowered to HIR. Therefore, we can extract literals to handle
898             // nonterminals in `#[doc]` (e.g. `#[doc = $e]`).
899             MacArgs::Eq(eq_span, MacArgsEq::Ast(ref expr)) => {
900                 // In valid code the value always ends up as a single literal. Otherwise, a dummy
901                 // literal suffices because the error is handled elsewhere.
902                 let lit = if let ExprKind::Lit(lit) = &expr.kind {
903                     lit.clone()
904                 } else {
905                     Lit {
906                         token: token::Lit::new(token::LitKind::Err, kw::Empty, None),
907                         kind: LitKind::Err(kw::Empty),
908                         span: DUMMY_SP,
909                     }
910                 };
911                 MacArgs::Eq(eq_span, MacArgsEq::Hir(lit))
912             }
913             MacArgs::Eq(_, MacArgsEq::Hir(ref lit)) => {
914                 unreachable!("in literal form when lowering mac args eq: {:?}", lit)
915             }
916         }
917     }
918
919     /// Given an associated type constraint like one of these:
920     ///
921     /// ```ignore (illustrative)
922     /// T: Iterator<Item: Debug>
923     ///             ^^^^^^^^^^^
924     /// T: Iterator<Item = Debug>
925     ///             ^^^^^^^^^^^^
926     /// ```
927     ///
928     /// returns a `hir::TypeBinding` representing `Item`.
929     #[instrument(level = "debug", skip(self))]
930     fn lower_assoc_ty_constraint(
931         &mut self,
932         constraint: &AssocConstraint,
933         itctx: ImplTraitContext,
934     ) -> hir::TypeBinding<'hir> {
935         debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx);
936         // lower generic arguments of identifier in constraint
937         let gen_args = if let Some(ref gen_args) = constraint.gen_args {
938             let gen_args_ctor = match gen_args {
939                 GenericArgs::AngleBracketed(ref data) => {
940                     self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).0
941                 }
942                 GenericArgs::Parenthesized(ref data) => {
943                     self.emit_bad_parenthesized_trait_in_assoc_ty(data);
944                     self.lower_angle_bracketed_parameter_data(
945                         &data.as_angle_bracketed_args(),
946                         ParamMode::Explicit,
947                         itctx,
948                     )
949                     .0
950                 }
951             };
952             gen_args_ctor.into_generic_args(self)
953         } else {
954             self.arena.alloc(hir::GenericArgs::none())
955         };
956
957         let kind = match constraint.kind {
958             AssocConstraintKind::Equality { ref term } => {
959                 let term = match term {
960                     Term::Ty(ref ty) => self.lower_ty(ty, itctx).into(),
961                     Term::Const(ref c) => self.lower_anon_const(c).into(),
962                 };
963                 hir::TypeBindingKind::Equality { term }
964             }
965             AssocConstraintKind::Bound { ref bounds } => {
966                 // Piggy-back on the `impl Trait` context to figure out the correct behavior.
967                 let (desugar_to_impl_trait, itctx) = match itctx {
968                     // We are in the return position:
969                     //
970                     //     fn foo() -> impl Iterator<Item: Debug>
971                     //
972                     // so desugar to
973                     //
974                     //     fn foo() -> impl Iterator<Item = impl Debug>
975                     ImplTraitContext::ReturnPositionOpaqueTy { .. }
976                     | ImplTraitContext::TypeAliasesOpaqueTy { .. } => (true, itctx),
977
978                     // We are in the argument position, but within a dyn type:
979                     //
980                     //     fn foo(x: dyn Iterator<Item: Debug>)
981                     //
982                     // so desugar to
983                     //
984                     //     fn foo(x: dyn Iterator<Item = impl Debug>)
985                     ImplTraitContext::Universal if self.is_in_dyn_type => (true, itctx),
986
987                     // In `type Foo = dyn Iterator<Item: Debug>` we desugar to
988                     // `type Foo = dyn Iterator<Item = impl Debug>` but we have to override the
989                     // "impl trait context" to permit `impl Debug` in this position (it desugars
990                     // then to an opaque type).
991                     //
992                     // FIXME: this is only needed until `impl Trait` is allowed in type aliases.
993                     ImplTraitContext::Disallowed(_) if self.is_in_dyn_type => {
994                         (true, ImplTraitContext::TypeAliasesOpaqueTy)
995                     }
996
997                     // We are in the parameter position, but not within a dyn type:
998                     //
999                     //     fn foo(x: impl Iterator<Item: Debug>)
1000                     //
1001                     // so we leave it as is and this gets expanded in astconv to a bound like
1002                     // `<T as Iterator>::Item: Debug` where `T` is the type parameter for the
1003                     // `impl Iterator`.
1004                     _ => (false, itctx),
1005                 };
1006
1007                 if desugar_to_impl_trait {
1008                     // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by
1009                     // constructing the HIR for `impl bounds...` and then lowering that.
1010
1011                     let parent_def_id = self.current_hir_id_owner;
1012                     let impl_trait_node_id = self.next_node_id();
1013                     self.create_def(parent_def_id, impl_trait_node_id, DefPathData::ImplTrait);
1014
1015                     self.with_dyn_type_scope(false, |this| {
1016                         let node_id = this.next_node_id();
1017                         let ty = this.lower_ty(
1018                             &Ty {
1019                                 id: node_id,
1020                                 kind: TyKind::ImplTrait(impl_trait_node_id, bounds.clone()),
1021                                 span: this.lower_span(constraint.span),
1022                                 tokens: None,
1023                             },
1024                             itctx,
1025                         );
1026
1027                         hir::TypeBindingKind::Equality { term: ty.into() }
1028                     })
1029                 } else {
1030                     // Desugar `AssocTy: Bounds` into a type binding where the
1031                     // later desugars into a trait predicate.
1032                     let bounds = self.lower_param_bounds(bounds, itctx);
1033
1034                     hir::TypeBindingKind::Constraint { bounds }
1035                 }
1036             }
1037         };
1038
1039         hir::TypeBinding {
1040             hir_id: self.lower_node_id(constraint.id),
1041             ident: self.lower_ident(constraint.ident),
1042             gen_args,
1043             kind,
1044             span: self.lower_span(constraint.span),
1045         }
1046     }
1047
1048     fn emit_bad_parenthesized_trait_in_assoc_ty(&self, data: &ParenthesizedArgs) {
1049         let mut err = self.tcx.sess.struct_span_err(
1050             data.span,
1051             "parenthesized generic arguments cannot be used in associated type constraints",
1052         );
1053         // Suggest removing empty parentheses: "Trait()" -> "Trait"
1054         if data.inputs.is_empty() {
1055             let parentheses_span =
1056                 data.inputs_span.shrink_to_lo().to(data.inputs_span.shrink_to_hi());
1057             err.multipart_suggestion(
1058                 "remove these parentheses",
1059                 vec![(parentheses_span, String::new())],
1060                 Applicability::MaybeIncorrect,
1061             );
1062         }
1063         // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
1064         else {
1065             // Start of parameters to the 1st argument
1066             let open_param = data.inputs_span.shrink_to_lo().to(data
1067                 .inputs
1068                 .first()
1069                 .unwrap()
1070                 .span
1071                 .shrink_to_lo());
1072             // End of last argument to end of parameters
1073             let close_param =
1074                 data.inputs.last().unwrap().span.shrink_to_hi().to(data.inputs_span.shrink_to_hi());
1075             err.multipart_suggestion(
1076                 &format!("use angle brackets instead",),
1077                 vec![(open_param, String::from("<")), (close_param, String::from(">"))],
1078                 Applicability::MaybeIncorrect,
1079             );
1080         }
1081         err.emit();
1082     }
1083
1084     #[instrument(level = "debug", skip(self))]
1085     fn lower_generic_arg(
1086         &mut self,
1087         arg: &ast::GenericArg,
1088         itctx: ImplTraitContext,
1089     ) -> hir::GenericArg<'hir> {
1090         match arg {
1091             ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(&lt)),
1092             ast::GenericArg::Type(ty) => {
1093                 match ty.kind {
1094                     TyKind::Infer if self.tcx.features().generic_arg_infer => {
1095                         return GenericArg::Infer(hir::InferArg {
1096                             hir_id: self.lower_node_id(ty.id),
1097                             span: self.lower_span(ty.span),
1098                         });
1099                     }
1100                     // We parse const arguments as path types as we cannot distinguish them during
1101                     // parsing. We try to resolve that ambiguity by attempting resolution in both the
1102                     // type and value namespaces. If we resolved the path in the value namespace, we
1103                     // transform it into a generic const argument.
1104                     TyKind::Path(ref qself, ref path) => {
1105                         if let Some(partial_res) = self.resolver.get_partial_res(ty.id) {
1106                             let res = partial_res.base_res();
1107                             if !res.matches_ns(Namespace::TypeNS) {
1108                                 debug!(
1109                                     "lower_generic_arg: Lowering type argument as const argument: {:?}",
1110                                     ty,
1111                                 );
1112
1113                                 // Construct an AnonConst where the expr is the "ty"'s path.
1114
1115                                 let parent_def_id = self.current_hir_id_owner;
1116                                 let node_id = self.next_node_id();
1117
1118                                 // Add a definition for the in-band const def.
1119                                 self.create_def(parent_def_id, node_id, DefPathData::AnonConst);
1120
1121                                 let span = self.lower_span(ty.span);
1122                                 let path_expr = Expr {
1123                                     id: ty.id,
1124                                     kind: ExprKind::Path(qself.clone(), path.clone()),
1125                                     span,
1126                                     attrs: AttrVec::new(),
1127                                     tokens: None,
1128                                 };
1129
1130                                 let ct = self.with_new_scopes(|this| hir::AnonConst {
1131                                     hir_id: this.lower_node_id(node_id),
1132                                     body: this.lower_const_body(path_expr.span, Some(&path_expr)),
1133                                 });
1134                                 return GenericArg::Const(ConstArg { value: ct, span });
1135                             }
1136                         }
1137                     }
1138                     _ => {}
1139                 }
1140                 GenericArg::Type(self.lower_ty_direct(&ty, itctx))
1141             }
1142             ast::GenericArg::Const(ct) => GenericArg::Const(ConstArg {
1143                 value: self.lower_anon_const(&ct),
1144                 span: self.lower_span(ct.value.span),
1145             }),
1146         }
1147     }
1148
1149     #[instrument(level = "debug", skip(self))]
1150     fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> &'hir hir::Ty<'hir> {
1151         self.arena.alloc(self.lower_ty_direct(t, itctx))
1152     }
1153
1154     fn lower_path_ty(
1155         &mut self,
1156         t: &Ty,
1157         qself: &Option<QSelf>,
1158         path: &Path,
1159         param_mode: ParamMode,
1160         itctx: ImplTraitContext,
1161     ) -> hir::Ty<'hir> {
1162         let id = self.lower_node_id(t.id);
1163         let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx);
1164         self.ty_path(id, t.span, qpath)
1165     }
1166
1167     fn ty(&mut self, span: Span, kind: hir::TyKind<'hir>) -> hir::Ty<'hir> {
1168         hir::Ty { hir_id: self.next_id(), kind, span: self.lower_span(span) }
1169     }
1170
1171     fn ty_tup(&mut self, span: Span, tys: &'hir [hir::Ty<'hir>]) -> hir::Ty<'hir> {
1172         self.ty(span, hir::TyKind::Tup(tys))
1173     }
1174
1175     fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
1176         let kind = match t.kind {
1177             TyKind::Infer => hir::TyKind::Infer,
1178             TyKind::Err => hir::TyKind::Err,
1179             TyKind::Slice(ref ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
1180             TyKind::Ptr(ref mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
1181             TyKind::Rptr(ref region, ref mt) => {
1182                 let region = region.unwrap_or_else(|| {
1183                     let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) =
1184                         self.resolver.get_lifetime_res(t.id)
1185                     {
1186                         debug_assert_eq!(start.plus(1), end);
1187                         start
1188                     } else {
1189                         self.next_node_id()
1190                     };
1191                     let span = self.tcx.sess.source_map().next_point(t.span.shrink_to_lo());
1192                     Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id }
1193                 });
1194                 let lifetime = self.lower_lifetime(&region);
1195                 hir::TyKind::Rptr(lifetime, self.lower_mt(mt, itctx))
1196             }
1197             TyKind::BareFn(ref f) => {
1198                 self.with_lifetime_binder(t.id, &f.generic_params, |this, generic_params| {
1199                     hir::TyKind::BareFn(this.arena.alloc(hir::BareFnTy {
1200                         generic_params,
1201                         unsafety: this.lower_unsafety(f.unsafety),
1202                         abi: this.lower_extern(f.ext),
1203                         decl: this.lower_fn_decl(&f.decl, None, FnDeclKind::Pointer, None),
1204                         param_names: this.lower_fn_params_to_names(&f.decl),
1205                     }))
1206                 })
1207             }
1208             TyKind::Never => hir::TyKind::Never,
1209             TyKind::Tup(ref tys) => hir::TyKind::Tup(
1210                 self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx))),
1211             ),
1212             TyKind::Paren(ref ty) => {
1213                 return self.lower_ty_direct(ty, itctx);
1214             }
1215             TyKind::Path(ref qself, ref path) => {
1216                 return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx);
1217             }
1218             TyKind::ImplicitSelf => {
1219                 let res = self.expect_full_res(t.id);
1220                 let res = self.lower_res(res);
1221                 hir::TyKind::Path(hir::QPath::Resolved(
1222                     None,
1223                     self.arena.alloc(hir::Path {
1224                         res,
1225                         segments: arena_vec![self; hir::PathSegment::from_ident(
1226                             Ident::with_dummy_span(kw::SelfUpper)
1227                         )],
1228                         span: self.lower_span(t.span),
1229                     }),
1230                 ))
1231             }
1232             TyKind::Array(ref ty, ref length) => {
1233                 hir::TyKind::Array(self.lower_ty(ty, itctx), self.lower_array_length(length))
1234             }
1235             TyKind::Typeof(ref expr) => hir::TyKind::Typeof(self.lower_anon_const(expr)),
1236             TyKind::TraitObject(ref bounds, kind) => {
1237                 let mut lifetime_bound = None;
1238                 let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
1239                     let bounds =
1240                         this.arena.alloc_from_iter(bounds.iter().filter_map(
1241                             |bound| match *bound {
1242                                 GenericBound::Trait(
1243                                     ref ty,
1244                                     TraitBoundModifier::None | TraitBoundModifier::MaybeConst,
1245                                 ) => Some(this.lower_poly_trait_ref(ty, itctx)),
1246                                 // `~const ?Bound` will cause an error during AST validation
1247                                 // anyways, so treat it like `?Bound` as compilation proceeds.
1248                                 GenericBound::Trait(
1249                                     _,
1250                                     TraitBoundModifier::Maybe | TraitBoundModifier::MaybeConstMaybe,
1251                                 ) => None,
1252                                 GenericBound::Outlives(ref lifetime) => {
1253                                     if lifetime_bound.is_none() {
1254                                         lifetime_bound = Some(this.lower_lifetime(lifetime));
1255                                     }
1256                                     None
1257                                 }
1258                             },
1259                         ));
1260                     let lifetime_bound =
1261                         lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));
1262                     (bounds, lifetime_bound)
1263                 });
1264                 hir::TyKind::TraitObject(bounds, lifetime_bound, kind)
1265             }
1266             TyKind::ImplTrait(def_node_id, ref bounds) => {
1267                 let span = t.span;
1268                 match itctx {
1269                     ImplTraitContext::ReturnPositionOpaqueTy { origin } => self
1270                         .lower_opaque_impl_trait(span, origin, def_node_id, |this| {
1271                             this.lower_param_bounds(bounds, itctx)
1272                         }),
1273                     ImplTraitContext::TypeAliasesOpaqueTy => {
1274                         let nested_itctx = ImplTraitContext::TypeAliasesOpaqueTy;
1275                         self.lower_opaque_impl_trait(
1276                             span,
1277                             hir::OpaqueTyOrigin::TyAlias,
1278                             def_node_id,
1279                             |this| this.lower_param_bounds(bounds, nested_itctx),
1280                         )
1281                     }
1282                     ImplTraitContext::Universal => {
1283                         let span = t.span;
1284                         let ident = Ident::from_str_and_span(&pprust::ty_to_string(t), span);
1285                         let (param, bounds, path) =
1286                             self.lower_generic_and_bounds(def_node_id, span, ident, bounds);
1287                         self.impl_trait_defs.push(param);
1288                         if let Some(bounds) = bounds {
1289                             self.impl_trait_bounds.push(bounds);
1290                         }
1291                         path
1292                     }
1293                     ImplTraitContext::Disallowed(position) => {
1294                         let mut err = struct_span_err!(
1295                             self.tcx.sess,
1296                             t.span,
1297                             E0562,
1298                             "`impl Trait` only allowed in function and inherent method return types, not in {}",
1299                             position
1300                         );
1301                         err.emit();
1302                         hir::TyKind::Err
1303                     }
1304                 }
1305             }
1306             TyKind::MacCall(_) => panic!("`TyKind::MacCall` should have been expanded by now"),
1307             TyKind::CVarArgs => {
1308                 self.tcx.sess.delay_span_bug(
1309                     t.span,
1310                     "`TyKind::CVarArgs` should have been handled elsewhere",
1311                 );
1312                 hir::TyKind::Err
1313             }
1314         };
1315
1316         hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.lower_node_id(t.id) }
1317     }
1318
1319     #[tracing::instrument(level = "debug", skip(self, lower_bounds))]
1320     fn lower_opaque_impl_trait(
1321         &mut self,
1322         span: Span,
1323         origin: hir::OpaqueTyOrigin,
1324         opaque_ty_node_id: NodeId,
1325         lower_bounds: impl FnOnce(&mut Self) -> hir::GenericBounds<'hir>,
1326     ) -> hir::TyKind<'hir> {
1327         // Make sure we know that some funky desugaring has been going on here.
1328         // This is a first: there is code in other places like for loop
1329         // desugaring that explicitly states that we don't want to track that.
1330         // Not tracking it makes lints in rustc and clippy very fragile, as
1331         // frequently opened issues show.
1332         let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
1333
1334         let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
1335
1336         let mut collected_lifetimes = FxHashMap::default();
1337         self.with_hir_id_owner(opaque_ty_node_id, |lctx| {
1338             let hir_bounds = if origin == hir::OpaqueTyOrigin::TyAlias {
1339                 lower_bounds(lctx)
1340             } else {
1341                 lctx.while_capturing_lifetimes(
1342                     opaque_ty_def_id,
1343                     &mut collected_lifetimes,
1344                     lower_bounds,
1345                 )
1346             };
1347             debug!(?collected_lifetimes);
1348
1349             let lifetime_defs = lctx.arena.alloc_from_iter(collected_lifetimes.iter().map(
1350                 |(_, &(span, p_id, p_name, _))| {
1351                     let hir_id = lctx.lower_node_id(p_id);
1352                     debug_assert_ne!(lctx.opt_local_def_id(p_id), None);
1353
1354                     let kind = if p_name.ident().name == kw::UnderscoreLifetime {
1355                         hir::LifetimeParamKind::Elided
1356                     } else {
1357                         hir::LifetimeParamKind::Explicit
1358                     };
1359
1360                     hir::GenericParam {
1361                         hir_id,
1362                         name: p_name,
1363                         span,
1364                         pure_wrt_drop: false,
1365                         kind: hir::GenericParamKind::Lifetime { kind },
1366                         colon_span: None,
1367                     }
1368                 },
1369             ));
1370
1371             debug!("lower_opaque_impl_trait: lifetime_defs={:#?}", lifetime_defs);
1372
1373             let opaque_ty_item = hir::OpaqueTy {
1374                 generics: self.arena.alloc(hir::Generics {
1375                     params: lifetime_defs,
1376                     predicates: &[],
1377                     has_where_clause_predicates: false,
1378                     where_clause_span: lctx.lower_span(span),
1379                     span: lctx.lower_span(span),
1380                 }),
1381                 bounds: hir_bounds,
1382                 origin,
1383             };
1384
1385             trace!("lower_opaque_impl_trait: {:#?}", opaque_ty_def_id);
1386             lctx.generate_opaque_type(opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span)
1387         });
1388
1389         let lifetimes = self.arena.alloc_from_iter(collected_lifetimes.into_iter().map(
1390             |(_, (span, _, p_name, res))| {
1391                 let id = self.next_node_id();
1392                 let ident = Ident::new(p_name.ident().name, span);
1393                 let l = self.new_named_lifetime_with_res(id, span, ident, res);
1394                 hir::GenericArg::Lifetime(l)
1395             },
1396         ));
1397
1398         debug!("lower_opaque_impl_trait: lifetimes={:#?}", lifetimes);
1399
1400         // `impl Trait` now just becomes `Foo<'a, 'b, ..>`.
1401         hir::TyKind::OpaqueDef(hir::ItemId { def_id: opaque_ty_def_id }, lifetimes)
1402     }
1403
1404     /// Registers a new opaque type with the proper `NodeId`s and
1405     /// returns the lowered node-ID for the opaque type.
1406     fn generate_opaque_type(
1407         &mut self,
1408         opaque_ty_id: LocalDefId,
1409         opaque_ty_item: hir::OpaqueTy<'hir>,
1410         span: Span,
1411         opaque_ty_span: Span,
1412     ) -> hir::OwnerNode<'hir> {
1413         let opaque_ty_item_kind = hir::ItemKind::OpaqueTy(opaque_ty_item);
1414         // Generate an `type Foo = impl Trait;` declaration.
1415         trace!("registering opaque type with id {:#?}", opaque_ty_id);
1416         let opaque_ty_item = hir::Item {
1417             def_id: opaque_ty_id,
1418             ident: Ident::empty(),
1419             kind: opaque_ty_item_kind,
1420             vis_span: self.lower_span(span.shrink_to_lo()),
1421             span: self.lower_span(opaque_ty_span),
1422         };
1423         hir::OwnerNode::Item(self.arena.alloc(opaque_ty_item))
1424     }
1425
1426     fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Ident] {
1427         // Skip the `...` (`CVarArgs`) trailing arguments from the AST,
1428         // as they are not explicit in HIR/Ty function signatures.
1429         // (instead, the `c_variadic` flag is set to `true`)
1430         let mut inputs = &decl.inputs[..];
1431         if decl.c_variadic() {
1432             inputs = &inputs[..inputs.len() - 1];
1433         }
1434         self.arena.alloc_from_iter(inputs.iter().map(|param| match param.pat.kind {
1435             PatKind::Ident(_, ident, _) => self.lower_ident(ident),
1436             _ => Ident::new(kw::Empty, self.lower_span(param.pat.span)),
1437         }))
1438     }
1439
1440     // Lowers a function declaration.
1441     //
1442     // `decl`: the unlowered (AST) function declaration.
1443     // `fn_def_id`: if `Some`, impl Trait arguments are lowered into generic parameters on the
1444     //      given DefId, otherwise impl Trait is disallowed. Must be `Some` if
1445     //      `make_ret_async` is also `Some`.
1446     // `impl_trait_return_allow`: determines whether `impl Trait` can be used in return position.
1447     //      This guards against trait declarations and implementations where `impl Trait` is
1448     //      disallowed.
1449     // `make_ret_async`: if `Some`, converts `-> T` into `-> impl Future<Output = T>` in the
1450     //      return type. This is used for `async fn` declarations. The `NodeId` is the ID of the
1451     //      return type `impl Trait` item.
1452     #[tracing::instrument(level = "debug", skip(self))]
1453     fn lower_fn_decl(
1454         &mut self,
1455         decl: &FnDecl,
1456         fn_node_id: Option<NodeId>,
1457         kind: FnDeclKind,
1458         make_ret_async: Option<NodeId>,
1459     ) -> &'hir hir::FnDecl<'hir> {
1460         let c_variadic = decl.c_variadic();
1461
1462         // Skip the `...` (`CVarArgs`) trailing arguments from the AST,
1463         // as they are not explicit in HIR/Ty function signatures.
1464         // (instead, the `c_variadic` flag is set to `true`)
1465         let mut inputs = &decl.inputs[..];
1466         if c_variadic {
1467             inputs = &inputs[..inputs.len() - 1];
1468         }
1469         let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {
1470             if fn_node_id.is_some() {
1471                 self.lower_ty_direct(&param.ty, ImplTraitContext::Universal)
1472             } else {
1473                 self.lower_ty_direct(
1474                     &param.ty,
1475                     ImplTraitContext::Disallowed(match kind {
1476                         FnDeclKind::Fn | FnDeclKind::Inherent => {
1477                             unreachable!("fn should allow in-band lifetimes")
1478                         }
1479                         FnDeclKind::ExternFn => ImplTraitPosition::ExternFnParam,
1480                         FnDeclKind::Closure => ImplTraitPosition::ClosureParam,
1481                         FnDeclKind::Pointer => ImplTraitPosition::PointerParam,
1482                         FnDeclKind::Trait => ImplTraitPosition::TraitParam,
1483                         FnDeclKind::Impl => ImplTraitPosition::ImplParam,
1484                     }),
1485                 )
1486             }
1487         }));
1488
1489         let output = if let Some(ret_id) = make_ret_async {
1490             self.lower_async_fn_ret_ty(
1491                 &decl.output,
1492                 fn_node_id.expect("`make_ret_async` but no `fn_def_id`"),
1493                 ret_id,
1494             )
1495         } else {
1496             match decl.output {
1497                 FnRetTy::Ty(ref ty) => {
1498                     let context = match fn_node_id {
1499                         Some(fn_node_id) if kind.impl_trait_return_allowed() => {
1500                             let fn_def_id = self.local_def_id(fn_node_id);
1501                             ImplTraitContext::ReturnPositionOpaqueTy {
1502                                 origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
1503                             }
1504                         }
1505                         _ => ImplTraitContext::Disallowed(match kind {
1506                             FnDeclKind::Fn | FnDeclKind::Inherent => {
1507                                 unreachable!("fn should allow in-band lifetimes")
1508                             }
1509                             FnDeclKind::ExternFn => ImplTraitPosition::ExternFnReturn,
1510                             FnDeclKind::Closure => ImplTraitPosition::ClosureReturn,
1511                             FnDeclKind::Pointer => ImplTraitPosition::PointerReturn,
1512                             FnDeclKind::Trait => ImplTraitPosition::TraitReturn,
1513                             FnDeclKind::Impl => ImplTraitPosition::ImplReturn,
1514                         }),
1515                     };
1516                     hir::FnRetTy::Return(self.lower_ty(ty, context))
1517                 }
1518                 FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(span)),
1519             }
1520         };
1521
1522         self.arena.alloc(hir::FnDecl {
1523             inputs,
1524             output,
1525             c_variadic,
1526             implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {
1527                 use BindingMode::{ByRef, ByValue};
1528                 let is_mutable_pat = matches!(
1529                     arg.pat.kind,
1530                     PatKind::Ident(ByValue(Mutability::Mut) | ByRef(Mutability::Mut), ..)
1531                 );
1532
1533                 match arg.ty.kind {
1534                     TyKind::ImplicitSelf if is_mutable_pat => hir::ImplicitSelfKind::Mut,
1535                     TyKind::ImplicitSelf => hir::ImplicitSelfKind::Imm,
1536                     // Given we are only considering `ImplicitSelf` types, we needn't consider
1537                     // the case where we have a mutable pattern to a reference as that would
1538                     // no longer be an `ImplicitSelf`.
1539                     TyKind::Rptr(_, ref mt)
1540                         if mt.ty.kind.is_implicit_self() && mt.mutbl == ast::Mutability::Mut =>
1541                     {
1542                         hir::ImplicitSelfKind::MutRef
1543                     }
1544                     TyKind::Rptr(_, ref mt) if mt.ty.kind.is_implicit_self() => {
1545                         hir::ImplicitSelfKind::ImmRef
1546                     }
1547                     _ => hir::ImplicitSelfKind::None,
1548                 }
1549             }),
1550         })
1551     }
1552
1553     // Transforms `-> T` for `async fn` into `-> OpaqueTy { .. }`
1554     // combined with the following definition of `OpaqueTy`:
1555     //
1556     //     type OpaqueTy<generics_from_parent_fn> = impl Future<Output = T>;
1557     //
1558     // `inputs`: lowered types of parameters to the function (used to collect lifetimes)
1559     // `output`: unlowered output type (`T` in `-> T`)
1560     // `fn_def_id`: `DefId` of the parent function (used to create child impl trait definition)
1561     // `opaque_ty_node_id`: `NodeId` of the opaque `impl Trait` type that should be created
1562     // `elided_lt_replacement`: replacement for elided lifetimes in the return type
1563     #[tracing::instrument(level = "debug", skip(self))]
1564     fn lower_async_fn_ret_ty(
1565         &mut self,
1566         output: &FnRetTy,
1567         fn_node_id: NodeId,
1568         opaque_ty_node_id: NodeId,
1569     ) -> hir::FnRetTy<'hir> {
1570         let span = output.span();
1571
1572         let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, span, None);
1573
1574         let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
1575         let fn_def_id = self.local_def_id(fn_node_id);
1576
1577         // When we create the opaque type for this async fn, it is going to have
1578         // to capture all the lifetimes involved in the signature (including in the
1579         // return type). This is done by introducing lifetime parameters for:
1580         //
1581         // - all the explicitly declared lifetimes from the impl and function itself;
1582         // - all the elided lifetimes in the fn arguments;
1583         // - all the elided lifetimes in the return type.
1584         //
1585         // So for example in this snippet:
1586         //
1587         // ```rust
1588         // impl<'a> Foo<'a> {
1589         //   async fn bar<'b>(&self, x: &'b Vec<f64>, y: &str) -> &u32 {
1590         //   //               ^ '0                       ^ '1     ^ '2
1591         //   // elided lifetimes used below
1592         //   }
1593         // }
1594         // ```
1595         //
1596         // we would create an opaque type like:
1597         //
1598         // ```
1599         // type Bar<'a, 'b, '0, '1, '2> = impl Future<Output = &'2 u32>;
1600         // ```
1601         //
1602         // and we would then desugar `bar` to the equivalent of:
1603         //
1604         // ```rust
1605         // impl<'a> Foo<'a> {
1606         //   fn bar<'b, '0, '1>(&'0 self, x: &'b Vec<f64>, y: &'1 str) -> Bar<'a, 'b, '0, '1, '_>
1607         // }
1608         // ```
1609         //
1610         // Note that the final parameter to `Bar` is `'_`, not `'2` --
1611         // this is because the elided lifetimes from the return type
1612         // should be figured out using the ordinary elision rules, and
1613         // this desugaring achieves that.
1614
1615         // Calculate all the lifetimes that should be captured
1616         // by the opaque type. This should include all in-scope
1617         // lifetime parameters, including those defined in-band.
1618
1619         let mut captures = FxHashMap::default();
1620
1621         let extra_lifetime_params = self.resolver.take_extra_lifetime_params(opaque_ty_node_id);
1622         debug!(?extra_lifetime_params);
1623         for (ident, outer_node_id, outer_res) in extra_lifetime_params {
1624             let Ident { name, span } = ident;
1625             let outer_def_id = self.local_def_id(outer_node_id);
1626             let inner_node_id = self.next_node_id();
1627
1628             // Add a definition for the in scope lifetime def.
1629             self.create_def(opaque_ty_def_id, inner_node_id, DefPathData::LifetimeNs(name));
1630
1631             let (p_name, inner_res) = match outer_res {
1632                 // Input lifetime like `'a`:
1633                 LifetimeRes::Param { param, .. } => {
1634                     (hir::ParamName::Plain(ident), LifetimeRes::Param { param, binder: fn_node_id })
1635                 }
1636                 // Input lifetime like `'1`:
1637                 LifetimeRes::Fresh { param, .. } => {
1638                     (hir::ParamName::Fresh, LifetimeRes::Fresh { param, binder: fn_node_id })
1639                 }
1640                 LifetimeRes::Static | LifetimeRes::Error => continue,
1641                 res => {
1642                     panic!("Unexpected lifetime resolution {:?} for {:?} at {:?}", res, ident, span)
1643                 }
1644             };
1645
1646             captures.insert(outer_def_id, (span, inner_node_id, p_name, inner_res));
1647         }
1648
1649         debug!(?captures);
1650
1651         self.with_hir_id_owner(opaque_ty_node_id, |this| {
1652             let future_bound =
1653                 this.while_capturing_lifetimes(opaque_ty_def_id, &mut captures, |this| {
1654                     // We have to be careful to get elision right here. The
1655                     // idea is that we create a lifetime parameter for each
1656                     // lifetime in the return type.  So, given a return type
1657                     // like `async fn foo(..) -> &[&u32]`, we lower to `impl
1658                     // Future<Output = &'1 [ &'2 u32 ]>`.
1659                     //
1660                     // Then, we will create `fn foo(..) -> Foo<'_, '_>`, and
1661                     // hence the elision takes place at the fn site.
1662                     this.lower_async_fn_output_type_to_future_bound(output, fn_def_id, span)
1663                 });
1664             debug!("lower_async_fn_ret_ty: future_bound={:#?}", future_bound);
1665             debug!("lower_async_fn_ret_ty: captures={:#?}", captures);
1666
1667             let generic_params =
1668                 this.arena.alloc_from_iter(captures.iter().map(|(_, &(span, p_id, p_name, _))| {
1669                     let hir_id = this.lower_node_id(p_id);
1670                     debug_assert_ne!(this.opt_local_def_id(p_id), None);
1671
1672                     let kind = if p_name.ident().name == kw::UnderscoreLifetime {
1673                         hir::LifetimeParamKind::Elided
1674                     } else {
1675                         hir::LifetimeParamKind::Explicit
1676                     };
1677
1678                     hir::GenericParam {
1679                         hir_id,
1680                         name: p_name,
1681                         span,
1682                         pure_wrt_drop: false,
1683                         kind: hir::GenericParamKind::Lifetime { kind },
1684                         colon_span: None,
1685                     }
1686                 }));
1687             debug!("lower_async_fn_ret_ty: generic_params={:#?}", generic_params);
1688
1689             let opaque_ty_item = hir::OpaqueTy {
1690                 generics: this.arena.alloc(hir::Generics {
1691                     params: generic_params,
1692                     predicates: &[],
1693                     has_where_clause_predicates: false,
1694                     where_clause_span: this.lower_span(span),
1695                     span: this.lower_span(span),
1696                 }),
1697                 bounds: arena_vec![this; future_bound],
1698                 origin: hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
1699             };
1700
1701             trace!("exist ty from async fn def id: {:#?}", opaque_ty_def_id);
1702             this.generate_opaque_type(opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span)
1703         });
1704
1705         // As documented above, we need to create the lifetime
1706         // arguments to our opaque type. Continuing with our example,
1707         // we're creating the type arguments for the return type:
1708         //
1709         // ```
1710         // Bar<'a, 'b, '0, '1, '_>
1711         // ```
1712         //
1713         // For the "input" lifetime parameters, we wish to create
1714         // references to the parameters themselves, including the
1715         // "implicit" ones created from parameter types (`'a`, `'b`,
1716         // '`0`, `'1`).
1717         //
1718         // For the "output" lifetime parameters, we just want to
1719         // generate `'_`.
1720         let generic_args =
1721             self.arena.alloc_from_iter(captures.into_iter().map(|(_, (span, _, p_name, res))| {
1722                 let id = self.next_node_id();
1723                 let ident = Ident::new(p_name.ident().name, span);
1724                 let l = self.new_named_lifetime_with_res(id, span, ident, res);
1725                 hir::GenericArg::Lifetime(l)
1726             }));
1727
1728         // Create the `Foo<...>` reference itself. Note that the `type
1729         // Foo = impl Trait` is, internally, created as a child of the
1730         // async fn, so the *type parameters* are inherited.  It's
1731         // only the lifetime parameters that we must supply.
1732         let opaque_ty_ref =
1733             hir::TyKind::OpaqueDef(hir::ItemId { def_id: opaque_ty_def_id }, generic_args);
1734         let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);
1735         hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
1736     }
1737
1738     /// Transforms `-> T` into `Future<Output = T>`.
1739     fn lower_async_fn_output_type_to_future_bound(
1740         &mut self,
1741         output: &FnRetTy,
1742         fn_def_id: LocalDefId,
1743         span: Span,
1744     ) -> hir::GenericBound<'hir> {
1745         // Compute the `T` in `Future<Output = T>` from the return type.
1746         let output_ty = match output {
1747             FnRetTy::Ty(ty) => {
1748                 // Not `OpaqueTyOrigin::AsyncFn`: that's only used for the
1749                 // `impl Future` opaque type that `async fn` implicitly
1750                 // generates.
1751                 let context = ImplTraitContext::ReturnPositionOpaqueTy {
1752                     origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
1753                 };
1754                 self.lower_ty(ty, context)
1755             }
1756             FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),
1757         };
1758
1759         // "<Output = T>"
1760         let future_args = self.arena.alloc(hir::GenericArgs {
1761             args: &[],
1762             bindings: arena_vec![self; self.output_ty_binding(span, output_ty)],
1763             parenthesized: false,
1764             span_ext: DUMMY_SP,
1765         });
1766
1767         hir::GenericBound::LangItemTrait(
1768             // ::std::future::Future<future_params>
1769             hir::LangItem::Future,
1770             self.lower_span(span),
1771             self.next_id(),
1772             future_args,
1773         )
1774     }
1775
1776     #[instrument(level = "trace", skip(self))]
1777     fn lower_param_bound(
1778         &mut self,
1779         tpb: &GenericBound,
1780         itctx: ImplTraitContext,
1781     ) -> hir::GenericBound<'hir> {
1782         match tpb {
1783             GenericBound::Trait(p, modifier) => hir::GenericBound::Trait(
1784                 self.lower_poly_trait_ref(p, itctx),
1785                 self.lower_trait_bound_modifier(*modifier),
1786             ),
1787             GenericBound::Outlives(lifetime) => {
1788                 hir::GenericBound::Outlives(self.lower_lifetime(lifetime))
1789             }
1790         }
1791     }
1792
1793     fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime {
1794         let span = self.lower_span(l.ident.span);
1795         let ident = self.lower_ident(l.ident);
1796         let res = self.resolver.get_lifetime_res(l.id).unwrap_or(LifetimeRes::Error);
1797         self.new_named_lifetime_with_res(l.id, span, ident, res)
1798     }
1799
1800     #[tracing::instrument(level = "debug", skip(self))]
1801     fn new_named_lifetime_with_res(
1802         &mut self,
1803         id: NodeId,
1804         span: Span,
1805         ident: Ident,
1806         res: LifetimeRes,
1807     ) -> hir::Lifetime {
1808         debug!(?self.captured_lifetimes);
1809         let name = match res {
1810             LifetimeRes::Param { mut param, binder } => {
1811                 debug_assert_ne!(ident.name, kw::UnderscoreLifetime);
1812                 let p_name = ParamName::Plain(ident);
1813                 if let Some(mut captured_lifetimes) = self.captured_lifetimes.take() {
1814                     if !captured_lifetimes.binders_to_ignore.contains(&binder) {
1815                         match captured_lifetimes.captures.entry(param) {
1816                             Entry::Occupied(o) => param = self.local_def_id(o.get().1),
1817                             Entry::Vacant(v) => {
1818                                 let p_id = self.next_node_id();
1819                                 let p_def_id = self.create_def(
1820                                     captured_lifetimes.parent_def_id,
1821                                     p_id,
1822                                     DefPathData::LifetimeNs(p_name.ident().name),
1823                                 );
1824
1825                                 v.insert((span, p_id, p_name, res));
1826                                 param = p_def_id;
1827                             }
1828                         }
1829                     }
1830
1831                     self.captured_lifetimes = Some(captured_lifetimes);
1832                 }
1833                 hir::LifetimeName::Param(param, p_name)
1834             }
1835             LifetimeRes::Fresh { param, binder } => {
1836                 debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
1837                 let mut param = self.local_def_id(param);
1838                 if let Some(mut captured_lifetimes) = self.captured_lifetimes.take() {
1839                     if !captured_lifetimes.binders_to_ignore.contains(&binder) {
1840                         match captured_lifetimes.captures.entry(param) {
1841                             Entry::Occupied(o) => param = self.local_def_id(o.get().1),
1842                             Entry::Vacant(v) => {
1843                                 let p_id = self.next_node_id();
1844                                 let p_def_id = self.create_def(
1845                                     captured_lifetimes.parent_def_id,
1846                                     p_id,
1847                                     DefPathData::LifetimeNs(kw::UnderscoreLifetime),
1848                                 );
1849
1850                                 v.insert((span, p_id, ParamName::Fresh, res));
1851                                 param = p_def_id;
1852                             }
1853                         }
1854                     }
1855
1856                     self.captured_lifetimes = Some(captured_lifetimes);
1857                 }
1858                 hir::LifetimeName::Param(param, ParamName::Fresh)
1859             }
1860             LifetimeRes::Anonymous { binder, elided } => {
1861                 let mut l_name = None;
1862                 if let Some(mut captured_lifetimes) = self.captured_lifetimes.take() {
1863                     if !captured_lifetimes.binders_to_ignore.contains(&binder) {
1864                         let p_id = self.next_node_id();
1865                         let p_def_id = self.create_def(
1866                             captured_lifetimes.parent_def_id,
1867                             p_id,
1868                             DefPathData::LifetimeNs(kw::UnderscoreLifetime),
1869                         );
1870                         captured_lifetimes
1871                             .captures
1872                             .insert(p_def_id, (span, p_id, ParamName::Fresh, res));
1873                         l_name = Some(hir::LifetimeName::Param(p_def_id, ParamName::Fresh));
1874                     }
1875                     self.captured_lifetimes = Some(captured_lifetimes);
1876                 };
1877                 l_name.unwrap_or(if elided {
1878                     hir::LifetimeName::Implicit
1879                 } else {
1880                     hir::LifetimeName::Underscore
1881                 })
1882             }
1883             LifetimeRes::Static => hir::LifetimeName::Static,
1884             LifetimeRes::Error => hir::LifetimeName::Error,
1885             res => panic!("Unexpected lifetime resolution {:?} for {:?} at {:?}", res, ident, span),
1886         };
1887         debug!(?self.captured_lifetimes);
1888         debug!(?name);
1889         hir::Lifetime { hir_id: self.lower_node_id(id), span: self.lower_span(span), name }
1890     }
1891
1892     fn lower_generic_params_mut<'s>(
1893         &'s mut self,
1894         params: &'s [GenericParam],
1895     ) -> impl Iterator<Item = hir::GenericParam<'hir>> + Captures<'a> + Captures<'s> {
1896         params.iter().map(move |param| self.lower_generic_param(param))
1897     }
1898
1899     fn lower_generic_params(&mut self, params: &[GenericParam]) -> &'hir [hir::GenericParam<'hir>] {
1900         self.arena.alloc_from_iter(self.lower_generic_params_mut(params))
1901     }
1902
1903     #[instrument(level = "trace", skip(self))]
1904     fn lower_generic_param(&mut self, param: &GenericParam) -> hir::GenericParam<'hir> {
1905         let (name, kind) = self.lower_generic_param_kind(param);
1906
1907         let hir_id = self.lower_node_id(param.id);
1908         self.lower_attrs(hir_id, &param.attrs);
1909         hir::GenericParam {
1910             hir_id,
1911             name,
1912             span: self.lower_span(param.span()),
1913             pure_wrt_drop: self.tcx.sess.contains_name(&param.attrs, sym::may_dangle),
1914             kind,
1915             colon_span: param.colon_span.map(|s| self.lower_span(s)),
1916         }
1917     }
1918
1919     fn lower_generic_param_kind(
1920         &mut self,
1921         param: &GenericParam,
1922     ) -> (hir::ParamName, hir::GenericParamKind<'hir>) {
1923         match param.kind {
1924             GenericParamKind::Lifetime => {
1925                 // AST resolution emitted an error on those parameters, so we lower them using
1926                 // `ParamName::Error`.
1927                 let param_name =
1928                     if let Some(LifetimeRes::Error) = self.resolver.get_lifetime_res(param.id) {
1929                         ParamName::Error
1930                     } else {
1931                         let ident = self.lower_ident(param.ident);
1932                         ParamName::Plain(ident)
1933                     };
1934                 let kind =
1935                     hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit };
1936
1937                 (param_name, kind)
1938             }
1939             GenericParamKind::Type { ref default, .. } => {
1940                 let kind = hir::GenericParamKind::Type {
1941                     default: default.as_ref().map(|x| {
1942                         self.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Type))
1943                     }),
1944                     synthetic: false,
1945                 };
1946
1947                 (hir::ParamName::Plain(self.lower_ident(param.ident)), kind)
1948             }
1949             GenericParamKind::Const { ref ty, kw_span: _, ref default } => {
1950                 let ty = self.lower_ty(&ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
1951                 let default = default.as_ref().map(|def| self.lower_anon_const(def));
1952                 (
1953                     hir::ParamName::Plain(self.lower_ident(param.ident)),
1954                     hir::GenericParamKind::Const { ty, default },
1955                 )
1956             }
1957         }
1958     }
1959
1960     fn lower_trait_ref(&mut self, p: &TraitRef, itctx: ImplTraitContext) -> hir::TraitRef<'hir> {
1961         let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx) {
1962             hir::QPath::Resolved(None, path) => path,
1963             qpath => panic!("lower_trait_ref: unexpected QPath `{:?}`", qpath),
1964         };
1965         hir::TraitRef { path, hir_ref_id: self.lower_node_id(p.ref_id) }
1966     }
1967
1968     #[tracing::instrument(level = "debug", skip(self))]
1969     fn lower_poly_trait_ref(
1970         &mut self,
1971         p: &PolyTraitRef,
1972         itctx: ImplTraitContext,
1973     ) -> hir::PolyTraitRef<'hir> {
1974         self.with_lifetime_binder(
1975             p.trait_ref.ref_id,
1976             &p.bound_generic_params,
1977             |this, bound_generic_params| {
1978                 let trait_ref = this.lower_trait_ref(&p.trait_ref, itctx);
1979                 hir::PolyTraitRef { bound_generic_params, trait_ref, span: this.lower_span(p.span) }
1980             },
1981         )
1982     }
1983
1984     fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> {
1985         hir::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl }
1986     }
1987
1988     fn lower_param_bounds(
1989         &mut self,
1990         bounds: &[GenericBound],
1991         itctx: ImplTraitContext,
1992     ) -> hir::GenericBounds<'hir> {
1993         self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, itctx))
1994     }
1995
1996     fn lower_param_bounds_mut<'s>(
1997         &'s mut self,
1998         bounds: &'s [GenericBound],
1999         itctx: ImplTraitContext,
2000     ) -> impl Iterator<Item = hir::GenericBound<'hir>> + Captures<'s> + Captures<'a> {
2001         bounds.iter().map(move |bound| self.lower_param_bound(bound, itctx))
2002     }
2003
2004     fn lower_generic_and_bounds(
2005         &mut self,
2006         node_id: NodeId,
2007         span: Span,
2008         ident: Ident,
2009         bounds: &[GenericBound],
2010     ) -> (hir::GenericParam<'hir>, Option<hir::WherePredicate<'hir>>, hir::TyKind<'hir>) {
2011         // Add a definition for the in-band `Param`.
2012         let def_id = self.local_def_id(node_id);
2013
2014         let hir_bounds = self.lower_param_bounds(bounds, ImplTraitContext::Universal);
2015         // Set the name to `impl Bound1 + Bound2`.
2016         let param = hir::GenericParam {
2017             hir_id: self.lower_node_id(node_id),
2018             name: ParamName::Plain(self.lower_ident(ident)),
2019             pure_wrt_drop: false,
2020             span: self.lower_span(span),
2021             kind: hir::GenericParamKind::Type { default: None, synthetic: true },
2022             colon_span: None,
2023         };
2024
2025         let preds = self.lower_generic_bound_predicate(
2026             ident,
2027             node_id,
2028             &GenericParamKind::Type { default: None },
2029             hir_bounds,
2030             hir::PredicateOrigin::ImplTrait,
2031         );
2032
2033         let ty = hir::TyKind::Path(hir::QPath::Resolved(
2034             None,
2035             self.arena.alloc(hir::Path {
2036                 span: self.lower_span(span),
2037                 res: Res::Def(DefKind::TyParam, def_id.to_def_id()),
2038                 segments: arena_vec![self; hir::PathSegment::from_ident(self.lower_ident(ident))],
2039             }),
2040         ));
2041
2042         (param, preds, ty)
2043     }
2044
2045     /// Lowers a block directly to an expression, presuming that it
2046     /// has no attributes and is not targeted by a `break`.
2047     fn lower_block_expr(&mut self, b: &Block) -> hir::Expr<'hir> {
2048         let block = self.lower_block(b, false);
2049         self.expr_block(block, AttrVec::new())
2050     }
2051
2052     fn lower_array_length(&mut self, c: &AnonConst) -> hir::ArrayLen {
2053         match c.value.kind {
2054             ExprKind::Underscore => {
2055                 if self.tcx.features().generic_arg_infer {
2056                     hir::ArrayLen::Infer(self.lower_node_id(c.id), c.value.span)
2057                 } else {
2058                     feature_err(
2059                         &self.tcx.sess.parse_sess,
2060                         sym::generic_arg_infer,
2061                         c.value.span,
2062                         "using `_` for array lengths is unstable",
2063                     )
2064                     .emit();
2065                     hir::ArrayLen::Body(self.lower_anon_const(c))
2066                 }
2067             }
2068             _ => hir::ArrayLen::Body(self.lower_anon_const(c)),
2069         }
2070     }
2071
2072     fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst {
2073         self.with_new_scopes(|this| hir::AnonConst {
2074             hir_id: this.lower_node_id(c.id),
2075             body: this.lower_const_body(c.value.span, Some(&c.value)),
2076         })
2077     }
2078
2079     fn lower_unsafe_source(&mut self, u: UnsafeSource) -> hir::UnsafeSource {
2080         match u {
2081             CompilerGenerated => hir::UnsafeSource::CompilerGenerated,
2082             UserProvided => hir::UnsafeSource::UserProvided,
2083         }
2084     }
2085
2086     fn lower_trait_bound_modifier(&mut self, f: TraitBoundModifier) -> hir::TraitBoundModifier {
2087         match f {
2088             TraitBoundModifier::None => hir::TraitBoundModifier::None,
2089             TraitBoundModifier::MaybeConst => hir::TraitBoundModifier::MaybeConst,
2090
2091             // `MaybeConstMaybe` will cause an error during AST validation, but we need to pick a
2092             // placeholder for compilation to proceed.
2093             TraitBoundModifier::MaybeConstMaybe | TraitBoundModifier::Maybe => {
2094                 hir::TraitBoundModifier::Maybe
2095             }
2096         }
2097     }
2098
2099     // Helper methods for building HIR.
2100
2101     fn stmt(&mut self, span: Span, kind: hir::StmtKind<'hir>) -> hir::Stmt<'hir> {
2102         hir::Stmt { span: self.lower_span(span), kind, hir_id: self.next_id() }
2103     }
2104
2105     fn stmt_expr(&mut self, span: Span, expr: hir::Expr<'hir>) -> hir::Stmt<'hir> {
2106         self.stmt(span, hir::StmtKind::Expr(self.arena.alloc(expr)))
2107     }
2108
2109     fn stmt_let_pat(
2110         &mut self,
2111         attrs: Option<&'hir [Attribute]>,
2112         span: Span,
2113         init: Option<&'hir hir::Expr<'hir>>,
2114         pat: &'hir hir::Pat<'hir>,
2115         source: hir::LocalSource,
2116     ) -> hir::Stmt<'hir> {
2117         let hir_id = self.next_id();
2118         if let Some(a) = attrs {
2119             debug_assert!(!a.is_empty());
2120             self.attrs.insert(hir_id.local_id, a);
2121         }
2122         let local = hir::Local { hir_id, init, pat, source, span: self.lower_span(span), ty: None };
2123         self.stmt(span, hir::StmtKind::Local(self.arena.alloc(local)))
2124     }
2125
2126     fn block_expr(&mut self, expr: &'hir hir::Expr<'hir>) -> &'hir hir::Block<'hir> {
2127         self.block_all(expr.span, &[], Some(expr))
2128     }
2129
2130     fn block_all(
2131         &mut self,
2132         span: Span,
2133         stmts: &'hir [hir::Stmt<'hir>],
2134         expr: Option<&'hir hir::Expr<'hir>>,
2135     ) -> &'hir hir::Block<'hir> {
2136         let blk = hir::Block {
2137             stmts,
2138             expr,
2139             hir_id: self.next_id(),
2140             rules: hir::BlockCheckMode::DefaultBlock,
2141             span: self.lower_span(span),
2142             targeted_by_break: false,
2143         };
2144         self.arena.alloc(blk)
2145     }
2146
2147     fn pat_cf_continue(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2148         let field = self.single_pat_field(span, pat);
2149         self.pat_lang_item_variant(span, hir::LangItem::ControlFlowContinue, field, None)
2150     }
2151
2152     fn pat_cf_break(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2153         let field = self.single_pat_field(span, pat);
2154         self.pat_lang_item_variant(span, hir::LangItem::ControlFlowBreak, field, None)
2155     }
2156
2157     fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2158         let field = self.single_pat_field(span, pat);
2159         self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field, None)
2160     }
2161
2162     fn pat_none(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
2163         self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[], None)
2164     }
2165
2166     fn single_pat_field(
2167         &mut self,
2168         span: Span,
2169         pat: &'hir hir::Pat<'hir>,
2170     ) -> &'hir [hir::PatField<'hir>] {
2171         let field = hir::PatField {
2172             hir_id: self.next_id(),
2173             ident: Ident::new(sym::integer(0), self.lower_span(span)),
2174             is_shorthand: false,
2175             pat,
2176             span: self.lower_span(span),
2177         };
2178         arena_vec![self; field]
2179     }
2180
2181     fn pat_lang_item_variant(
2182         &mut self,
2183         span: Span,
2184         lang_item: hir::LangItem,
2185         fields: &'hir [hir::PatField<'hir>],
2186         hir_id: Option<hir::HirId>,
2187     ) -> &'hir hir::Pat<'hir> {
2188         let qpath = hir::QPath::LangItem(lang_item, self.lower_span(span), hir_id);
2189         self.pat(span, hir::PatKind::Struct(qpath, fields, false))
2190     }
2191
2192     fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, hir::HirId) {
2193         self.pat_ident_binding_mode(span, ident, hir::BindingAnnotation::Unannotated)
2194     }
2195
2196     fn pat_ident_mut(&mut self, span: Span, ident: Ident) -> (hir::Pat<'hir>, hir::HirId) {
2197         self.pat_ident_binding_mode_mut(span, ident, hir::BindingAnnotation::Unannotated)
2198     }
2199
2200     fn pat_ident_binding_mode(
2201         &mut self,
2202         span: Span,
2203         ident: Ident,
2204         bm: hir::BindingAnnotation,
2205     ) -> (&'hir hir::Pat<'hir>, hir::HirId) {
2206         let (pat, hir_id) = self.pat_ident_binding_mode_mut(span, ident, bm);
2207         (self.arena.alloc(pat), hir_id)
2208     }
2209
2210     fn pat_ident_binding_mode_mut(
2211         &mut self,
2212         span: Span,
2213         ident: Ident,
2214         bm: hir::BindingAnnotation,
2215     ) -> (hir::Pat<'hir>, hir::HirId) {
2216         let hir_id = self.next_id();
2217
2218         (
2219             hir::Pat {
2220                 hir_id,
2221                 kind: hir::PatKind::Binding(bm, hir_id, self.lower_ident(ident), None),
2222                 span: self.lower_span(span),
2223                 default_binding_modes: true,
2224             },
2225             hir_id,
2226         )
2227     }
2228
2229     fn pat(&mut self, span: Span, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> {
2230         self.arena.alloc(hir::Pat {
2231             hir_id: self.next_id(),
2232             kind,
2233             span: self.lower_span(span),
2234             default_binding_modes: true,
2235         })
2236     }
2237
2238     fn pat_without_dbm(&mut self, span: Span, kind: hir::PatKind<'hir>) -> hir::Pat<'hir> {
2239         hir::Pat {
2240             hir_id: self.next_id(),
2241             kind,
2242             span: self.lower_span(span),
2243             default_binding_modes: false,
2244         }
2245     }
2246
2247     fn ty_path(
2248         &mut self,
2249         mut hir_id: hir::HirId,
2250         span: Span,
2251         qpath: hir::QPath<'hir>,
2252     ) -> hir::Ty<'hir> {
2253         let kind = match qpath {
2254             hir::QPath::Resolved(None, path) => {
2255                 // Turn trait object paths into `TyKind::TraitObject` instead.
2256                 match path.res {
2257                     Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
2258                         let principal = hir::PolyTraitRef {
2259                             bound_generic_params: &[],
2260                             trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
2261                             span: self.lower_span(span),
2262                         };
2263
2264                         // The original ID is taken by the `PolyTraitRef`,
2265                         // so the `Ty` itself needs a different one.
2266                         hir_id = self.next_id();
2267                         hir::TyKind::TraitObject(
2268                             arena_vec![self; principal],
2269                             self.elided_dyn_bound(span),
2270                             TraitObjectSyntax::None,
2271                         )
2272                     }
2273                     _ => hir::TyKind::Path(hir::QPath::Resolved(None, path)),
2274                 }
2275             }
2276             _ => hir::TyKind::Path(qpath),
2277         };
2278
2279         hir::Ty { hir_id, kind, span: self.lower_span(span) }
2280     }
2281
2282     /// Invoked to create the lifetime argument(s) for an elided trait object
2283     /// bound, like the bound in `Box<dyn Debug>`. This method is not invoked
2284     /// when the bound is written, even if it is written with `'_` like in
2285     /// `Box<dyn Debug + '_>`. In those cases, `lower_lifetime` is invoked.
2286     fn elided_dyn_bound(&mut self, span: Span) -> hir::Lifetime {
2287         let r = hir::Lifetime {
2288             hir_id: self.next_id(),
2289             span: self.lower_span(span),
2290             name: hir::LifetimeName::ImplicitObjectLifetimeDefault,
2291         };
2292         debug!("elided_dyn_bound: r={:?}", r);
2293         r
2294     }
2295 }
2296
2297 /// Helper struct for delayed construction of GenericArgs.
2298 struct GenericArgsCtor<'hir> {
2299     args: SmallVec<[hir::GenericArg<'hir>; 4]>,
2300     bindings: &'hir [hir::TypeBinding<'hir>],
2301     parenthesized: bool,
2302     span: Span,
2303 }
2304
2305 impl<'hir> GenericArgsCtor<'hir> {
2306     fn is_empty(&self) -> bool {
2307         self.args.is_empty() && self.bindings.is_empty() && !self.parenthesized
2308     }
2309
2310     fn into_generic_args(self, this: &LoweringContext<'_, 'hir>) -> &'hir hir::GenericArgs<'hir> {
2311         let ga = hir::GenericArgs {
2312             args: this.arena.alloc_from_iter(self.args),
2313             bindings: self.bindings,
2314             parenthesized: self.parenthesized,
2315             span_ext: this.lower_span(self.span),
2316         };
2317         this.arena.alloc(ga)
2318     }
2319 }