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