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