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