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