]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_ast_lowering/src/lib.rs
Auto merge of #99182 - RalfJung:mitigate-uninit, r=scottmcm
[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 #![cfg_attr(bootstrap, 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.unstable_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.unstable_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         // Check whether we should interpret this as a bare trait object.
1163         // This check mirrors the one in late resolution.  We only introduce this special case in
1164         // the rare occurence we need to lower `Fresh` anonymous lifetimes.
1165         // The other cases when a qpath should be opportunistically made a trait object are handled
1166         // by `ty_path`.
1167         if qself.is_none()
1168             && let Some(partial_res) = self.resolver.get_partial_res(t.id)
1169             && partial_res.unresolved_segments() == 0
1170             && let Res::Def(DefKind::Trait | DefKind::TraitAlias, _) = partial_res.base_res()
1171         {
1172             let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
1173                 let bound = this.lower_poly_trait_ref(
1174                     &PolyTraitRef {
1175                         bound_generic_params: vec![],
1176                         trait_ref: TraitRef { path: path.clone(), ref_id: t.id },
1177                         span: t.span
1178                     },
1179                     itctx,
1180                 );
1181                 let bounds = this.arena.alloc_from_iter([bound]);
1182                 let lifetime_bound = this.elided_dyn_bound(t.span);
1183                 (bounds, lifetime_bound)
1184             });
1185             let kind = hir::TyKind::TraitObject(bounds, lifetime_bound, TraitObjectSyntax::None);
1186             return hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.next_id() };
1187         }
1188
1189         let id = self.lower_node_id(t.id);
1190         let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx);
1191         self.ty_path(id, t.span, qpath)
1192     }
1193
1194     fn ty(&mut self, span: Span, kind: hir::TyKind<'hir>) -> hir::Ty<'hir> {
1195         hir::Ty { hir_id: self.next_id(), kind, span: self.lower_span(span) }
1196     }
1197
1198     fn ty_tup(&mut self, span: Span, tys: &'hir [hir::Ty<'hir>]) -> hir::Ty<'hir> {
1199         self.ty(span, hir::TyKind::Tup(tys))
1200     }
1201
1202     fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
1203         let kind = match t.kind {
1204             TyKind::Infer => hir::TyKind::Infer,
1205             TyKind::Err => hir::TyKind::Err,
1206             TyKind::Slice(ref ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
1207             TyKind::Ptr(ref mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
1208             TyKind::Rptr(ref region, ref mt) => {
1209                 let region = region.unwrap_or_else(|| {
1210                     let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) =
1211                         self.resolver.get_lifetime_res(t.id)
1212                     {
1213                         debug_assert_eq!(start.plus(1), end);
1214                         start
1215                     } else {
1216                         self.next_node_id()
1217                     };
1218                     let span = self.tcx.sess.source_map().next_point(t.span.shrink_to_lo());
1219                     Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id }
1220                 });
1221                 let lifetime = self.lower_lifetime(&region);
1222                 hir::TyKind::Rptr(lifetime, self.lower_mt(mt, itctx))
1223             }
1224             TyKind::BareFn(ref f) => {
1225                 self.with_lifetime_binder(t.id, &f.generic_params, |this, generic_params| {
1226                     hir::TyKind::BareFn(this.arena.alloc(hir::BareFnTy {
1227                         generic_params,
1228                         unsafety: this.lower_unsafety(f.unsafety),
1229                         abi: this.lower_extern(f.ext),
1230                         decl: this.lower_fn_decl(&f.decl, None, FnDeclKind::Pointer, None),
1231                         param_names: this.lower_fn_params_to_names(&f.decl),
1232                     }))
1233                 })
1234             }
1235             TyKind::Never => hir::TyKind::Never,
1236             TyKind::Tup(ref tys) => hir::TyKind::Tup(
1237                 self.arena.alloc_from_iter(tys.iter().map(|ty| self.lower_ty_direct(ty, itctx))),
1238             ),
1239             TyKind::Paren(ref ty) => {
1240                 return self.lower_ty_direct(ty, itctx);
1241             }
1242             TyKind::Path(ref qself, ref path) => {
1243                 return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx);
1244             }
1245             TyKind::ImplicitSelf => {
1246                 let res = self.expect_full_res(t.id);
1247                 let res = self.lower_res(res);
1248                 hir::TyKind::Path(hir::QPath::Resolved(
1249                     None,
1250                     self.arena.alloc(hir::Path {
1251                         res,
1252                         segments: arena_vec![self; hir::PathSegment::from_ident(
1253                             Ident::with_dummy_span(kw::SelfUpper)
1254                         )],
1255                         span: self.lower_span(t.span),
1256                     }),
1257                 ))
1258             }
1259             TyKind::Array(ref ty, ref length) => {
1260                 hir::TyKind::Array(self.lower_ty(ty, itctx), self.lower_array_length(length))
1261             }
1262             TyKind::Typeof(ref expr) => hir::TyKind::Typeof(self.lower_anon_const(expr)),
1263             TyKind::TraitObject(ref bounds, kind) => {
1264                 let mut lifetime_bound = None;
1265                 let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
1266                     let bounds =
1267                         this.arena.alloc_from_iter(bounds.iter().filter_map(
1268                             |bound| match *bound {
1269                                 GenericBound::Trait(
1270                                     ref ty,
1271                                     TraitBoundModifier::None | TraitBoundModifier::MaybeConst,
1272                                 ) => Some(this.lower_poly_trait_ref(ty, itctx)),
1273                                 // `~const ?Bound` will cause an error during AST validation
1274                                 // anyways, so treat it like `?Bound` as compilation proceeds.
1275                                 GenericBound::Trait(
1276                                     _,
1277                                     TraitBoundModifier::Maybe | TraitBoundModifier::MaybeConstMaybe,
1278                                 ) => None,
1279                                 GenericBound::Outlives(ref lifetime) => {
1280                                     if lifetime_bound.is_none() {
1281                                         lifetime_bound = Some(this.lower_lifetime(lifetime));
1282                                     }
1283                                     None
1284                                 }
1285                             },
1286                         ));
1287                     let lifetime_bound =
1288                         lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));
1289                     (bounds, lifetime_bound)
1290                 });
1291                 hir::TyKind::TraitObject(bounds, lifetime_bound, kind)
1292             }
1293             TyKind::ImplTrait(def_node_id, ref bounds) => {
1294                 let span = t.span;
1295                 match itctx {
1296                     ImplTraitContext::ReturnPositionOpaqueTy { origin } => self
1297                         .lower_opaque_impl_trait(span, origin, def_node_id, |this| {
1298                             this.lower_param_bounds(bounds, itctx)
1299                         }),
1300                     ImplTraitContext::TypeAliasesOpaqueTy => {
1301                         let nested_itctx = ImplTraitContext::TypeAliasesOpaqueTy;
1302                         self.lower_opaque_impl_trait(
1303                             span,
1304                             hir::OpaqueTyOrigin::TyAlias,
1305                             def_node_id,
1306                             |this| this.lower_param_bounds(bounds, nested_itctx),
1307                         )
1308                     }
1309                     ImplTraitContext::Universal => {
1310                         let span = t.span;
1311                         let ident = Ident::from_str_and_span(&pprust::ty_to_string(t), span);
1312                         let (param, bounds, path) =
1313                             self.lower_generic_and_bounds(def_node_id, span, ident, bounds);
1314                         self.impl_trait_defs.push(param);
1315                         if let Some(bounds) = bounds {
1316                             self.impl_trait_bounds.push(bounds);
1317                         }
1318                         path
1319                     }
1320                     ImplTraitContext::Disallowed(position) => {
1321                         let mut err = struct_span_err!(
1322                             self.tcx.sess,
1323                             t.span,
1324                             E0562,
1325                             "`impl Trait` only allowed in function and inherent method return types, not in {}",
1326                             position
1327                         );
1328                         err.emit();
1329                         hir::TyKind::Err
1330                     }
1331                 }
1332             }
1333             TyKind::MacCall(_) => panic!("`TyKind::MacCall` should have been expanded by now"),
1334             TyKind::CVarArgs => {
1335                 self.tcx.sess.delay_span_bug(
1336                     t.span,
1337                     "`TyKind::CVarArgs` should have been handled elsewhere",
1338                 );
1339                 hir::TyKind::Err
1340             }
1341         };
1342
1343         hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.lower_node_id(t.id) }
1344     }
1345
1346     #[tracing::instrument(level = "debug", skip(self, lower_bounds))]
1347     fn lower_opaque_impl_trait(
1348         &mut self,
1349         span: Span,
1350         origin: hir::OpaqueTyOrigin,
1351         opaque_ty_node_id: NodeId,
1352         lower_bounds: impl FnOnce(&mut Self) -> hir::GenericBounds<'hir>,
1353     ) -> hir::TyKind<'hir> {
1354         // Make sure we know that some funky desugaring has been going on here.
1355         // This is a first: there is code in other places like for loop
1356         // desugaring that explicitly states that we don't want to track that.
1357         // Not tracking it makes lints in rustc and clippy very fragile, as
1358         // frequently opened issues show.
1359         let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
1360
1361         let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
1362
1363         let mut collected_lifetimes = FxHashMap::default();
1364         self.with_hir_id_owner(opaque_ty_node_id, |lctx| {
1365             let hir_bounds = if origin == hir::OpaqueTyOrigin::TyAlias {
1366                 lower_bounds(lctx)
1367             } else {
1368                 lctx.while_capturing_lifetimes(
1369                     opaque_ty_def_id,
1370                     &mut collected_lifetimes,
1371                     lower_bounds,
1372                 )
1373             };
1374             debug!(?collected_lifetimes);
1375
1376             let lifetime_defs = lctx.arena.alloc_from_iter(collected_lifetimes.iter().map(
1377                 |(_, &(span, p_id, p_name, _))| {
1378                     let hir_id = lctx.lower_node_id(p_id);
1379                     debug_assert_ne!(lctx.opt_local_def_id(p_id), None);
1380
1381                     let kind = if p_name.ident().name == kw::UnderscoreLifetime {
1382                         hir::LifetimeParamKind::Elided
1383                     } else {
1384                         hir::LifetimeParamKind::Explicit
1385                     };
1386
1387                     hir::GenericParam {
1388                         hir_id,
1389                         name: p_name,
1390                         span,
1391                         pure_wrt_drop: false,
1392                         kind: hir::GenericParamKind::Lifetime { kind },
1393                         colon_span: None,
1394                     }
1395                 },
1396             ));
1397
1398             debug!("lower_opaque_impl_trait: lifetime_defs={:#?}", lifetime_defs);
1399
1400             let opaque_ty_item = hir::OpaqueTy {
1401                 generics: self.arena.alloc(hir::Generics {
1402                     params: lifetime_defs,
1403                     predicates: &[],
1404                     has_where_clause_predicates: false,
1405                     where_clause_span: lctx.lower_span(span),
1406                     span: lctx.lower_span(span),
1407                 }),
1408                 bounds: hir_bounds,
1409                 origin,
1410             };
1411
1412             trace!("lower_opaque_impl_trait: {:#?}", opaque_ty_def_id);
1413             lctx.generate_opaque_type(opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span)
1414         });
1415
1416         let lifetimes = self.arena.alloc_from_iter(collected_lifetimes.into_iter().map(
1417             |(_, (span, _, p_name, res))| {
1418                 let id = self.next_node_id();
1419                 let ident = Ident::new(p_name.ident().name, span);
1420                 let l = self.new_named_lifetime_with_res(id, span, ident, res);
1421                 hir::GenericArg::Lifetime(l)
1422             },
1423         ));
1424
1425         debug!("lower_opaque_impl_trait: lifetimes={:#?}", lifetimes);
1426
1427         // `impl Trait` now just becomes `Foo<'a, 'b, ..>`.
1428         hir::TyKind::OpaqueDef(hir::ItemId { def_id: opaque_ty_def_id }, lifetimes)
1429     }
1430
1431     /// Registers a new opaque type with the proper `NodeId`s and
1432     /// returns the lowered node-ID for the opaque type.
1433     fn generate_opaque_type(
1434         &mut self,
1435         opaque_ty_id: LocalDefId,
1436         opaque_ty_item: hir::OpaqueTy<'hir>,
1437         span: Span,
1438         opaque_ty_span: Span,
1439     ) -> hir::OwnerNode<'hir> {
1440         let opaque_ty_item_kind = hir::ItemKind::OpaqueTy(opaque_ty_item);
1441         // Generate an `type Foo = impl Trait;` declaration.
1442         trace!("registering opaque type with id {:#?}", opaque_ty_id);
1443         let opaque_ty_item = hir::Item {
1444             def_id: opaque_ty_id,
1445             ident: Ident::empty(),
1446             kind: opaque_ty_item_kind,
1447             vis_span: self.lower_span(span.shrink_to_lo()),
1448             span: self.lower_span(opaque_ty_span),
1449         };
1450         hir::OwnerNode::Item(self.arena.alloc(opaque_ty_item))
1451     }
1452
1453     fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Ident] {
1454         // Skip the `...` (`CVarArgs`) trailing arguments from the AST,
1455         // as they are not explicit in HIR/Ty function signatures.
1456         // (instead, the `c_variadic` flag is set to `true`)
1457         let mut inputs = &decl.inputs[..];
1458         if decl.c_variadic() {
1459             inputs = &inputs[..inputs.len() - 1];
1460         }
1461         self.arena.alloc_from_iter(inputs.iter().map(|param| match param.pat.kind {
1462             PatKind::Ident(_, ident, _) => self.lower_ident(ident),
1463             _ => Ident::new(kw::Empty, self.lower_span(param.pat.span)),
1464         }))
1465     }
1466
1467     // Lowers a function declaration.
1468     //
1469     // `decl`: the unlowered (AST) function declaration.
1470     // `fn_def_id`: if `Some`, impl Trait arguments are lowered into generic parameters on the
1471     //      given DefId, otherwise impl Trait is disallowed. Must be `Some` if
1472     //      `make_ret_async` is also `Some`.
1473     // `impl_trait_return_allow`: determines whether `impl Trait` can be used in return position.
1474     //      This guards against trait declarations and implementations where `impl Trait` is
1475     //      disallowed.
1476     // `make_ret_async`: if `Some`, converts `-> T` into `-> impl Future<Output = T>` in the
1477     //      return type. This is used for `async fn` declarations. The `NodeId` is the ID of the
1478     //      return type `impl Trait` item.
1479     #[tracing::instrument(level = "debug", skip(self))]
1480     fn lower_fn_decl(
1481         &mut self,
1482         decl: &FnDecl,
1483         fn_node_id: Option<NodeId>,
1484         kind: FnDeclKind,
1485         make_ret_async: Option<NodeId>,
1486     ) -> &'hir hir::FnDecl<'hir> {
1487         let c_variadic = decl.c_variadic();
1488
1489         // Skip the `...` (`CVarArgs`) trailing arguments from the AST,
1490         // as they are not explicit in HIR/Ty function signatures.
1491         // (instead, the `c_variadic` flag is set to `true`)
1492         let mut inputs = &decl.inputs[..];
1493         if c_variadic {
1494             inputs = &inputs[..inputs.len() - 1];
1495         }
1496         let inputs = self.arena.alloc_from_iter(inputs.iter().map(|param| {
1497             if fn_node_id.is_some() {
1498                 self.lower_ty_direct(&param.ty, ImplTraitContext::Universal)
1499             } else {
1500                 self.lower_ty_direct(
1501                     &param.ty,
1502                     ImplTraitContext::Disallowed(match kind {
1503                         FnDeclKind::Fn | FnDeclKind::Inherent => {
1504                             unreachable!("fn should allow in-band lifetimes")
1505                         }
1506                         FnDeclKind::ExternFn => ImplTraitPosition::ExternFnParam,
1507                         FnDeclKind::Closure => ImplTraitPosition::ClosureParam,
1508                         FnDeclKind::Pointer => ImplTraitPosition::PointerParam,
1509                         FnDeclKind::Trait => ImplTraitPosition::TraitParam,
1510                         FnDeclKind::Impl => ImplTraitPosition::ImplParam,
1511                     }),
1512                 )
1513             }
1514         }));
1515
1516         let output = if let Some(ret_id) = make_ret_async {
1517             self.lower_async_fn_ret_ty(
1518                 &decl.output,
1519                 fn_node_id.expect("`make_ret_async` but no `fn_def_id`"),
1520                 ret_id,
1521             )
1522         } else {
1523             match decl.output {
1524                 FnRetTy::Ty(ref ty) => {
1525                     let context = match fn_node_id {
1526                         Some(fn_node_id) if kind.impl_trait_return_allowed() => {
1527                             let fn_def_id = self.local_def_id(fn_node_id);
1528                             ImplTraitContext::ReturnPositionOpaqueTy {
1529                                 origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
1530                             }
1531                         }
1532                         _ => ImplTraitContext::Disallowed(match kind {
1533                             FnDeclKind::Fn | FnDeclKind::Inherent => {
1534                                 unreachable!("fn should allow in-band lifetimes")
1535                             }
1536                             FnDeclKind::ExternFn => ImplTraitPosition::ExternFnReturn,
1537                             FnDeclKind::Closure => ImplTraitPosition::ClosureReturn,
1538                             FnDeclKind::Pointer => ImplTraitPosition::PointerReturn,
1539                             FnDeclKind::Trait => ImplTraitPosition::TraitReturn,
1540                             FnDeclKind::Impl => ImplTraitPosition::ImplReturn,
1541                         }),
1542                     };
1543                     hir::FnRetTy::Return(self.lower_ty(ty, context))
1544                 }
1545                 FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(span)),
1546             }
1547         };
1548
1549         self.arena.alloc(hir::FnDecl {
1550             inputs,
1551             output,
1552             c_variadic,
1553             implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {
1554                 use BindingMode::{ByRef, ByValue};
1555                 let is_mutable_pat = matches!(
1556                     arg.pat.kind,
1557                     PatKind::Ident(ByValue(Mutability::Mut) | ByRef(Mutability::Mut), ..)
1558                 );
1559
1560                 match arg.ty.kind {
1561                     TyKind::ImplicitSelf if is_mutable_pat => hir::ImplicitSelfKind::Mut,
1562                     TyKind::ImplicitSelf => hir::ImplicitSelfKind::Imm,
1563                     // Given we are only considering `ImplicitSelf` types, we needn't consider
1564                     // the case where we have a mutable pattern to a reference as that would
1565                     // no longer be an `ImplicitSelf`.
1566                     TyKind::Rptr(_, ref mt)
1567                         if mt.ty.kind.is_implicit_self() && mt.mutbl == ast::Mutability::Mut =>
1568                     {
1569                         hir::ImplicitSelfKind::MutRef
1570                     }
1571                     TyKind::Rptr(_, ref mt) if mt.ty.kind.is_implicit_self() => {
1572                         hir::ImplicitSelfKind::ImmRef
1573                     }
1574                     _ => hir::ImplicitSelfKind::None,
1575                 }
1576             }),
1577         })
1578     }
1579
1580     // Transforms `-> T` for `async fn` into `-> OpaqueTy { .. }`
1581     // combined with the following definition of `OpaqueTy`:
1582     //
1583     //     type OpaqueTy<generics_from_parent_fn> = impl Future<Output = T>;
1584     //
1585     // `inputs`: lowered types of parameters to the function (used to collect lifetimes)
1586     // `output`: unlowered output type (`T` in `-> T`)
1587     // `fn_def_id`: `DefId` of the parent function (used to create child impl trait definition)
1588     // `opaque_ty_node_id`: `NodeId` of the opaque `impl Trait` type that should be created
1589     // `elided_lt_replacement`: replacement for elided lifetimes in the return type
1590     #[tracing::instrument(level = "debug", skip(self))]
1591     fn lower_async_fn_ret_ty(
1592         &mut self,
1593         output: &FnRetTy,
1594         fn_node_id: NodeId,
1595         opaque_ty_node_id: NodeId,
1596     ) -> hir::FnRetTy<'hir> {
1597         let span = output.span();
1598
1599         let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, span, None);
1600
1601         let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
1602         let fn_def_id = self.local_def_id(fn_node_id);
1603
1604         // When we create the opaque type for this async fn, it is going to have
1605         // to capture all the lifetimes involved in the signature (including in the
1606         // return type). This is done by introducing lifetime parameters for:
1607         //
1608         // - all the explicitly declared lifetimes from the impl and function itself;
1609         // - all the elided lifetimes in the fn arguments;
1610         // - all the elided lifetimes in the return type.
1611         //
1612         // So for example in this snippet:
1613         //
1614         // ```rust
1615         // impl<'a> Foo<'a> {
1616         //   async fn bar<'b>(&self, x: &'b Vec<f64>, y: &str) -> &u32 {
1617         //   //               ^ '0                       ^ '1     ^ '2
1618         //   // elided lifetimes used below
1619         //   }
1620         // }
1621         // ```
1622         //
1623         // we would create an opaque type like:
1624         //
1625         // ```
1626         // type Bar<'a, 'b, '0, '1, '2> = impl Future<Output = &'2 u32>;
1627         // ```
1628         //
1629         // and we would then desugar `bar` to the equivalent of:
1630         //
1631         // ```rust
1632         // impl<'a> Foo<'a> {
1633         //   fn bar<'b, '0, '1>(&'0 self, x: &'b Vec<f64>, y: &'1 str) -> Bar<'a, 'b, '0, '1, '_>
1634         // }
1635         // ```
1636         //
1637         // Note that the final parameter to `Bar` is `'_`, not `'2` --
1638         // this is because the elided lifetimes from the return type
1639         // should be figured out using the ordinary elision rules, and
1640         // this desugaring achieves that.
1641
1642         // Calculate all the lifetimes that should be captured
1643         // by the opaque type. This should include all in-scope
1644         // lifetime parameters, including those defined in-band.
1645
1646         let mut captures = FxHashMap::default();
1647
1648         let extra_lifetime_params = self.resolver.take_extra_lifetime_params(opaque_ty_node_id);
1649         debug!(?extra_lifetime_params);
1650         for (ident, outer_node_id, outer_res) in extra_lifetime_params {
1651             let Ident { name, span } = ident;
1652             let outer_def_id = self.local_def_id(outer_node_id);
1653             let inner_node_id = self.next_node_id();
1654
1655             // Add a definition for the in scope lifetime def.
1656             self.create_def(opaque_ty_def_id, inner_node_id, DefPathData::LifetimeNs(name));
1657
1658             let (p_name, inner_res) = match outer_res {
1659                 // Input lifetime like `'a`:
1660                 LifetimeRes::Param { param, .. } => {
1661                     (hir::ParamName::Plain(ident), LifetimeRes::Param { param, binder: fn_node_id })
1662                 }
1663                 // Input lifetime like `'1`:
1664                 LifetimeRes::Fresh { param, .. } => {
1665                     (hir::ParamName::Fresh, LifetimeRes::Fresh { param, binder: fn_node_id })
1666                 }
1667                 LifetimeRes::Static | LifetimeRes::Error => continue,
1668                 res => {
1669                     panic!("Unexpected lifetime resolution {:?} for {:?} at {:?}", res, ident, span)
1670                 }
1671             };
1672
1673             captures.insert(outer_def_id, (span, inner_node_id, p_name, inner_res));
1674         }
1675
1676         debug!(?captures);
1677
1678         self.with_hir_id_owner(opaque_ty_node_id, |this| {
1679             let future_bound =
1680                 this.while_capturing_lifetimes(opaque_ty_def_id, &mut captures, |this| {
1681                     // We have to be careful to get elision right here. The
1682                     // idea is that we create a lifetime parameter for each
1683                     // lifetime in the return type.  So, given a return type
1684                     // like `async fn foo(..) -> &[&u32]`, we lower to `impl
1685                     // Future<Output = &'1 [ &'2 u32 ]>`.
1686                     //
1687                     // Then, we will create `fn foo(..) -> Foo<'_, '_>`, and
1688                     // hence the elision takes place at the fn site.
1689                     this.lower_async_fn_output_type_to_future_bound(output, fn_def_id, span)
1690                 });
1691             debug!("lower_async_fn_ret_ty: future_bound={:#?}", future_bound);
1692             debug!("lower_async_fn_ret_ty: captures={:#?}", captures);
1693
1694             let generic_params =
1695                 this.arena.alloc_from_iter(captures.iter().map(|(_, &(span, p_id, p_name, _))| {
1696                     let hir_id = this.lower_node_id(p_id);
1697                     debug_assert_ne!(this.opt_local_def_id(p_id), None);
1698
1699                     let kind = if p_name.ident().name == kw::UnderscoreLifetime {
1700                         hir::LifetimeParamKind::Elided
1701                     } else {
1702                         hir::LifetimeParamKind::Explicit
1703                     };
1704
1705                     hir::GenericParam {
1706                         hir_id,
1707                         name: p_name,
1708                         span,
1709                         pure_wrt_drop: false,
1710                         kind: hir::GenericParamKind::Lifetime { kind },
1711                         colon_span: None,
1712                     }
1713                 }));
1714             debug!("lower_async_fn_ret_ty: generic_params={:#?}", generic_params);
1715
1716             let opaque_ty_item = hir::OpaqueTy {
1717                 generics: this.arena.alloc(hir::Generics {
1718                     params: generic_params,
1719                     predicates: &[],
1720                     has_where_clause_predicates: false,
1721                     where_clause_span: this.lower_span(span),
1722                     span: this.lower_span(span),
1723                 }),
1724                 bounds: arena_vec![this; future_bound],
1725                 origin: hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
1726             };
1727
1728             trace!("exist ty from async fn def id: {:#?}", opaque_ty_def_id);
1729             this.generate_opaque_type(opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span)
1730         });
1731
1732         // As documented above, we need to create the lifetime
1733         // arguments to our opaque type. Continuing with our example,
1734         // we're creating the type arguments for the return type:
1735         //
1736         // ```
1737         // Bar<'a, 'b, '0, '1, '_>
1738         // ```
1739         //
1740         // For the "input" lifetime parameters, we wish to create
1741         // references to the parameters themselves, including the
1742         // "implicit" ones created from parameter types (`'a`, `'b`,
1743         // '`0`, `'1`).
1744         //
1745         // For the "output" lifetime parameters, we just want to
1746         // generate `'_`.
1747         let generic_args =
1748             self.arena.alloc_from_iter(captures.into_iter().map(|(_, (span, _, p_name, res))| {
1749                 let id = self.next_node_id();
1750                 let ident = Ident::new(p_name.ident().name, span);
1751                 let l = self.new_named_lifetime_with_res(id, span, ident, res);
1752                 hir::GenericArg::Lifetime(l)
1753             }));
1754
1755         // Create the `Foo<...>` reference itself. Note that the `type
1756         // Foo = impl Trait` is, internally, created as a child of the
1757         // async fn, so the *type parameters* are inherited.  It's
1758         // only the lifetime parameters that we must supply.
1759         let opaque_ty_ref =
1760             hir::TyKind::OpaqueDef(hir::ItemId { def_id: opaque_ty_def_id }, generic_args);
1761         let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);
1762         hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
1763     }
1764
1765     /// Transforms `-> T` into `Future<Output = T>`.
1766     fn lower_async_fn_output_type_to_future_bound(
1767         &mut self,
1768         output: &FnRetTy,
1769         fn_def_id: LocalDefId,
1770         span: Span,
1771     ) -> hir::GenericBound<'hir> {
1772         // Compute the `T` in `Future<Output = T>` from the return type.
1773         let output_ty = match output {
1774             FnRetTy::Ty(ty) => {
1775                 // Not `OpaqueTyOrigin::AsyncFn`: that's only used for the
1776                 // `impl Future` opaque type that `async fn` implicitly
1777                 // generates.
1778                 let context = ImplTraitContext::ReturnPositionOpaqueTy {
1779                     origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
1780                 };
1781                 self.lower_ty(ty, context)
1782             }
1783             FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),
1784         };
1785
1786         // "<Output = T>"
1787         let future_args = self.arena.alloc(hir::GenericArgs {
1788             args: &[],
1789             bindings: arena_vec![self; self.output_ty_binding(span, output_ty)],
1790             parenthesized: false,
1791             span_ext: DUMMY_SP,
1792         });
1793
1794         hir::GenericBound::LangItemTrait(
1795             // ::std::future::Future<future_params>
1796             hir::LangItem::Future,
1797             self.lower_span(span),
1798             self.next_id(),
1799             future_args,
1800         )
1801     }
1802
1803     #[instrument(level = "trace", skip(self))]
1804     fn lower_param_bound(
1805         &mut self,
1806         tpb: &GenericBound,
1807         itctx: ImplTraitContext,
1808     ) -> hir::GenericBound<'hir> {
1809         match tpb {
1810             GenericBound::Trait(p, modifier) => hir::GenericBound::Trait(
1811                 self.lower_poly_trait_ref(p, itctx),
1812                 self.lower_trait_bound_modifier(*modifier),
1813             ),
1814             GenericBound::Outlives(lifetime) => {
1815                 hir::GenericBound::Outlives(self.lower_lifetime(lifetime))
1816             }
1817         }
1818     }
1819
1820     fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime {
1821         let span = self.lower_span(l.ident.span);
1822         let ident = self.lower_ident(l.ident);
1823         let res = self.resolver.get_lifetime_res(l.id).unwrap_or(LifetimeRes::Error);
1824         self.new_named_lifetime_with_res(l.id, span, ident, res)
1825     }
1826
1827     #[tracing::instrument(level = "debug", skip(self))]
1828     fn new_named_lifetime_with_res(
1829         &mut self,
1830         id: NodeId,
1831         span: Span,
1832         ident: Ident,
1833         res: LifetimeRes,
1834     ) -> hir::Lifetime {
1835         debug!(?self.captured_lifetimes);
1836         let name = match res {
1837             LifetimeRes::Param { mut param, binder } => {
1838                 let p_name = ParamName::Plain(ident);
1839                 if let Some(mut captured_lifetimes) = self.captured_lifetimes.take() {
1840                     if !captured_lifetimes.binders_to_ignore.contains(&binder) {
1841                         match captured_lifetimes.captures.entry(param) {
1842                             Entry::Occupied(o) => param = self.local_def_id(o.get().1),
1843                             Entry::Vacant(v) => {
1844                                 let p_id = self.next_node_id();
1845                                 let p_def_id = self.create_def(
1846                                     captured_lifetimes.parent_def_id,
1847                                     p_id,
1848                                     DefPathData::LifetimeNs(p_name.ident().name),
1849                                 );
1850
1851                                 v.insert((span, p_id, p_name, res));
1852                                 param = p_def_id;
1853                             }
1854                         }
1855                     }
1856
1857                     self.captured_lifetimes = Some(captured_lifetimes);
1858                 }
1859                 hir::LifetimeName::Param(param, p_name)
1860             }
1861             LifetimeRes::Fresh { param, binder } => {
1862                 debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
1863                 let mut param = self.local_def_id(param);
1864                 if let Some(mut captured_lifetimes) = self.captured_lifetimes.take() {
1865                     if !captured_lifetimes.binders_to_ignore.contains(&binder) {
1866                         match captured_lifetimes.captures.entry(param) {
1867                             Entry::Occupied(o) => param = self.local_def_id(o.get().1),
1868                             Entry::Vacant(v) => {
1869                                 let p_id = self.next_node_id();
1870                                 let p_def_id = self.create_def(
1871                                     captured_lifetimes.parent_def_id,
1872                                     p_id,
1873                                     DefPathData::LifetimeNs(kw::UnderscoreLifetime),
1874                                 );
1875
1876                                 v.insert((span, p_id, ParamName::Fresh, res));
1877                                 param = p_def_id;
1878                             }
1879                         }
1880                     }
1881
1882                     self.captured_lifetimes = Some(captured_lifetimes);
1883                 }
1884                 hir::LifetimeName::Param(param, ParamName::Fresh)
1885             }
1886             LifetimeRes::Infer => hir::LifetimeName::Infer,
1887             LifetimeRes::Static => hir::LifetimeName::Static,
1888             LifetimeRes::Error => hir::LifetimeName::Error,
1889             res => panic!("Unexpected lifetime resolution {:?} for {:?} at {:?}", res, ident, span),
1890         };
1891         debug!(?self.captured_lifetimes);
1892         debug!(?name);
1893         hir::Lifetime { hir_id: self.lower_node_id(id), span: self.lower_span(span), name }
1894     }
1895
1896     fn lower_generic_params_mut<'s>(
1897         &'s mut self,
1898         params: &'s [GenericParam],
1899     ) -> impl Iterator<Item = hir::GenericParam<'hir>> + Captures<'a> + Captures<'s> {
1900         params.iter().map(move |param| self.lower_generic_param(param))
1901     }
1902
1903     fn lower_generic_params(&mut self, params: &[GenericParam]) -> &'hir [hir::GenericParam<'hir>] {
1904         self.arena.alloc_from_iter(self.lower_generic_params_mut(params))
1905     }
1906
1907     #[instrument(level = "trace", skip(self))]
1908     fn lower_generic_param(&mut self, param: &GenericParam) -> hir::GenericParam<'hir> {
1909         let (name, kind) = self.lower_generic_param_kind(param);
1910
1911         let hir_id = self.lower_node_id(param.id);
1912         self.lower_attrs(hir_id, &param.attrs);
1913         hir::GenericParam {
1914             hir_id,
1915             name,
1916             span: self.lower_span(param.span()),
1917             pure_wrt_drop: self.tcx.sess.contains_name(&param.attrs, sym::may_dangle),
1918             kind,
1919             colon_span: param.colon_span.map(|s| self.lower_span(s)),
1920         }
1921     }
1922
1923     fn lower_generic_param_kind(
1924         &mut self,
1925         param: &GenericParam,
1926     ) -> (hir::ParamName, hir::GenericParamKind<'hir>) {
1927         match param.kind {
1928             GenericParamKind::Lifetime => {
1929                 // AST resolution emitted an error on those parameters, so we lower them using
1930                 // `ParamName::Error`.
1931                 let param_name =
1932                     if let Some(LifetimeRes::Error) = self.resolver.get_lifetime_res(param.id) {
1933                         ParamName::Error
1934                     } else {
1935                         let ident = self.lower_ident(param.ident);
1936                         ParamName::Plain(ident)
1937                     };
1938                 let kind =
1939                     hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit };
1940
1941                 (param_name, kind)
1942             }
1943             GenericParamKind::Type { ref default, .. } => {
1944                 let kind = hir::GenericParamKind::Type {
1945                     default: default.as_ref().map(|x| {
1946                         self.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Type))
1947                     }),
1948                     synthetic: false,
1949                 };
1950
1951                 (hir::ParamName::Plain(self.lower_ident(param.ident)), kind)
1952             }
1953             GenericParamKind::Const { ref ty, kw_span: _, ref default } => {
1954                 let ty = self.lower_ty(&ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
1955                 let default = default.as_ref().map(|def| self.lower_anon_const(def));
1956                 (
1957                     hir::ParamName::Plain(self.lower_ident(param.ident)),
1958                     hir::GenericParamKind::Const { ty, default },
1959                 )
1960             }
1961         }
1962     }
1963
1964     fn lower_trait_ref(&mut self, p: &TraitRef, itctx: ImplTraitContext) -> hir::TraitRef<'hir> {
1965         let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx) {
1966             hir::QPath::Resolved(None, path) => path,
1967             qpath => panic!("lower_trait_ref: unexpected QPath `{:?}`", qpath),
1968         };
1969         hir::TraitRef { path, hir_ref_id: self.lower_node_id(p.ref_id) }
1970     }
1971
1972     #[tracing::instrument(level = "debug", skip(self))]
1973     fn lower_poly_trait_ref(
1974         &mut self,
1975         p: &PolyTraitRef,
1976         itctx: ImplTraitContext,
1977     ) -> hir::PolyTraitRef<'hir> {
1978         self.with_lifetime_binder(
1979             p.trait_ref.ref_id,
1980             &p.bound_generic_params,
1981             |this, bound_generic_params| {
1982                 let trait_ref = this.lower_trait_ref(&p.trait_ref, itctx);
1983                 hir::PolyTraitRef { bound_generic_params, trait_ref, span: this.lower_span(p.span) }
1984             },
1985         )
1986     }
1987
1988     fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> {
1989         hir::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl }
1990     }
1991
1992     fn lower_param_bounds(
1993         &mut self,
1994         bounds: &[GenericBound],
1995         itctx: ImplTraitContext,
1996     ) -> hir::GenericBounds<'hir> {
1997         self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, itctx))
1998     }
1999
2000     fn lower_param_bounds_mut<'s>(
2001         &'s mut self,
2002         bounds: &'s [GenericBound],
2003         itctx: ImplTraitContext,
2004     ) -> impl Iterator<Item = hir::GenericBound<'hir>> + Captures<'s> + Captures<'a> {
2005         bounds.iter().map(move |bound| self.lower_param_bound(bound, itctx))
2006     }
2007
2008     fn lower_generic_and_bounds(
2009         &mut self,
2010         node_id: NodeId,
2011         span: Span,
2012         ident: Ident,
2013         bounds: &[GenericBound],
2014     ) -> (hir::GenericParam<'hir>, Option<hir::WherePredicate<'hir>>, hir::TyKind<'hir>) {
2015         // Add a definition for the in-band `Param`.
2016         let def_id = self.local_def_id(node_id);
2017
2018         let hir_bounds = self.lower_param_bounds(bounds, ImplTraitContext::Universal);
2019         // Set the name to `impl Bound1 + Bound2`.
2020         let param = hir::GenericParam {
2021             hir_id: self.lower_node_id(node_id),
2022             name: ParamName::Plain(self.lower_ident(ident)),
2023             pure_wrt_drop: false,
2024             span: self.lower_span(span),
2025             kind: hir::GenericParamKind::Type { default: None, synthetic: true },
2026             colon_span: None,
2027         };
2028
2029         let preds = self.lower_generic_bound_predicate(
2030             ident,
2031             node_id,
2032             &GenericParamKind::Type { default: None },
2033             hir_bounds,
2034             hir::PredicateOrigin::ImplTrait,
2035         );
2036
2037         let ty = hir::TyKind::Path(hir::QPath::Resolved(
2038             None,
2039             self.arena.alloc(hir::Path {
2040                 span: self.lower_span(span),
2041                 res: Res::Def(DefKind::TyParam, def_id.to_def_id()),
2042                 segments: arena_vec![self; hir::PathSegment::from_ident(self.lower_ident(ident))],
2043             }),
2044         ));
2045
2046         (param, preds, ty)
2047     }
2048
2049     /// Lowers a block directly to an expression, presuming that it
2050     /// has no attributes and is not targeted by a `break`.
2051     fn lower_block_expr(&mut self, b: &Block) -> hir::Expr<'hir> {
2052         let block = self.lower_block(b, false);
2053         self.expr_block(block, AttrVec::new())
2054     }
2055
2056     fn lower_array_length(&mut self, c: &AnonConst) -> hir::ArrayLen {
2057         match c.value.kind {
2058             ExprKind::Underscore => {
2059                 if self.tcx.features().generic_arg_infer {
2060                     hir::ArrayLen::Infer(self.lower_node_id(c.id), c.value.span)
2061                 } else {
2062                     feature_err(
2063                         &self.tcx.sess.parse_sess,
2064                         sym::generic_arg_infer,
2065                         c.value.span,
2066                         "using `_` for array lengths is unstable",
2067                     )
2068                     .emit();
2069                     hir::ArrayLen::Body(self.lower_anon_const(c))
2070                 }
2071             }
2072             _ => hir::ArrayLen::Body(self.lower_anon_const(c)),
2073         }
2074     }
2075
2076     fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst {
2077         self.with_new_scopes(|this| hir::AnonConst {
2078             hir_id: this.lower_node_id(c.id),
2079             body: this.lower_const_body(c.value.span, Some(&c.value)),
2080         })
2081     }
2082
2083     fn lower_unsafe_source(&mut self, u: UnsafeSource) -> hir::UnsafeSource {
2084         match u {
2085             CompilerGenerated => hir::UnsafeSource::CompilerGenerated,
2086             UserProvided => hir::UnsafeSource::UserProvided,
2087         }
2088     }
2089
2090     fn lower_trait_bound_modifier(&mut self, f: TraitBoundModifier) -> hir::TraitBoundModifier {
2091         match f {
2092             TraitBoundModifier::None => hir::TraitBoundModifier::None,
2093             TraitBoundModifier::MaybeConst => hir::TraitBoundModifier::MaybeConst,
2094
2095             // `MaybeConstMaybe` will cause an error during AST validation, but we need to pick a
2096             // placeholder for compilation to proceed.
2097             TraitBoundModifier::MaybeConstMaybe | TraitBoundModifier::Maybe => {
2098                 hir::TraitBoundModifier::Maybe
2099             }
2100         }
2101     }
2102
2103     // Helper methods for building HIR.
2104
2105     fn stmt(&mut self, span: Span, kind: hir::StmtKind<'hir>) -> hir::Stmt<'hir> {
2106         hir::Stmt { span: self.lower_span(span), kind, hir_id: self.next_id() }
2107     }
2108
2109     fn stmt_expr(&mut self, span: Span, expr: hir::Expr<'hir>) -> hir::Stmt<'hir> {
2110         self.stmt(span, hir::StmtKind::Expr(self.arena.alloc(expr)))
2111     }
2112
2113     fn stmt_let_pat(
2114         &mut self,
2115         attrs: Option<&'hir [Attribute]>,
2116         span: Span,
2117         init: Option<&'hir hir::Expr<'hir>>,
2118         pat: &'hir hir::Pat<'hir>,
2119         source: hir::LocalSource,
2120     ) -> hir::Stmt<'hir> {
2121         let hir_id = self.next_id();
2122         if let Some(a) = attrs {
2123             debug_assert!(!a.is_empty());
2124             self.attrs.insert(hir_id.local_id, a);
2125         }
2126         let local = hir::Local {
2127             hir_id,
2128             init,
2129             pat,
2130             els: None,
2131             source,
2132             span: self.lower_span(span),
2133             ty: None,
2134         };
2135         self.stmt(span, hir::StmtKind::Local(self.arena.alloc(local)))
2136     }
2137
2138     fn block_expr(&mut self, expr: &'hir hir::Expr<'hir>) -> &'hir hir::Block<'hir> {
2139         self.block_all(expr.span, &[], Some(expr))
2140     }
2141
2142     fn block_all(
2143         &mut self,
2144         span: Span,
2145         stmts: &'hir [hir::Stmt<'hir>],
2146         expr: Option<&'hir hir::Expr<'hir>>,
2147     ) -> &'hir hir::Block<'hir> {
2148         let blk = hir::Block {
2149             stmts,
2150             expr,
2151             hir_id: self.next_id(),
2152             rules: hir::BlockCheckMode::DefaultBlock,
2153             span: self.lower_span(span),
2154             targeted_by_break: false,
2155         };
2156         self.arena.alloc(blk)
2157     }
2158
2159     fn pat_cf_continue(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2160         let field = self.single_pat_field(span, pat);
2161         self.pat_lang_item_variant(span, hir::LangItem::ControlFlowContinue, field, None)
2162     }
2163
2164     fn pat_cf_break(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2165         let field = self.single_pat_field(span, pat);
2166         self.pat_lang_item_variant(span, hir::LangItem::ControlFlowBreak, field, None)
2167     }
2168
2169     fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2170         let field = self.single_pat_field(span, pat);
2171         self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field, None)
2172     }
2173
2174     fn pat_none(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
2175         self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[], None)
2176     }
2177
2178     fn single_pat_field(
2179         &mut self,
2180         span: Span,
2181         pat: &'hir hir::Pat<'hir>,
2182     ) -> &'hir [hir::PatField<'hir>] {
2183         let field = hir::PatField {
2184             hir_id: self.next_id(),
2185             ident: Ident::new(sym::integer(0), self.lower_span(span)),
2186             is_shorthand: false,
2187             pat,
2188             span: self.lower_span(span),
2189         };
2190         arena_vec![self; field]
2191     }
2192
2193     fn pat_lang_item_variant(
2194         &mut self,
2195         span: Span,
2196         lang_item: hir::LangItem,
2197         fields: &'hir [hir::PatField<'hir>],
2198         hir_id: Option<hir::HirId>,
2199     ) -> &'hir hir::Pat<'hir> {
2200         let qpath = hir::QPath::LangItem(lang_item, self.lower_span(span), hir_id);
2201         self.pat(span, hir::PatKind::Struct(qpath, fields, false))
2202     }
2203
2204     fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, hir::HirId) {
2205         self.pat_ident_binding_mode(span, ident, hir::BindingAnnotation::Unannotated)
2206     }
2207
2208     fn pat_ident_mut(&mut self, span: Span, ident: Ident) -> (hir::Pat<'hir>, hir::HirId) {
2209         self.pat_ident_binding_mode_mut(span, ident, hir::BindingAnnotation::Unannotated)
2210     }
2211
2212     fn pat_ident_binding_mode(
2213         &mut self,
2214         span: Span,
2215         ident: Ident,
2216         bm: hir::BindingAnnotation,
2217     ) -> (&'hir hir::Pat<'hir>, hir::HirId) {
2218         let (pat, hir_id) = self.pat_ident_binding_mode_mut(span, ident, bm);
2219         (self.arena.alloc(pat), hir_id)
2220     }
2221
2222     fn pat_ident_binding_mode_mut(
2223         &mut self,
2224         span: Span,
2225         ident: Ident,
2226         bm: hir::BindingAnnotation,
2227     ) -> (hir::Pat<'hir>, hir::HirId) {
2228         let hir_id = self.next_id();
2229
2230         (
2231             hir::Pat {
2232                 hir_id,
2233                 kind: hir::PatKind::Binding(bm, hir_id, self.lower_ident(ident), None),
2234                 span: self.lower_span(span),
2235                 default_binding_modes: true,
2236             },
2237             hir_id,
2238         )
2239     }
2240
2241     fn pat(&mut self, span: Span, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> {
2242         self.arena.alloc(hir::Pat {
2243             hir_id: self.next_id(),
2244             kind,
2245             span: self.lower_span(span),
2246             default_binding_modes: true,
2247         })
2248     }
2249
2250     fn pat_without_dbm(&mut self, span: Span, kind: hir::PatKind<'hir>) -> hir::Pat<'hir> {
2251         hir::Pat {
2252             hir_id: self.next_id(),
2253             kind,
2254             span: self.lower_span(span),
2255             default_binding_modes: false,
2256         }
2257     }
2258
2259     fn ty_path(
2260         &mut self,
2261         mut hir_id: hir::HirId,
2262         span: Span,
2263         qpath: hir::QPath<'hir>,
2264     ) -> hir::Ty<'hir> {
2265         let kind = match qpath {
2266             hir::QPath::Resolved(None, path) => {
2267                 // Turn trait object paths into `TyKind::TraitObject` instead.
2268                 match path.res {
2269                     Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
2270                         let principal = hir::PolyTraitRef {
2271                             bound_generic_params: &[],
2272                             trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
2273                             span: self.lower_span(span),
2274                         };
2275
2276                         // The original ID is taken by the `PolyTraitRef`,
2277                         // so the `Ty` itself needs a different one.
2278                         hir_id = self.next_id();
2279                         hir::TyKind::TraitObject(
2280                             arena_vec![self; principal],
2281                             self.elided_dyn_bound(span),
2282                             TraitObjectSyntax::None,
2283                         )
2284                     }
2285                     _ => hir::TyKind::Path(hir::QPath::Resolved(None, path)),
2286                 }
2287             }
2288             _ => hir::TyKind::Path(qpath),
2289         };
2290
2291         hir::Ty { hir_id, kind, span: self.lower_span(span) }
2292     }
2293
2294     /// Invoked to create the lifetime argument(s) for an elided trait object
2295     /// bound, like the bound in `Box<dyn Debug>`. This method is not invoked
2296     /// when the bound is written, even if it is written with `'_` like in
2297     /// `Box<dyn Debug + '_>`. In those cases, `lower_lifetime` is invoked.
2298     fn elided_dyn_bound(&mut self, span: Span) -> hir::Lifetime {
2299         let r = hir::Lifetime {
2300             hir_id: self.next_id(),
2301             span: self.lower_span(span),
2302             name: hir::LifetimeName::ImplicitObjectLifetimeDefault,
2303         };
2304         debug!("elided_dyn_bound: r={:?}", r);
2305         r
2306     }
2307 }
2308
2309 /// Helper struct for delayed construction of GenericArgs.
2310 struct GenericArgsCtor<'hir> {
2311     args: SmallVec<[hir::GenericArg<'hir>; 4]>,
2312     bindings: &'hir [hir::TypeBinding<'hir>],
2313     parenthesized: bool,
2314     span: Span,
2315 }
2316
2317 impl<'hir> GenericArgsCtor<'hir> {
2318     fn is_empty(&self) -> bool {
2319         self.args.is_empty() && self.bindings.is_empty() && !self.parenthesized
2320     }
2321
2322     fn into_generic_args(self, this: &LoweringContext<'_, 'hir>) -> &'hir hir::GenericArgs<'hir> {
2323         let ga = hir::GenericArgs {
2324             args: this.arena.alloc_from_iter(self.args),
2325             bindings: self.bindings,
2326             parenthesized: self.parenthesized,
2327             span_ext: this.lower_span(self.span),
2328         };
2329         this.arena.alloc(ga)
2330     }
2331 }