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