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