1 //! Lowers the AST to the HIR.
3 //! Since the AST and HIR are fairly similar, this is mostly a simple procedure,
4 //! much like a fold. Where lowering involves a bit more work things get more
5 //! interesting and there are some invariants you should know about. These mostly
6 //! concern spans and IDs.
8 //! Spans are assigned to AST nodes during parsing and then are modified during
9 //! expansion to indicate the origin of a node and the process it went through
10 //! being expanded. IDs are assigned to AST nodes just before lowering.
12 //! For the simpler lowering steps, IDs and spans should be preserved. Unlike
13 //! expansion we do not preserve the process of lowering in the spans, so spans
14 //! should not be modified here. When creating a new node (as opposed to
15 //! "folding" an existing one), create a new ID using `next_id()`.
17 //! You must ensure that IDs are unique. That means that you should only use the
18 //! ID from an AST node in a single HIR node (you can assume that AST node-IDs
19 //! are unique). Every new node must have a unique ID. Avoid cloning HIR nodes.
20 //! If you do, you must then set the new node's ID to a fresh one.
22 //! Spans are used for error messages and for tools to map semantics back to
23 //! source code. It is therefore not as important with spans as IDs to be strict
24 //! about use (you can't break the compiler by screwing up a span). Obviously, a
25 //! HIR node can only have a single span. But multiple nodes can have the same
26 //! span and spans don't need to be kept in order, etc. Where code is preserved
27 //! by lowering, it should have the same span as in the AST. Where HIR nodes are
28 //! new it is probably best to give a span for the whole AST node being lowered.
29 //! All nodes should have real spans; don't use dummy spans. Tools are likely to
30 //! get confused if the spans from leaf AST nodes occur in multiple places
31 //! in the HIR, especially for multiple identifiers.
33 #![feature(box_patterns)]
34 #![feature(let_chains)]
36 #![feature(never_type)]
37 #![recursion_limit = "256"]
38 #![allow(rustc::potential_query_instability)]
44 use rustc_ast
::{self as ast, *}
;
45 use rustc_ast_pretty
::pprust
;
46 use rustc_data_structures
::captures
::Captures
;
47 use rustc_data_structures
::fingerprint
::Fingerprint
;
48 use rustc_data_structures
::fx
::FxHashMap
;
49 use rustc_data_structures
::sorted_map
::SortedMap
;
50 use rustc_data_structures
::stable_hasher
::{HashStable, StableHasher}
;
51 use rustc_data_structures
::sync
::Lrc
;
52 use rustc_errors
::{struct_span_err, Applicability, Handler}
;
54 use rustc_hir
::def
::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}
;
55 use rustc_hir
::def_id
::{LocalDefId, CRATE_DEF_ID}
;
56 use rustc_hir
::definitions
::DefPathData
;
57 use rustc_hir
::{ConstArg, GenericArg, ItemLocalId, ParamName, TraitCandidate}
;
58 use rustc_index
::vec
::{Idx, IndexVec}
;
59 use rustc_middle
::span_bug
;
60 use rustc_middle
::ty
::{ResolverAstLowering, TyCtxt}
;
61 use rustc_session
::parse
::feature_err
;
62 use rustc_span
::hygiene
::MacroKind
;
63 use rustc_span
::source_map
::DesugaringKind
;
64 use rustc_span
::symbol
::{kw, sym, Ident, Symbol}
;
65 use rustc_span
::{Span, DUMMY_SP}
;
67 use smallvec
::SmallVec
;
68 use std
::collections
::hash_map
::Entry
;
70 macro_rules
! arena_vec
{
71 ($this
:expr
; $
($x
:expr
),*) => (
72 $this
.arena
.alloc_from_iter([$
($x
),*])
81 mod lifetime_collector
;
85 struct LoweringContext
<'a
, 'hir
> {
87 resolver
: &'a
mut ResolverAstLowering
,
89 /// Used to allocate HIR nodes.
90 arena
: &'hir hir
::Arena
<'hir
>,
92 /// Bodies inside the owner being lowered.
93 bodies
: Vec
<(hir
::ItemLocalId
, &'hir hir
::Body
<'hir
>)>,
94 /// Attributes inside the owner being lowered.
95 attrs
: SortedMap
<hir
::ItemLocalId
, &'hir
[Attribute
]>,
96 /// Collect items that were created by lowering the current owner.
97 children
: FxHashMap
<LocalDefId
, hir
::MaybeOwner
<&'hir hir
::OwnerInfo
<'hir
>>>,
99 generator_kind
: Option
<hir
::GeneratorKind
>,
101 /// When inside an `async` context, this is the `HirId` of the
102 /// `task_context` local bound to the resume argument of the generator.
103 task_context
: Option
<hir
::HirId
>,
105 /// Used to get the current `fn`'s def span to point to when using `await`
106 /// outside of an `async fn`.
107 current_item
: Option
<Span
>,
109 catch_scope
: Option
<NodeId
>,
110 loop_scope
: Option
<NodeId
>,
111 is_in_loop_condition
: bool
,
112 is_in_trait_impl
: bool
,
113 is_in_dyn_type
: bool
,
115 current_hir_id_owner
: LocalDefId
,
116 item_local_id_counter
: hir
::ItemLocalId
,
117 local_id_to_def_id
: SortedMap
<ItemLocalId
, LocalDefId
>,
118 trait_map
: FxHashMap
<ItemLocalId
, Box
<[TraitCandidate
]>>,
120 impl_trait_defs
: Vec
<hir
::GenericParam
<'hir
>>,
121 impl_trait_bounds
: Vec
<hir
::WherePredicate
<'hir
>>,
123 /// NodeIds that are lowered inside the current HIR owner.
124 node_id_to_local_id
: FxHashMap
<NodeId
, hir
::ItemLocalId
>,
126 allow_try_trait
: Option
<Lrc
<[Symbol
]>>,
127 allow_gen_future
: Option
<Lrc
<[Symbol
]>>,
128 allow_into_future
: Option
<Lrc
<[Symbol
]>>,
131 trait ResolverAstLoweringExt
{
132 fn legacy_const_generic_args(&self, expr
: &Expr
) -> Option
<Vec
<usize>>;
133 fn get_partial_res(&self, id
: NodeId
) -> Option
<PartialRes
>;
134 fn get_import_res(&self, id
: NodeId
) -> PerNS
<Option
<Res
<NodeId
>>>;
135 fn get_label_res(&self, id
: NodeId
) -> Option
<NodeId
>;
136 fn get_lifetime_res(&self, id
: NodeId
) -> Option
<LifetimeRes
>;
137 fn take_extra_lifetime_params(&mut self, id
: NodeId
) -> Vec
<(Ident
, NodeId
, LifetimeRes
)>;
138 fn decl_macro_kind(&self, def_id
: LocalDefId
) -> MacroKind
;
139 /// Record the map from `from` local def id to `to` local def id, on `generics_def_id_map`
141 fn record_def_id_remap(&mut self, from
: LocalDefId
, to
: LocalDefId
);
142 /// Get the previously recorded `to` local def id given the `from` local def id, obtained using
143 /// `generics_def_id_map` field.
144 fn get_remapped_def_id(&self, local_def_id
: LocalDefId
) -> LocalDefId
;
147 impl ResolverAstLoweringExt
for ResolverAstLowering
{
148 fn legacy_const_generic_args(&self, expr
: &Expr
) -> Option
<Vec
<usize>> {
149 if let ExprKind
::Path(None
, path
) = &expr
.kind
{
150 // Don't perform legacy const generics rewriting if the path already
151 // has generic arguments.
152 if path
.segments
.last().unwrap().args
.is_some() {
156 let partial_res
= self.partial_res_map
.get(&expr
.id
)?
;
157 if partial_res
.unresolved_segments() != 0 {
161 if let Res
::Def(DefKind
::Fn
, def_id
) = partial_res
.base_res() {
162 // We only support cross-crate argument rewriting. Uses
163 // within the same crate should be updated to use the new
164 // const generics style.
165 if def_id
.is_local() {
169 if let Some(v
) = self.legacy_const_generic_args
.get(&def_id
) {
178 /// Obtains resolution for a `NodeId` with a single resolution.
179 fn get_partial_res(&self, id
: NodeId
) -> Option
<PartialRes
> {
180 self.partial_res_map
.get(&id
).copied()
183 /// Obtains per-namespace resolutions for `use` statement with the given `NodeId`.
184 fn get_import_res(&self, id
: NodeId
) -> PerNS
<Option
<Res
<NodeId
>>> {
185 self.import_res_map
.get(&id
).copied().unwrap_or_default()
188 /// Obtains resolution for a label with the given `NodeId`.
189 fn get_label_res(&self, id
: NodeId
) -> Option
<NodeId
> {
190 self.label_res_map
.get(&id
).copied()
193 /// Obtains resolution for a lifetime with the given `NodeId`.
194 fn get_lifetime_res(&self, id
: NodeId
) -> Option
<LifetimeRes
> {
195 self.lifetimes_res_map
.get(&id
).copied()
198 /// Obtain the list of lifetimes parameters to add to an item.
200 /// Extra lifetime parameters should only be added in places that can appear
201 /// as a `binder` in `LifetimeRes`.
203 /// The extra lifetimes that appear from the parenthesized `Fn`-trait desugaring
204 /// should appear at the enclosing `PolyTraitRef`.
205 fn take_extra_lifetime_params(&mut self, id
: NodeId
) -> Vec
<(Ident
, NodeId
, LifetimeRes
)> {
206 self.extra_lifetime_params_map
.remove(&id
).unwrap_or_default()
209 fn decl_macro_kind(&self, def_id
: LocalDefId
) -> MacroKind
{
210 self.builtin_macro_kinds
.get(&def_id
).copied().unwrap_or(MacroKind
::Bang
)
213 /// Push a remapping into the top-most map.
214 /// Panics if no map has been pushed.
215 /// Remapping is used when creating lowering `-> impl Trait` return
216 /// types to create the resulting opaque type.
217 #[tracing::instrument(level = "debug", skip(self))]
218 fn record_def_id_remap(&mut self, from
: LocalDefId
, to
: LocalDefId
) {
219 self.generics_def_id_map
.last_mut().expect("no map pushed").insert(from
, to
);
222 fn get_remapped_def_id(&self, mut local_def_id
: LocalDefId
) -> LocalDefId
{
223 // `generics_def_id_map` is a stack of mappings. As we go deeper in impl traits nesting we
224 // push new mappings so we need to try first the latest mappings, hence `iter().rev()`.
228 // `fn test<'a, 'b>() -> impl Trait<&'a u8, Ty = impl Sized + 'b> {}`
230 // We would end with a generics_def_id_map like:
232 // `[[fn#'b -> impl_trait#'b], [fn#'b -> impl_sized#'b]]`
234 // for the opaque type generated on `impl Sized + 'b`, We want the result to be:
235 // impl_sized#'b, so iterating forward is the wrong thing to do.
236 for map
in self.generics_def_id_map
.iter().rev() {
237 if let Some(r
) = map
.get(&local_def_id
) {
238 debug
!("def_id_remapper: remapping from `{local_def_id:?}` to `{r:?}`");
241 debug
!("def_id_remapper: no remapping for `{local_def_id:?}` found in map");
249 /// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,
250 /// and if so, what meaning it has.
251 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
252 enum ImplTraitContext
{
253 /// Treat `impl Trait` as shorthand for a new universal generic parameter.
254 /// Example: `fn foo(x: impl Debug)`, where `impl Debug` is conceptually
255 /// equivalent to a fresh universal parameter like `fn foo<T: Debug>(x: T)`.
257 /// Newly generated parameters should be inserted into the given `Vec`.
260 /// Treat `impl Trait` as shorthand for a new opaque type.
261 /// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
262 /// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`.
264 ReturnPositionOpaqueTy
{
265 /// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn,
266 origin
: hir
::OpaqueTyOrigin
,
268 /// Impl trait in type aliases.
270 /// `impl Trait` is not accepted in this position.
271 Disallowed(ImplTraitPosition
),
274 /// Position in which `impl Trait` is disallowed.
275 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
276 enum ImplTraitPosition
{
298 impl std
::fmt
::Display
for ImplTraitPosition
{
299 fn fmt(&self, f
: &mut std
::fmt
::Formatter
<'_
>) -> std
::fmt
::Result
{
300 let name
= match self {
301 ImplTraitPosition
::Path
=> "path",
302 ImplTraitPosition
::Variable
=> "variable binding",
303 ImplTraitPosition
::Type
=> "type",
304 ImplTraitPosition
::Trait
=> "trait",
305 ImplTraitPosition
::AsyncBlock
=> "async block",
306 ImplTraitPosition
::Bound
=> "bound",
307 ImplTraitPosition
::Generic
=> "generic",
308 ImplTraitPosition
::ExternFnParam
=> "`extern fn` param",
309 ImplTraitPosition
::ClosureParam
=> "closure param",
310 ImplTraitPosition
::PointerParam
=> "`fn` pointer param",
311 ImplTraitPosition
::FnTraitParam
=> "`Fn` trait param",
312 ImplTraitPosition
::TraitParam
=> "trait method param",
313 ImplTraitPosition
::ImplParam
=> "`impl` method param",
314 ImplTraitPosition
::ExternFnReturn
=> "`extern fn` return",
315 ImplTraitPosition
::ClosureReturn
=> "closure return",
316 ImplTraitPosition
::PointerReturn
=> "`fn` pointer return",
317 ImplTraitPosition
::FnTraitReturn
=> "`Fn` trait return",
318 ImplTraitPosition
::TraitReturn
=> "trait method return",
319 ImplTraitPosition
::ImplReturn
=> "`impl` method return",
322 write
!(f
, "{}", name
)
338 fn impl_trait_return_allowed(&self) -> bool
{
340 FnDeclKind
::Fn
| FnDeclKind
::Inherent
=> true,
346 #[derive(Copy, Clone)]
349 Crate(&'a ast
::Crate
),
351 AssocItem(&'a ast
::AssocItem
, visit
::AssocCtxt
),
352 ForeignItem(&'a ast
::ForeignItem
),
356 node_id_to_def_id
: &FxHashMap
<NodeId
, LocalDefId
>,
358 ) -> IndexVec
<LocalDefId
, AstOwner
<'a
>> {
359 let mut indexer
= Indexer { node_id_to_def_id, index: IndexVec::new() }
;
360 indexer
.index
.ensure_contains_elem(CRATE_DEF_ID
, || AstOwner
::NonOwner
);
361 indexer
.index
[CRATE_DEF_ID
] = AstOwner
::Crate(krate
);
362 visit
::walk_crate(&mut indexer
, krate
);
363 return indexer
.index
;
365 struct Indexer
<'s
, 'a
> {
366 node_id_to_def_id
: &'s FxHashMap
<NodeId
, LocalDefId
>,
367 index
: IndexVec
<LocalDefId
, AstOwner
<'a
>>,
370 impl<'a
> visit
::Visitor
<'a
> for Indexer
<'_
, 'a
> {
371 fn visit_attribute(&mut self, _
: &'a Attribute
) {
372 // We do not want to lower expressions that appear in attributes,
373 // as they are not accessible to the rest of the HIR.
376 fn visit_item(&mut self, item
: &'a ast
::Item
) {
377 let def_id
= self.node_id_to_def_id
[&item
.id
];
378 self.index
.ensure_contains_elem(def_id
, || AstOwner
::NonOwner
);
379 self.index
[def_id
] = AstOwner
::Item(item
);
380 visit
::walk_item(self, item
)
383 fn visit_assoc_item(&mut self, item
: &'a ast
::AssocItem
, ctxt
: visit
::AssocCtxt
) {
384 let def_id
= self.node_id_to_def_id
[&item
.id
];
385 self.index
.ensure_contains_elem(def_id
, || AstOwner
::NonOwner
);
386 self.index
[def_id
] = AstOwner
::AssocItem(item
, ctxt
);
387 visit
::walk_assoc_item(self, item
, ctxt
);
390 fn visit_foreign_item(&mut self, item
: &'a ast
::ForeignItem
) {
391 let def_id
= self.node_id_to_def_id
[&item
.id
];
392 self.index
.ensure_contains_elem(def_id
, || AstOwner
::NonOwner
);
393 self.index
[def_id
] = AstOwner
::ForeignItem(item
);
394 visit
::walk_foreign_item(self, item
);
399 /// Compute the hash for the HIR of the full crate.
400 /// This hash will then be part of the crate_hash which is stored in the metadata.
403 owners
: &IndexVec
<LocalDefId
, hir
::MaybeOwner
<&hir
::OwnerInfo
<'_
>>>,
405 let mut hir_body_nodes
: Vec
<_
> = owners
407 .filter_map(|(def_id
, info
)| {
408 let info
= info
.as_owner()?
;
409 let def_path_hash
= tcx
.hir().def_path_hash(def_id
);
410 Some((def_path_hash
, info
))
413 hir_body_nodes
.sort_unstable_by_key(|bn
| bn
.0);
415 tcx
.with_stable_hashing_context(|mut hcx
| {
416 let mut stable_hasher
= StableHasher
::new();
417 hir_body_nodes
.hash_stable(&mut hcx
, &mut stable_hasher
);
418 stable_hasher
.finish()
422 pub fn lower_to_hir
<'hir
>(tcx
: TyCtxt
<'hir
>, (): ()) -> hir
::Crate
<'hir
> {
424 let krate
= tcx
.untracked_crate
.steal();
425 let mut resolver
= tcx
.resolver_for_lowering(()).steal();
427 let ast_index
= index_crate(&resolver
.node_id_to_def_id
, &krate
);
428 let mut owners
= IndexVec
::from_fn_n(
429 |_
| hir
::MaybeOwner
::Phantom
,
430 tcx
.definitions_untracked().def_index_count(),
433 for def_id
in ast_index
.indices() {
436 resolver
: &mut resolver
,
437 ast_index
: &ast_index
,
443 // Drop AST to free memory
444 std
::mem
::drop(ast_index
);
445 sess
.time("drop_ast", || std
::mem
::drop(krate
));
447 // Discard hygiene data, which isn't required after lowering to HIR.
448 if !sess
.opts
.unstable_opts
.keep_hygiene_data
{
449 rustc_span
::hygiene
::clear_syntax_context_map();
452 let hir_hash
= compute_hir_hash(tcx
, &owners
);
453 hir
::Crate { owners, hir_hash }
456 #[derive(Copy, Clone, PartialEq, Debug)]
458 /// Any path in a type context.
460 /// Path in a type definition, where the anonymous lifetime `'_` is not allowed.
462 /// The `module::Type` in `module::Type::method` in an expression.
466 enum ParenthesizedGenericArgs
{
471 impl<'a
, 'hir
> LoweringContext
<'a
, 'hir
> {
475 node_id
: ast
::NodeId
,
478 debug_assert_ne
!(node_id
, ast
::DUMMY_NODE_ID
);
480 self.opt_local_def_id(node_id
).is_none(),
481 "adding a def'n for node-id {:?} and data {:?} but a previous def'n exists: {:?}",
484 self.tcx
.hir().def_key(self.local_def_id(node_id
)),
487 let def_id
= self.tcx
.create_def(parent
, data
);
489 debug
!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id
, node_id
);
490 self.resolver
.node_id_to_def_id
.insert(node_id
, def_id
);
495 fn next_node_id(&mut self) -> NodeId
{
496 let start
= self.resolver
.next_node_id
;
497 let next
= start
.as_u32().checked_add(1).expect("input too large; ran out of NodeIds");
498 self.resolver
.next_node_id
= ast
::NodeId
::from_u32(next
);
502 /// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name
503 /// resolver (if any), after applying any remapping from `get_remapped_def_id`.
505 /// For example, in a function like `fn foo<'a>(x: &'a u32)`,
506 /// invoking with the id from the `ast::Lifetime` node found inside
507 /// the `&'a u32` type would return the `LocalDefId` of the
508 /// `'a` parameter declared on `foo`.
510 /// This function also applies remapping from `get_remapped_def_id`.
511 /// These are used when synthesizing opaque types from `-> impl Trait` return types and so forth.
512 /// For example, in a function like `fn foo<'a>() -> impl Debug + 'a`,
513 /// we would create an opaque type `type FooReturn<'a1> = impl Debug + 'a1`.
514 /// When lowering the `Debug + 'a` bounds, we add a remapping to map `'a` to `'a1`.
515 fn opt_local_def_id(&self, node
: NodeId
) -> Option
<LocalDefId
> {
519 .map(|local_def_id
| self.resolver
.get_remapped_def_id(*local_def_id
))
522 fn local_def_id(&self, node
: NodeId
) -> LocalDefId
{
523 self.opt_local_def_id(node
).unwrap_or_else(|| panic
!("no entry for node id: `{:?}`", node
))
526 /// Freshen the `LoweringContext` and ready it to lower a nested item.
527 /// The lowered item is registered into `self.children`.
529 /// This function sets up `HirId` lowering infrastructure,
530 /// and stashes the shared mutable state to avoid pollution by the closure.
531 #[instrument(level = "debug", skip(self, f))]
532 fn with_hir_id_owner(
535 f
: impl FnOnce(&mut Self) -> hir
::OwnerNode
<'hir
>,
537 let def_id
= self.local_def_id(owner
);
539 let current_attrs
= std
::mem
::take(&mut self.attrs
);
540 let current_bodies
= std
::mem
::take(&mut self.bodies
);
541 let current_node_ids
= std
::mem
::take(&mut self.node_id_to_local_id
);
542 let current_id_to_def_id
= std
::mem
::take(&mut self.local_id_to_def_id
);
543 let current_trait_map
= std
::mem
::take(&mut self.trait_map
);
544 let current_owner
= std
::mem
::replace(&mut self.current_hir_id_owner
, def_id
);
545 let current_local_counter
=
546 std
::mem
::replace(&mut self.item_local_id_counter
, hir
::ItemLocalId
::new(1));
547 let current_impl_trait_defs
= std
::mem
::take(&mut self.impl_trait_defs
);
548 let current_impl_trait_bounds
= std
::mem
::take(&mut self.impl_trait_bounds
);
550 // Do not reset `next_node_id` and `node_id_to_def_id`:
551 // we want `f` to be able to refer to the `LocalDefId`s that the caller created.
552 // and the caller to refer to some of the subdefinitions' nodes' `LocalDefId`s.
554 // Always allocate the first `HirId` for the owner itself.
555 let _old
= self.node_id_to_local_id
.insert(owner
, hir
::ItemLocalId
::new(0));
556 debug_assert_eq
!(_old
, None
);
559 debug_assert_eq
!(def_id
, item
.def_id());
560 // `f` should have consumed all the elements in these vectors when constructing `item`.
561 debug_assert
!(self.impl_trait_defs
.is_empty());
562 debug_assert
!(self.impl_trait_bounds
.is_empty());
563 let info
= self.make_owner_info(item
);
565 self.attrs
= current_attrs
;
566 self.bodies
= current_bodies
;
567 self.node_id_to_local_id
= current_node_ids
;
568 self.local_id_to_def_id
= current_id_to_def_id
;
569 self.trait_map
= current_trait_map
;
570 self.current_hir_id_owner
= current_owner
;
571 self.item_local_id_counter
= current_local_counter
;
572 self.impl_trait_defs
= current_impl_trait_defs
;
573 self.impl_trait_bounds
= current_impl_trait_bounds
;
575 let _old
= self.children
.insert(def_id
, hir
::MaybeOwner
::Owner(info
));
576 debug_assert
!(_old
.is_none())
579 /// Installs the remapping `remap` in scope while `f` is being executed.
580 /// This causes references to the `LocalDefId` keys to be changed to
581 /// refer to the values instead.
583 /// The remapping is used when one piece of AST expands to multiple
584 /// pieces of HIR. For example, the function `fn foo<'a>(...) -> impl Debug + 'a`,
585 /// expands to both a function definition (`foo`) and a TAIT for the return value,
586 /// both of which have a lifetime parameter `'a`. The remapping allows us to
587 /// rewrite the `'a` in the return value to refer to the
588 /// `'a` declared on the TAIT, instead of the function.
589 fn with_remapping
<R
>(
591 remap
: FxHashMap
<LocalDefId
, LocalDefId
>,
592 f
: impl FnOnce(&mut Self) -> R
,
594 self.resolver
.generics_def_id_map
.push(remap
);
596 self.resolver
.generics_def_id_map
.pop();
600 fn make_owner_info(&mut self, node
: hir
::OwnerNode
<'hir
>) -> &'hir hir
::OwnerInfo
<'hir
> {
601 let attrs
= std
::mem
::take(&mut self.attrs
);
602 let mut bodies
= std
::mem
::take(&mut self.bodies
);
603 let local_id_to_def_id
= std
::mem
::take(&mut self.local_id_to_def_id
);
604 let trait_map
= std
::mem
::take(&mut self.trait_map
);
606 #[cfg(debug_assertions)]
607 for (id
, attrs
) in attrs
.iter() {
608 // Verify that we do not store empty slices in the map.
609 if attrs
.is_empty() {
610 panic
!("Stored empty attributes for {:?}", id
);
614 bodies
.sort_by_key(|(k
, _
)| *k
);
615 let bodies
= SortedMap
::from_presorted_elements(bodies
);
616 let (hash_including_bodies
, hash_without_bodies
) = self.hash_owner(node
, &bodies
);
617 let (nodes
, parenting
) =
618 index
::index_hir(self.tcx
.sess
, &*self.tcx
.definitions_untracked(), node
, &bodies
);
619 let nodes
= hir
::OwnerNodes
{
620 hash_including_bodies
,
627 let hash
= self.tcx
.with_stable_hashing_context(|mut hcx
| {
628 let mut stable_hasher
= StableHasher
::new();
629 attrs
.hash_stable(&mut hcx
, &mut stable_hasher
);
630 stable_hasher
.finish()
632 hir
::AttributeMap { map: attrs, hash }
635 self.arena
.alloc(hir
::OwnerInfo { nodes, parenting, attrs, trait_map }
)
638 /// Hash the HIR node twice, one deep and one shallow hash. This allows to differentiate
639 /// queries which depend on the full HIR tree and those which only depend on the item signature.
642 node
: hir
::OwnerNode
<'hir
>,
643 bodies
: &SortedMap
<hir
::ItemLocalId
, &'hir hir
::Body
<'hir
>>,
644 ) -> (Fingerprint
, Fingerprint
) {
645 self.tcx
.with_stable_hashing_context(|mut hcx
| {
646 let mut stable_hasher
= StableHasher
::new();
647 hcx
.with_hir_bodies(true, node
.def_id(), bodies
, |hcx
| {
648 node
.hash_stable(hcx
, &mut stable_hasher
)
650 let hash_including_bodies
= stable_hasher
.finish();
651 let mut stable_hasher
= StableHasher
::new();
652 hcx
.with_hir_bodies(false, node
.def_id(), bodies
, |hcx
| {
653 node
.hash_stable(hcx
, &mut stable_hasher
)
655 let hash_without_bodies
= stable_hasher
.finish();
656 (hash_including_bodies
, hash_without_bodies
)
660 /// This method allocates a new `HirId` for the given `NodeId` and stores it in
661 /// the `LoweringContext`'s `NodeId => HirId` map.
662 /// Take care not to call this method if the resulting `HirId` is then not
663 /// actually used in the HIR, as that would trigger an assertion in the
664 /// `HirIdValidator` later on, which makes sure that all `NodeId`s got mapped
665 /// properly. Calling the method twice with the same `NodeId` is fine though.
666 fn lower_node_id(&mut self, ast_node_id
: NodeId
) -> hir
::HirId
{
667 assert_ne
!(ast_node_id
, DUMMY_NODE_ID
);
669 match self.node_id_to_local_id
.entry(ast_node_id
) {
670 Entry
::Occupied(o
) => {
671 hir
::HirId { owner: self.current_hir_id_owner, local_id: *o.get() }
673 Entry
::Vacant(v
) => {
674 // Generate a new `HirId`.
675 let owner
= self.current_hir_id_owner
;
676 let local_id
= self.item_local_id_counter
;
677 let hir_id
= hir
::HirId { owner, local_id }
;
680 self.item_local_id_counter
.increment_by(1);
682 assert_ne
!(local_id
, hir
::ItemLocalId
::new(0));
683 if let Some(def_id
) = self.opt_local_def_id(ast_node_id
) {
684 // Do not override a `MaybeOwner::Owner` that may already here.
685 self.children
.entry(def_id
).or_insert(hir
::MaybeOwner
::NonOwner(hir_id
));
686 self.local_id_to_def_id
.insert(local_id
, def_id
);
689 if let Some(traits
) = self.resolver
.trait_map
.remove(&ast_node_id
) {
690 self.trait_map
.insert(hir_id
.local_id
, traits
.into_boxed_slice());
698 /// Generate a new `HirId` without a backing `NodeId`.
699 fn next_id(&mut self) -> hir
::HirId
{
700 let owner
= self.current_hir_id_owner
;
701 let local_id
= self.item_local_id_counter
;
702 assert_ne
!(local_id
, hir
::ItemLocalId
::new(0));
703 self.item_local_id_counter
.increment_by(1);
704 hir
::HirId { owner, local_id }
707 #[instrument(level = "trace", skip(self))]
708 fn lower_res(&mut self, res
: Res
<NodeId
>) -> Res
{
709 let res
: Result
<Res
, ()> = res
.apply_id(|id
| {
710 let owner
= self.current_hir_id_owner
;
711 let local_id
= self.node_id_to_local_id
.get(&id
).copied().ok_or(())?
;
712 Ok(hir
::HirId { owner, local_id }
)
716 // We may fail to find a HirId when the Res points to a Local from an enclosing HIR owner.
717 // This can happen when trying to lower the return type `x` in erroneous code like
718 // async fn foo(x: u8) -> x {}
719 // In that case, `x` is lowered as a function parameter, and the return type is lowered as
720 // an opaque type as a synthesized HIR owner.
721 res
.unwrap_or(Res
::Err
)
724 fn expect_full_res(&mut self, id
: NodeId
) -> Res
<NodeId
> {
725 self.resolver
.get_partial_res(id
).map_or(Res
::Err
, |pr
| {
726 if pr
.unresolved_segments() != 0 {
727 panic
!("path not fully resolved: {:?}", pr
);
733 fn expect_full_res_from_use(&mut self, id
: NodeId
) -> impl Iterator
<Item
= Res
<NodeId
>> {
734 self.resolver
.get_import_res(id
).present_items()
737 fn diagnostic(&self) -> &Handler
{
738 self.tcx
.sess
.diagnostic()
741 /// Reuses the span but adds information like the kind of the desugaring and features that are
742 /// allowed inside this span.
743 fn mark_span_with_reason(
745 reason
: DesugaringKind
,
747 allow_internal_unstable
: Option
<Lrc
<[Symbol
]>>,
749 self.tcx
.with_stable_hashing_context(|hcx
| {
750 span
.mark_with_reason(allow_internal_unstable
, reason
, self.tcx
.sess
.edition(), hcx
)
754 /// Intercept all spans entering HIR.
755 /// Mark a span as relative to the current owning item.
756 fn lower_span(&self, span
: Span
) -> Span
{
757 if self.tcx
.sess
.opts
.unstable_opts
.incremental_relative_spans
{
758 span
.with_parent(Some(self.current_hir_id_owner
))
760 // Do not make spans relative when not using incremental compilation.
765 fn lower_ident(&self, ident
: Ident
) -> Ident
{
766 Ident
::new(ident
.name
, self.lower_span(ident
.span
))
769 /// Converts a lifetime into a new generic parameter.
770 #[tracing::instrument(level = "debug", skip(self))]
771 fn lifetime_res_to_generic_param(
776 ) -> Option
<hir
::GenericParam
<'hir
>> {
777 let (name
, kind
) = match res
{
778 LifetimeRes
::Param { .. }
=> {
779 (hir
::ParamName
::Plain(ident
), hir
::LifetimeParamKind
::Explicit
)
781 LifetimeRes
::Fresh { param, .. }
=> {
782 // Late resolution delegates to us the creation of the `LocalDefId`.
783 let _def_id
= self.create_def(
784 self.current_hir_id_owner
,
786 DefPathData
::LifetimeNs(kw
::UnderscoreLifetime
),
790 (hir
::ParamName
::Fresh
, hir
::LifetimeParamKind
::Elided
)
792 LifetimeRes
::Static
| LifetimeRes
::Error
=> return None
,
794 "Unexpected lifetime resolution {:?} for {:?} at {:?}",
795 res
, ident
, ident
.span
798 let hir_id
= self.lower_node_id(node_id
);
799 Some(hir
::GenericParam
{
802 span
: self.lower_span(ident
.span
),
803 pure_wrt_drop
: false,
804 kind
: hir
::GenericParamKind
::Lifetime { kind }
,
809 /// Lowers a lifetime binder that defines `generic_params`, returning the corresponding HIR
810 /// nodes. The returned list includes any "extra" lifetime parameters that were added by the
811 /// name resolver owing to lifetime elision; this also populates the resolver's node-id->def-id
812 /// map, so that later calls to `opt_node_id_to_def_id` that refer to these extra lifetime
813 /// parameters will be successful.
814 #[tracing::instrument(level = "debug", skip(self))]
816 fn lower_lifetime_binder(
819 generic_params
: &[GenericParam
],
820 ) -> &'hir
[hir
::GenericParam
<'hir
>] {
821 let mut generic_params
: Vec
<_
> = self.lower_generic_params_mut(generic_params
).collect();
822 let extra_lifetimes
= self.resolver
.take_extra_lifetime_params(binder
);
823 debug
!(?extra_lifetimes
);
824 generic_params
.extend(extra_lifetimes
.into_iter().filter_map(|(ident
, node_id
, res
)| {
825 self.lifetime_res_to_generic_param(ident
, node_id
, res
)
827 let generic_params
= self.arena
.alloc_from_iter(generic_params
);
828 debug
!(?generic_params
);
833 fn with_dyn_type_scope
<T
>(&mut self, in_scope
: bool
, f
: impl FnOnce(&mut Self) -> T
) -> T
{
834 let was_in_dyn_type
= self.is_in_dyn_type
;
835 self.is_in_dyn_type
= in_scope
;
837 let result
= f(self);
839 self.is_in_dyn_type
= was_in_dyn_type
;
844 fn with_new_scopes
<T
>(&mut self, f
: impl FnOnce(&mut Self) -> T
) -> T
{
845 let was_in_loop_condition
= self.is_in_loop_condition
;
846 self.is_in_loop_condition
= false;
848 let catch_scope
= self.catch_scope
.take();
849 let loop_scope
= self.loop_scope
.take();
851 self.catch_scope
= catch_scope
;
852 self.loop_scope
= loop_scope
;
854 self.is_in_loop_condition
= was_in_loop_condition
;
859 fn lower_attrs(&mut self, id
: hir
::HirId
, attrs
: &[Attribute
]) -> Option
<&'hir
[Attribute
]> {
860 if attrs
.is_empty() {
863 debug_assert_eq
!(id
.owner
, self.current_hir_id_owner
);
864 let ret
= self.arena
.alloc_from_iter(attrs
.iter().map(|a
| self.lower_attr(a
)));
865 debug_assert
!(!ret
.is_empty());
866 self.attrs
.insert(id
.local_id
, ret
);
871 fn lower_attr(&self, attr
: &Attribute
) -> Attribute
{
872 // Note that we explicitly do not walk the path. Since we don't really
873 // lower attributes (we use the AST version) there is nowhere to keep
874 // the `HirId`s. We don't actually need HIR version of attributes anyway.
875 // Tokens are also not needed after macro expansion and parsing.
876 let kind
= match attr
.kind
{
877 AttrKind
::Normal(ref item
, _
) => AttrKind
::Normal(
879 path
: item
.path
.clone(),
880 args
: self.lower_mac_args(&item
.args
),
885 AttrKind
::DocComment(comment_kind
, data
) => AttrKind
::DocComment(comment_kind
, data
),
888 Attribute { kind, id: attr.id, style: attr.style, span: self.lower_span(attr.span) }
891 fn alias_attrs(&mut self, id
: hir
::HirId
, target_id
: hir
::HirId
) {
892 debug_assert_eq
!(id
.owner
, self.current_hir_id_owner
);
893 debug_assert_eq
!(target_id
.owner
, self.current_hir_id_owner
);
894 if let Some(&a
) = self.attrs
.get(&target_id
.local_id
) {
895 debug_assert
!(!a
.is_empty());
896 self.attrs
.insert(id
.local_id
, a
);
900 fn lower_mac_args(&self, args
: &MacArgs
) -> MacArgs
{
902 MacArgs
::Empty
=> MacArgs
::Empty
,
903 MacArgs
::Delimited(dspan
, delim
, ref tokens
) => {
904 // This is either a non-key-value attribute, or a `macro_rules!` body.
905 // We either not have any nonterminals present (in the case of an attribute),
906 // or have tokens available for all nonterminals in the case of a nested
907 // `macro_rules`: e.g:
910 // macro_rules! outer {
912 // macro_rules! inner {
919 // In both cases, we don't want to synthesize any tokens
920 MacArgs
::Delimited(dspan
, delim
, tokens
.flattened())
922 // This is an inert key-value attribute - it will never be visible to macros
923 // after it gets lowered to HIR. Therefore, we can extract literals to handle
924 // nonterminals in `#[doc]` (e.g. `#[doc = $e]`).
925 MacArgs
::Eq(eq_span
, MacArgsEq
::Ast(ref expr
)) => {
926 // In valid code the value always ends up as a single literal. Otherwise, a dummy
927 // literal suffices because the error is handled elsewhere.
928 let lit
= if let ExprKind
::Lit(lit
) = &expr
.kind
{
932 token
: token
::Lit
::new(token
::LitKind
::Err
, kw
::Empty
, None
),
933 kind
: LitKind
::Err(kw
::Empty
),
937 MacArgs
::Eq(eq_span
, MacArgsEq
::Hir(lit
))
939 MacArgs
::Eq(_
, MacArgsEq
::Hir(ref lit
)) => {
940 unreachable
!("in literal form when lowering mac args eq: {:?}", lit
)
945 /// Given an associated type constraint like one of these:
947 /// ```ignore (illustrative)
948 /// T: Iterator<Item: Debug>
950 /// T: Iterator<Item = Debug>
954 /// returns a `hir::TypeBinding` representing `Item`.
955 #[instrument(level = "debug", skip(self))]
956 fn lower_assoc_ty_constraint(
958 constraint
: &AssocConstraint
,
959 itctx
: ImplTraitContext
,
960 ) -> hir
::TypeBinding
<'hir
> {
961 debug
!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint
, itctx
);
962 // lower generic arguments of identifier in constraint
963 let gen_args
= if let Some(ref gen_args
) = constraint
.gen_args
{
964 let gen_args_ctor
= match gen_args
{
965 GenericArgs
::AngleBracketed(ref data
) => {
966 self.lower_angle_bracketed_parameter_data(data
, ParamMode
::Explicit
, itctx
).0
968 GenericArgs
::Parenthesized(ref data
) => {
969 self.emit_bad_parenthesized_trait_in_assoc_ty(data
);
970 self.lower_angle_bracketed_parameter_data(
971 &data
.as_angle_bracketed_args(),
978 gen_args_ctor
.into_generic_args(self)
980 self.arena
.alloc(hir
::GenericArgs
::none())
983 let kind
= match constraint
.kind
{
984 AssocConstraintKind
::Equality { ref term }
=> {
985 let term
= match term
{
986 Term
::Ty(ref ty
) => self.lower_ty(ty
, itctx
).into(),
987 Term
::Const(ref c
) => self.lower_anon_const(c
).into(),
989 hir
::TypeBindingKind
::Equality { term }
991 AssocConstraintKind
::Bound { ref bounds }
=> {
992 // Piggy-back on the `impl Trait` context to figure out the correct behavior.
993 let (desugar_to_impl_trait
, itctx
) = match itctx
{
994 // We are in the return position:
996 // fn foo() -> impl Iterator<Item: Debug>
1000 // fn foo() -> impl Iterator<Item = impl Debug>
1001 ImplTraitContext
::ReturnPositionOpaqueTy { .. }
1002 | ImplTraitContext
::TypeAliasesOpaqueTy { .. }
=> (true, itctx
),
1004 // We are in the argument position, but within a dyn type:
1006 // fn foo(x: dyn Iterator<Item: Debug>)
1010 // fn foo(x: dyn Iterator<Item = impl Debug>)
1011 ImplTraitContext
::Universal
if self.is_in_dyn_type
=> (true, itctx
),
1013 // In `type Foo = dyn Iterator<Item: Debug>` we desugar to
1014 // `type Foo = dyn Iterator<Item = impl Debug>` but we have to override the
1015 // "impl trait context" to permit `impl Debug` in this position (it desugars
1016 // then to an opaque type).
1018 // FIXME: this is only needed until `impl Trait` is allowed in type aliases.
1019 ImplTraitContext
::Disallowed(_
) if self.is_in_dyn_type
=> {
1020 (true, ImplTraitContext
::TypeAliasesOpaqueTy
)
1023 // We are in the parameter position, but not within a dyn type:
1025 // fn foo(x: impl Iterator<Item: Debug>)
1027 // so we leave it as is and this gets expanded in astconv to a bound like
1028 // `<T as Iterator>::Item: Debug` where `T` is the type parameter for the
1030 _
=> (false, itctx
),
1033 if desugar_to_impl_trait
{
1034 // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by
1035 // constructing the HIR for `impl bounds...` and then lowering that.
1037 let parent_def_id
= self.current_hir_id_owner
;
1038 let impl_trait_node_id
= self.next_node_id();
1039 self.create_def(parent_def_id
, impl_trait_node_id
, DefPathData
::ImplTrait
);
1041 self.with_dyn_type_scope(false, |this
| {
1042 let node_id
= this
.next_node_id();
1043 let ty
= this
.lower_ty(
1046 kind
: TyKind
::ImplTrait(impl_trait_node_id
, bounds
.clone()),
1047 span
: this
.lower_span(constraint
.span
),
1053 hir
::TypeBindingKind
::Equality { term: ty.into() }
1056 // Desugar `AssocTy: Bounds` into a type binding where the
1057 // later desugars into a trait predicate.
1058 let bounds
= self.lower_param_bounds(bounds
, itctx
);
1060 hir
::TypeBindingKind
::Constraint { bounds }
1066 hir_id
: self.lower_node_id(constraint
.id
),
1067 ident
: self.lower_ident(constraint
.ident
),
1070 span
: self.lower_span(constraint
.span
),
1074 fn emit_bad_parenthesized_trait_in_assoc_ty(&self, data
: &ParenthesizedArgs
) {
1075 let mut err
= self.tcx
.sess
.struct_span_err(
1077 "parenthesized generic arguments cannot be used in associated type constraints",
1079 // Suggest removing empty parentheses: "Trait()" -> "Trait"
1080 if data
.inputs
.is_empty() {
1081 let parentheses_span
=
1082 data
.inputs_span
.shrink_to_lo().to(data
.inputs_span
.shrink_to_hi());
1083 err
.multipart_suggestion(
1084 "remove these parentheses",
1085 vec
![(parentheses_span
, String
::new())],
1086 Applicability
::MaybeIncorrect
,
1089 // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
1091 // Start of parameters to the 1st argument
1092 let open_param
= data
.inputs_span
.shrink_to_lo().to(data
1098 // End of last argument to end of parameters
1100 data
.inputs
.last().unwrap().span
.shrink_to_hi().to(data
.inputs_span
.shrink_to_hi());
1101 err
.multipart_suggestion(
1102 &format
!("use angle brackets instead",),
1103 vec
![(open_param
, String
::from("<")), (close_param
, String
::from(">"))],
1104 Applicability
::MaybeIncorrect
,
1110 #[instrument(level = "debug", skip(self))]
1111 fn lower_generic_arg(
1113 arg
: &ast
::GenericArg
,
1114 itctx
: ImplTraitContext
,
1115 ) -> hir
::GenericArg
<'hir
> {
1117 ast
::GenericArg
::Lifetime(lt
) => GenericArg
::Lifetime(self.lower_lifetime(<
)),
1118 ast
::GenericArg
::Type(ty
) => {
1120 TyKind
::Infer
if self.tcx
.features().generic_arg_infer
=> {
1121 return GenericArg
::Infer(hir
::InferArg
{
1122 hir_id
: self.lower_node_id(ty
.id
),
1123 span
: self.lower_span(ty
.span
),
1126 // We parse const arguments as path types as we cannot distinguish them during
1127 // parsing. We try to resolve that ambiguity by attempting resolution in both the
1128 // type and value namespaces. If we resolved the path in the value namespace, we
1129 // transform it into a generic const argument.
1130 TyKind
::Path(ref qself
, ref path
) => {
1131 if let Some(partial_res
) = self.resolver
.get_partial_res(ty
.id
) {
1132 let res
= partial_res
.base_res();
1133 if !res
.matches_ns(Namespace
::TypeNS
) {
1135 "lower_generic_arg: Lowering type argument as const argument: {:?}",
1139 // Construct an AnonConst where the expr is the "ty"'s path.
1141 let parent_def_id
= self.current_hir_id_owner
;
1142 let node_id
= self.next_node_id();
1144 // Add a definition for the in-band const def.
1145 self.create_def(parent_def_id
, node_id
, DefPathData
::AnonConst
);
1147 let span
= self.lower_span(ty
.span
);
1148 let path_expr
= Expr
{
1150 kind
: ExprKind
::Path(qself
.clone(), path
.clone()),
1152 attrs
: AttrVec
::new(),
1156 let ct
= self.with_new_scopes(|this
| hir
::AnonConst
{
1157 hir_id
: this
.lower_node_id(node_id
),
1158 body
: this
.lower_const_body(path_expr
.span
, Some(&path_expr
)),
1160 return GenericArg
::Const(ConstArg { value: ct, span }
);
1166 GenericArg
::Type(self.lower_ty_direct(&ty
, itctx
))
1168 ast
::GenericArg
::Const(ct
) => GenericArg
::Const(ConstArg
{
1169 value
: self.lower_anon_const(&ct
),
1170 span
: self.lower_span(ct
.value
.span
),
1175 #[instrument(level = "debug", skip(self))]
1176 fn lower_ty(&mut self, t
: &Ty
, itctx
: ImplTraitContext
) -> &'hir hir
::Ty
<'hir
> {
1177 self.arena
.alloc(self.lower_ty_direct(t
, itctx
))
1183 qself
: &Option
<QSelf
>,
1185 param_mode
: ParamMode
,
1186 itctx
: ImplTraitContext
,
1187 ) -> hir
::Ty
<'hir
> {
1188 // Check whether we should interpret this as a bare trait object.
1189 // This check mirrors the one in late resolution. We only introduce this special case in
1190 // the rare occurence we need to lower `Fresh` anonymous lifetimes.
1191 // The other cases when a qpath should be opportunistically made a trait object are handled
1194 && let Some(partial_res
) = self.resolver
.get_partial_res(t
.id
)
1195 && partial_res
.unresolved_segments() == 0
1196 && let Res
::Def(DefKind
::Trait
| DefKind
::TraitAlias
, _
) = partial_res
.base_res()
1198 let (bounds
, lifetime_bound
) = self.with_dyn_type_scope(true, |this
| {
1199 let bound
= this
.lower_poly_trait_ref(
1201 bound_generic_params
: vec
![],
1202 trait_ref
: TraitRef { path: path.clone(), ref_id: t.id }
,
1207 let bounds
= this
.arena
.alloc_from_iter([bound
]);
1208 let lifetime_bound
= this
.elided_dyn_bound(t
.span
);
1209 (bounds
, lifetime_bound
)
1211 let kind
= hir
::TyKind
::TraitObject(bounds
, lifetime_bound
, TraitObjectSyntax
::None
);
1212 return hir
::Ty { kind, span: self.lower_span(t.span), hir_id: self.next_id() }
;
1215 let id
= self.lower_node_id(t
.id
);
1216 let qpath
= self.lower_qpath(t
.id
, qself
, path
, param_mode
, itctx
);
1217 self.ty_path(id
, t
.span
, qpath
)
1220 fn ty(&mut self, span
: Span
, kind
: hir
::TyKind
<'hir
>) -> hir
::Ty
<'hir
> {
1221 hir
::Ty { hir_id: self.next_id(), kind, span: self.lower_span(span) }
1224 fn ty_tup(&mut self, span
: Span
, tys
: &'hir
[hir
::Ty
<'hir
>]) -> hir
::Ty
<'hir
> {
1225 self.ty(span
, hir
::TyKind
::Tup(tys
))
1228 fn lower_ty_direct(&mut self, t
: &Ty
, itctx
: ImplTraitContext
) -> hir
::Ty
<'hir
> {
1229 let kind
= match t
.kind
{
1230 TyKind
::Infer
=> hir
::TyKind
::Infer
,
1231 TyKind
::Err
=> hir
::TyKind
::Err
,
1232 TyKind
::Slice(ref ty
) => hir
::TyKind
::Slice(self.lower_ty(ty
, itctx
)),
1233 TyKind
::Ptr(ref mt
) => hir
::TyKind
::Ptr(self.lower_mt(mt
, itctx
)),
1234 TyKind
::Rptr(ref region
, ref mt
) => {
1235 let region
= region
.unwrap_or_else(|| {
1236 let id
= if let Some(LifetimeRes
::ElidedAnchor { start, end }
) =
1237 self.resolver
.get_lifetime_res(t
.id
)
1239 debug_assert_eq
!(start
.plus(1), end
);
1244 let span
= self.tcx
.sess
.source_map().next_point(t
.span
.shrink_to_lo());
1245 Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id }
1247 let lifetime
= self.lower_lifetime(®ion
);
1248 hir
::TyKind
::Rptr(lifetime
, self.lower_mt(mt
, itctx
))
1250 TyKind
::BareFn(ref f
) => {
1251 let generic_params
= self.lower_lifetime_binder(t
.id
, &f
.generic_params
);
1252 hir
::TyKind
::BareFn(self.arena
.alloc(hir
::BareFnTy
{
1254 unsafety
: self.lower_unsafety(f
.unsafety
),
1255 abi
: self.lower_extern(f
.ext
),
1256 decl
: self.lower_fn_decl(&f
.decl
, None
, FnDeclKind
::Pointer
, None
),
1257 param_names
: self.lower_fn_params_to_names(&f
.decl
),
1260 TyKind
::Never
=> hir
::TyKind
::Never
,
1261 TyKind
::Tup(ref tys
) => hir
::TyKind
::Tup(
1262 self.arena
.alloc_from_iter(tys
.iter().map(|ty
| self.lower_ty_direct(ty
, itctx
))),
1264 TyKind
::Paren(ref ty
) => {
1265 return self.lower_ty_direct(ty
, itctx
);
1267 TyKind
::Path(ref qself
, ref path
) => {
1268 return self.lower_path_ty(t
, qself
, path
, ParamMode
::Explicit
, itctx
);
1270 TyKind
::ImplicitSelf
=> {
1271 let res
= self.expect_full_res(t
.id
);
1272 let res
= self.lower_res(res
);
1273 hir
::TyKind
::Path(hir
::QPath
::Resolved(
1275 self.arena
.alloc(hir
::Path
{
1277 segments
: arena_vec
![self; hir
::PathSegment
::from_ident(
1278 Ident
::with_dummy_span(kw
::SelfUpper
)
1280 span
: self.lower_span(t
.span
),
1284 TyKind
::Array(ref ty
, ref length
) => {
1285 hir
::TyKind
::Array(self.lower_ty(ty
, itctx
), self.lower_array_length(length
))
1287 TyKind
::Typeof(ref expr
) => hir
::TyKind
::Typeof(self.lower_anon_const(expr
)),
1288 TyKind
::TraitObject(ref bounds
, kind
) => {
1289 let mut lifetime_bound
= None
;
1290 let (bounds
, lifetime_bound
) = self.with_dyn_type_scope(true, |this
| {
1292 this
.arena
.alloc_from_iter(bounds
.iter().filter_map(
1293 |bound
| match *bound
{
1294 GenericBound
::Trait(
1296 TraitBoundModifier
::None
| TraitBoundModifier
::MaybeConst
,
1297 ) => Some(this
.lower_poly_trait_ref(ty
, itctx
)),
1298 // `~const ?Bound` will cause an error during AST validation
1299 // anyways, so treat it like `?Bound` as compilation proceeds.
1300 GenericBound
::Trait(
1302 TraitBoundModifier
::Maybe
| TraitBoundModifier
::MaybeConstMaybe
,
1304 GenericBound
::Outlives(ref lifetime
) => {
1305 if lifetime_bound
.is_none() {
1306 lifetime_bound
= Some(this
.lower_lifetime(lifetime
));
1312 let lifetime_bound
=
1313 lifetime_bound
.unwrap_or_else(|| this
.elided_dyn_bound(t
.span
));
1314 (bounds
, lifetime_bound
)
1316 hir
::TyKind
::TraitObject(bounds
, lifetime_bound
, kind
)
1318 TyKind
::ImplTrait(def_node_id
, ref bounds
) => {
1321 ImplTraitContext
::ReturnPositionOpaqueTy { origin }
=> {
1322 self.lower_opaque_impl_trait(span
, origin
, def_node_id
, bounds
, itctx
)
1324 ImplTraitContext
::TypeAliasesOpaqueTy
=> {
1325 let nested_itctx
= ImplTraitContext
::TypeAliasesOpaqueTy
;
1326 self.lower_opaque_impl_trait(
1328 hir
::OpaqueTyOrigin
::TyAlias
,
1334 ImplTraitContext
::Universal
=> {
1336 let ident
= Ident
::from_str_and_span(&pprust
::ty_to_string(t
), span
);
1337 let (param
, bounds
, path
) =
1338 self.lower_generic_and_bounds(def_node_id
, span
, ident
, bounds
);
1339 self.impl_trait_defs
.push(param
);
1340 if let Some(bounds
) = bounds
{
1341 self.impl_trait_bounds
.push(bounds
);
1345 ImplTraitContext
::Disallowed(position
) => {
1346 let mut err
= struct_span_err
!(
1350 "`impl Trait` only allowed in function and inherent method return types, not in {}",
1358 TyKind
::MacCall(_
) => panic
!("`TyKind::MacCall` should have been expanded by now"),
1359 TyKind
::CVarArgs
=> {
1360 self.tcx
.sess
.delay_span_bug(
1362 "`TyKind::CVarArgs` should have been handled elsewhere",
1368 hir
::Ty { kind, span: self.lower_span(t.span), hir_id: self.lower_node_id(t.id) }
1371 /// Lowers a `ReturnPositionOpaqueTy` (`-> impl Trait`) or a `TypeAliasesOpaqueTy` (`type F =
1372 /// impl Trait`): this creates the associated Opaque Type (TAIT) definition and then returns a
1373 /// HIR type that references the TAIT.
1375 /// Given a function definition like:
1378 /// fn test<'a, T: Debug>(x: &'a T) -> impl Debug + 'a {
1383 /// we will create a TAIT definition in the HIR like
1386 /// type TestReturn<'a, T, 'x> = impl Debug + 'x
1389 /// and return a type like `TestReturn<'static, T, 'a>`, so that the function looks like:
1392 /// fn test<'a, T: Debug>(x: &'a T) -> TestReturn<'static, T, 'a>
1395 /// Note the subtlety around type parameters! The new TAIT, `TestReturn`, inherits all the
1396 /// type parameters from the function `test` (this is implemented in the query layer, they aren't
1397 /// added explicitly in the HIR). But this includes all the lifetimes, and we only want to
1398 /// capture the lifetimes that are referenced in the bounds. Therefore, we add *extra* lifetime parameters
1399 /// for the lifetimes that get captured (`'x`, in our example above) and reference those.
1400 #[tracing::instrument(level = "debug", skip(self))]
1401 fn lower_opaque_impl_trait(
1404 origin
: hir
::OpaqueTyOrigin
,
1405 opaque_ty_node_id
: NodeId
,
1406 bounds
: &GenericBounds
,
1407 itctx
: ImplTraitContext
,
1408 ) -> hir
::TyKind
<'hir
> {
1409 // Make sure we know that some funky desugaring has been going on here.
1410 // This is a first: there is code in other places like for loop
1411 // desugaring that explicitly states that we don't want to track that.
1412 // Not tracking it makes lints in rustc and clippy very fragile, as
1413 // frequently opened issues show.
1414 let opaque_ty_span
= self.mark_span_with_reason(DesugaringKind
::OpaqueTy
, span
, None
);
1416 let opaque_ty_def_id
= self.local_def_id(opaque_ty_node_id
);
1417 debug
!(?opaque_ty_def_id
);
1419 // Contains the new lifetime definitions created for the TAIT (if any).
1420 let mut collected_lifetimes
= Vec
::new();
1422 // If this came from a TAIT (as opposed to a function that returns an RPIT), we only want
1423 // to capture the lifetimes that appear in the bounds. So visit the bounds to find out
1424 // exactly which ones those are.
1425 let lifetimes_to_remap
= if origin
== hir
::OpaqueTyOrigin
::TyAlias
{
1426 // in a TAIT like `type Foo<'a> = impl Foo<'a>`, we don't keep all the lifetime parameters
1429 // in fn return position, like the `fn test<'a>() -> impl Debug + 'a` example,
1430 // we only keep the lifetimes that appear in the `impl Debug` itself:
1431 lifetime_collector
::lifetimes_in_bounds(&self.resolver
, bounds
)
1433 debug
!(?lifetimes_to_remap
);
1435 self.with_hir_id_owner(opaque_ty_node_id
, |lctx
| {
1436 let mut new_remapping
= FxHashMap
::default();
1438 // If this opaque type is only capturing a subset of the lifetimes (those that appear
1439 // in bounds), then create the new lifetime parameters required and create a mapping
1440 // from the old `'a` (on the function) to the new `'a` (on the opaque type).
1441 collected_lifetimes
= lctx
.create_lifetime_defs(
1443 &lifetimes_to_remap
,
1446 debug
!(?collected_lifetimes
);
1447 debug
!(?new_remapping
);
1449 // Install the remapping from old to new (if any):
1450 lctx
.with_remapping(new_remapping
, |lctx
| {
1451 // This creates HIR lifetime definitions as `hir::GenericParam`, in the given
1452 // example `type TestReturn<'a, T, 'x> = impl Debug + 'x`, it creates a collection
1453 // containing `&['x]`.
1454 let lifetime_defs
= lctx
.arena
.alloc_from_iter(collected_lifetimes
.iter().map(
1455 |&(new_node_id
, lifetime
)| {
1456 let hir_id
= lctx
.lower_node_id(new_node_id
);
1457 debug_assert_ne
!(lctx
.opt_local_def_id(new_node_id
), None
);
1459 let (name
, kind
) = if lifetime
.ident
.name
== kw
::UnderscoreLifetime
{
1460 (hir
::ParamName
::Fresh
, hir
::LifetimeParamKind
::Elided
)
1463 hir
::ParamName
::Plain(lifetime
.ident
),
1464 hir
::LifetimeParamKind
::Explicit
,
1471 span
: lifetime
.ident
.span
,
1472 pure_wrt_drop
: false,
1473 kind
: hir
::GenericParamKind
::Lifetime { kind }
,
1478 debug
!(?lifetime_defs
);
1480 // Then when we lower the param bounds, references to 'a are remapped to 'a1, so we
1481 // get back Debug + 'a1, which is suitable for use on the TAIT.
1482 let hir_bounds
= lctx
.lower_param_bounds(bounds
, itctx
);
1483 debug
!(?hir_bounds
);
1485 let opaque_ty_item
= hir
::OpaqueTy
{
1486 generics
: self.arena
.alloc(hir
::Generics
{
1487 params
: lifetime_defs
,
1489 has_where_clause_predicates
: false,
1490 where_clause_span
: lctx
.lower_span(span
),
1491 span
: lctx
.lower_span(span
),
1496 debug
!(?opaque_ty_item
);
1498 lctx
.generate_opaque_type(opaque_ty_def_id
, opaque_ty_item
, span
, opaque_ty_span
)
1502 // This creates HIR lifetime arguments as `hir::GenericArg`, in the given example `type
1503 // TestReturn<'a, T, 'x> = impl Debug + 'x`, it creates a collection containing `&['x]`.
1505 self.arena
.alloc_from_iter(collected_lifetimes
.into_iter().map(|(_
, lifetime
)| {
1506 let id
= self.next_node_id();
1507 let span
= lifetime
.ident
.span
;
1509 let ident
= if lifetime
.ident
.name
== kw
::UnderscoreLifetime
{
1510 Ident
::with_dummy_span(kw
::UnderscoreLifetime
)
1515 let l
= self.new_named_lifetime(lifetime
.id
, id
, span
, ident
);
1516 hir
::GenericArg
::Lifetime(l
)
1520 // `impl Trait` now just becomes `Foo<'a, 'b, ..>`.
1521 hir
::TyKind
::OpaqueDef(hir
::ItemId { def_id: opaque_ty_def_id }
, lifetimes
)
1524 /// Registers a new opaque type with the proper `NodeId`s and
1525 /// returns the lowered node-ID for the opaque type.
1526 fn generate_opaque_type(
1528 opaque_ty_id
: LocalDefId
,
1529 opaque_ty_item
: hir
::OpaqueTy
<'hir
>,
1531 opaque_ty_span
: Span
,
1532 ) -> hir
::OwnerNode
<'hir
> {
1533 let opaque_ty_item_kind
= hir
::ItemKind
::OpaqueTy(opaque_ty_item
);
1534 // Generate an `type Foo = impl Trait;` declaration.
1535 trace
!("registering opaque type with id {:#?}", opaque_ty_id
);
1536 let opaque_ty_item
= hir
::Item
{
1537 def_id
: opaque_ty_id
,
1538 ident
: Ident
::empty(),
1539 kind
: opaque_ty_item_kind
,
1540 vis_span
: self.lower_span(span
.shrink_to_lo()),
1541 span
: self.lower_span(opaque_ty_span
),
1543 hir
::OwnerNode
::Item(self.arena
.alloc(opaque_ty_item
))
1546 /// Given a `parent_def_id`, a list of `lifetimes_in_bounds and a `remapping` hash to be
1547 /// filled, this function creates new definitions for `Param` and `Fresh` lifetimes, inserts the
1548 /// new definition, adds it to the remapping with the definition of the given lifetime and
1549 /// returns a list of lifetimes to be lowered afterwards.
1550 fn create_lifetime_defs(
1552 parent_def_id
: LocalDefId
,
1553 lifetimes_in_bounds
: &[Lifetime
],
1554 remapping
: &mut FxHashMap
<LocalDefId
, LocalDefId
>,
1555 ) -> Vec
<(NodeId
, Lifetime
)> {
1556 let mut result
= Vec
::new();
1558 for lifetime
in lifetimes_in_bounds
{
1559 let res
= self.resolver
.get_lifetime_res(lifetime
.id
).unwrap_or(LifetimeRes
::Error
);
1563 LifetimeRes
::Param { param: old_def_id, binder: _ }
=> {
1564 if remapping
.get(&old_def_id
).is_none() {
1565 let node_id
= self.next_node_id();
1567 let new_def_id
= self.create_def(
1570 DefPathData
::LifetimeNs(lifetime
.ident
.name
),
1572 remapping
.insert(old_def_id
, new_def_id
);
1574 result
.push((node_id
, *lifetime
));
1578 LifetimeRes
::Fresh { param, binder: _ }
=> {
1579 debug_assert_eq
!(lifetime
.ident
.name
, kw
::UnderscoreLifetime
);
1580 if let Some(old_def_id
) = self.opt_local_def_id(param
) && remapping
.get(&old_def_id
).is_none() {
1581 let node_id
= self.next_node_id();
1583 let new_def_id
= self.create_def(
1586 DefPathData
::LifetimeNs(kw
::UnderscoreLifetime
),
1588 remapping
.insert(old_def_id
, new_def_id
);
1590 result
.push((node_id
, *lifetime
));
1594 LifetimeRes
::Static
| LifetimeRes
::Error
=> {}
1597 let bug_msg
= format
!(
1598 "Unexpected lifetime resolution {:?} for {:?} at {:?}",
1599 res
, lifetime
.ident
, lifetime
.ident
.span
1601 span_bug
!(lifetime
.ident
.span
, "{}", bug_msg
);
1609 fn lower_fn_params_to_names(&mut self, decl
: &FnDecl
) -> &'hir
[Ident
] {
1610 // Skip the `...` (`CVarArgs`) trailing arguments from the AST,
1611 // as they are not explicit in HIR/Ty function signatures.
1612 // (instead, the `c_variadic` flag is set to `true`)
1613 let mut inputs
= &decl
.inputs
[..];
1614 if decl
.c_variadic() {
1615 inputs
= &inputs
[..inputs
.len() - 1];
1617 self.arena
.alloc_from_iter(inputs
.iter().map(|param
| match param
.pat
.kind
{
1618 PatKind
::Ident(_
, ident
, _
) => self.lower_ident(ident
),
1619 _
=> Ident
::new(kw
::Empty
, self.lower_span(param
.pat
.span
)),
1623 // Lowers a function declaration.
1625 // `decl`: the unlowered (AST) function declaration.
1626 // `fn_def_id`: if `Some`, impl Trait arguments are lowered into generic parameters on the
1627 // given DefId, otherwise impl Trait is disallowed. Must be `Some` if
1628 // `make_ret_async` is also `Some`.
1629 // `impl_trait_return_allow`: determines whether `impl Trait` can be used in return position.
1630 // This guards against trait declarations and implementations where `impl Trait` is
1632 // `make_ret_async`: if `Some`, converts `-> T` into `-> impl Future<Output = T>` in the
1633 // return type. This is used for `async fn` declarations. The `NodeId` is the ID of the
1634 // return type `impl Trait` item.
1635 #[tracing::instrument(level = "debug", skip(self))]
1639 fn_node_id
: Option
<NodeId
>,
1641 make_ret_async
: Option
<NodeId
>,
1642 ) -> &'hir hir
::FnDecl
<'hir
> {
1643 let c_variadic
= decl
.c_variadic();
1645 // Skip the `...` (`CVarArgs`) trailing arguments from the AST,
1646 // as they are not explicit in HIR/Ty function signatures.
1647 // (instead, the `c_variadic` flag is set to `true`)
1648 let mut inputs
= &decl
.inputs
[..];
1650 inputs
= &inputs
[..inputs
.len() - 1];
1652 let inputs
= self.arena
.alloc_from_iter(inputs
.iter().map(|param
| {
1653 if fn_node_id
.is_some() {
1654 self.lower_ty_direct(¶m
.ty
, ImplTraitContext
::Universal
)
1656 self.lower_ty_direct(
1658 ImplTraitContext
::Disallowed(match kind
{
1659 FnDeclKind
::Fn
| FnDeclKind
::Inherent
=> {
1660 unreachable
!("fn should allow in-band lifetimes")
1662 FnDeclKind
::ExternFn
=> ImplTraitPosition
::ExternFnParam
,
1663 FnDeclKind
::Closure
=> ImplTraitPosition
::ClosureParam
,
1664 FnDeclKind
::Pointer
=> ImplTraitPosition
::PointerParam
,
1665 FnDeclKind
::Trait
=> ImplTraitPosition
::TraitParam
,
1666 FnDeclKind
::Impl
=> ImplTraitPosition
::ImplParam
,
1672 let output
= if let Some(ret_id
) = make_ret_async
{
1673 self.lower_async_fn_ret_ty(
1675 fn_node_id
.expect("`make_ret_async` but no `fn_def_id`"),
1680 FnRetTy
::Ty(ref ty
) => {
1681 let context
= match fn_node_id
{
1682 Some(fn_node_id
) if kind
.impl_trait_return_allowed() => {
1683 let fn_def_id
= self.local_def_id(fn_node_id
);
1684 ImplTraitContext
::ReturnPositionOpaqueTy
{
1685 origin
: hir
::OpaqueTyOrigin
::FnReturn(fn_def_id
),
1688 _
=> ImplTraitContext
::Disallowed(match kind
{
1689 FnDeclKind
::Fn
| FnDeclKind
::Inherent
=> {
1690 unreachable
!("fn should allow in-band lifetimes")
1692 FnDeclKind
::ExternFn
=> ImplTraitPosition
::ExternFnReturn
,
1693 FnDeclKind
::Closure
=> ImplTraitPosition
::ClosureReturn
,
1694 FnDeclKind
::Pointer
=> ImplTraitPosition
::PointerReturn
,
1695 FnDeclKind
::Trait
=> ImplTraitPosition
::TraitReturn
,
1696 FnDeclKind
::Impl
=> ImplTraitPosition
::ImplReturn
,
1699 hir
::FnRetTy
::Return(self.lower_ty(ty
, context
))
1701 FnRetTy
::Default(span
) => hir
::FnRetTy
::DefaultReturn(self.lower_span(span
)),
1705 self.arena
.alloc(hir
::FnDecl
{
1709 implicit_self
: decl
.inputs
.get(0).map_or(hir
::ImplicitSelfKind
::None
, |arg
| {
1710 use BindingMode
::{ByRef, ByValue}
;
1711 let is_mutable_pat
= matches
!(
1713 PatKind
::Ident(ByValue(Mutability
::Mut
) | ByRef(Mutability
::Mut
), ..)
1717 TyKind
::ImplicitSelf
if is_mutable_pat
=> hir
::ImplicitSelfKind
::Mut
,
1718 TyKind
::ImplicitSelf
=> hir
::ImplicitSelfKind
::Imm
,
1719 // Given we are only considering `ImplicitSelf` types, we needn't consider
1720 // the case where we have a mutable pattern to a reference as that would
1721 // no longer be an `ImplicitSelf`.
1722 TyKind
::Rptr(_
, ref mt
)
1723 if mt
.ty
.kind
.is_implicit_self() && mt
.mutbl
== ast
::Mutability
::Mut
=>
1725 hir
::ImplicitSelfKind
::MutRef
1727 TyKind
::Rptr(_
, ref mt
) if mt
.ty
.kind
.is_implicit_self() => {
1728 hir
::ImplicitSelfKind
::ImmRef
1730 _
=> hir
::ImplicitSelfKind
::None
,
1736 // Transforms `-> T` for `async fn` into `-> OpaqueTy { .. }`
1737 // combined with the following definition of `OpaqueTy`:
1739 // type OpaqueTy<generics_from_parent_fn> = impl Future<Output = T>;
1741 // `output`: unlowered output type (`T` in `-> T`)
1742 // `fn_def_id`: `DefId` of the parent function (used to create child impl trait definition)
1743 // `opaque_ty_node_id`: `NodeId` of the opaque `impl Trait` type that should be created
1744 #[tracing::instrument(level = "debug", skip(self))]
1745 fn lower_async_fn_ret_ty(
1749 opaque_ty_node_id
: NodeId
,
1750 ) -> hir
::FnRetTy
<'hir
> {
1751 let span
= output
.span();
1753 let opaque_ty_span
= self.mark_span_with_reason(DesugaringKind
::Async
, span
, None
);
1755 let opaque_ty_def_id
= self.local_def_id(opaque_ty_node_id
);
1756 let fn_def_id
= self.local_def_id(fn_node_id
);
1758 // When we create the opaque type for this async fn, it is going to have
1759 // to capture all the lifetimes involved in the signature (including in the
1760 // return type). This is done by introducing lifetime parameters for:
1762 // - all the explicitly declared lifetimes from the impl and function itself;
1763 // - all the elided lifetimes in the fn arguments;
1764 // - all the elided lifetimes in the return type.
1766 // So for example in this snippet:
1769 // impl<'a> Foo<'a> {
1770 // async fn bar<'b>(&self, x: &'b Vec<f64>, y: &str) -> &u32 {
1771 // // ^ '0 ^ '1 ^ '2
1772 // // elided lifetimes used below
1777 // we would create an opaque type like:
1780 // type Bar<'a, 'b, '0, '1, '2> = impl Future<Output = &'2 u32>;
1783 // and we would then desugar `bar` to the equivalent of:
1786 // impl<'a> Foo<'a> {
1787 // fn bar<'b, '0, '1>(&'0 self, x: &'b Vec<f64>, y: &'1 str) -> Bar<'a, 'b, '0, '1, '_>
1791 // Note that the final parameter to `Bar` is `'_`, not `'2` --
1792 // this is because the elided lifetimes from the return type
1793 // should be figured out using the ordinary elision rules, and
1794 // this desugaring achieves that.
1796 // Calculate all the lifetimes that should be captured
1797 // by the opaque type. This should include all in-scope
1798 // lifetime parameters, including those defined in-band.
1800 // Contains the new lifetime definitions created for the TAIT (if any) generated for the
1802 let mut collected_lifetimes
= Vec
::new();
1803 let mut new_remapping
= FxHashMap
::default();
1805 let extra_lifetime_params
= self.resolver
.take_extra_lifetime_params(opaque_ty_node_id
);
1806 debug
!(?extra_lifetime_params
);
1807 for (ident
, outer_node_id
, outer_res
) in extra_lifetime_params
{
1808 let outer_def_id
= self.local_def_id(outer_node_id
);
1809 let inner_node_id
= self.next_node_id();
1811 // Add a definition for the in scope lifetime def.
1812 let inner_def_id
= self.create_def(
1815 DefPathData
::LifetimeNs(ident
.name
),
1817 new_remapping
.insert(outer_def_id
, inner_def_id
);
1819 let inner_res
= match outer_res
{
1820 // Input lifetime like `'a`:
1821 LifetimeRes
::Param { param, .. }
=> {
1822 LifetimeRes
::Param { param, binder: fn_node_id }
1824 // Input lifetime like `'1`:
1825 LifetimeRes
::Fresh { param, .. }
=> {
1826 LifetimeRes
::Fresh { param, binder: fn_node_id }
1828 LifetimeRes
::Static
| LifetimeRes
::Error
=> continue,
1831 "Unexpected lifetime resolution {:?} for {:?} at {:?}",
1832 res
, ident
, ident
.span
1837 let lifetime
= Lifetime { id: outer_node_id, ident }
;
1838 collected_lifetimes
.push((inner_node_id
, lifetime
, Some(inner_res
)));
1841 debug
!(?collected_lifetimes
);
1843 // We only want to capture the lifetimes that appear in the bounds. So visit the bounds to
1844 // find out exactly which ones those are.
1845 // in fn return position, like the `fn test<'a>() -> impl Debug + 'a` example,
1846 // we only keep the lifetimes that appear in the `impl Debug` itself:
1847 let lifetimes_to_remap
= lifetime_collector
::lifetimes_in_ret_ty(&self.resolver
, output
);
1848 debug
!(?lifetimes_to_remap
);
1850 self.with_hir_id_owner(opaque_ty_node_id
, |this
| {
1851 // If this opaque type is only capturing a subset of the lifetimes (those that appear
1852 // in bounds), then create the new lifetime parameters required and create a mapping
1853 // from the old `'a` (on the function) to the new `'a` (on the opaque type).
1854 collected_lifetimes
.extend(
1855 this
.create_lifetime_defs(
1857 &lifetimes_to_remap
,
1861 .map(|(new_node_id
, lifetime
)| (new_node_id
, lifetime
, None
)),
1863 debug
!(?collected_lifetimes
);
1864 debug
!(?new_remapping
);
1866 // Install the remapping from old to new (if any):
1867 this
.with_remapping(new_remapping
, |this
| {
1868 // We have to be careful to get elision right here. The
1869 // idea is that we create a lifetime parameter for each
1870 // lifetime in the return type. So, given a return type
1871 // like `async fn foo(..) -> &[&u32]`, we lower to `impl
1872 // Future<Output = &'1 [ &'2 u32 ]>`.
1874 // Then, we will create `fn foo(..) -> Foo<'_, '_>`, and
1875 // hence the elision takes place at the fn site.
1877 this
.lower_async_fn_output_type_to_future_bound(output
, fn_def_id
, span
);
1879 let generic_params
= this
.arena
.alloc_from_iter(collected_lifetimes
.iter().map(
1880 |&(new_node_id
, lifetime
, _
)| {
1881 let hir_id
= this
.lower_node_id(new_node_id
);
1882 debug_assert_ne
!(this
.opt_local_def_id(new_node_id
), None
);
1884 let (name
, kind
) = if lifetime
.ident
.name
== kw
::UnderscoreLifetime
{
1885 (hir
::ParamName
::Fresh
, hir
::LifetimeParamKind
::Elided
)
1888 hir
::ParamName
::Plain(lifetime
.ident
),
1889 hir
::LifetimeParamKind
::Explicit
,
1896 span
: lifetime
.ident
.span
,
1897 pure_wrt_drop
: false,
1898 kind
: hir
::GenericParamKind
::Lifetime { kind }
,
1903 debug
!("lower_async_fn_ret_ty: generic_params={:#?}", generic_params
);
1905 let opaque_ty_item
= hir
::OpaqueTy
{
1906 generics
: this
.arena
.alloc(hir
::Generics
{
1907 params
: generic_params
,
1909 has_where_clause_predicates
: false,
1910 where_clause_span
: this
.lower_span(span
),
1911 span
: this
.lower_span(span
),
1913 bounds
: arena_vec
![this
; future_bound
],
1914 origin
: hir
::OpaqueTyOrigin
::AsyncFn(fn_def_id
),
1917 trace
!("exist ty from async fn def id: {:#?}", opaque_ty_def_id
);
1918 this
.generate_opaque_type(opaque_ty_def_id
, opaque_ty_item
, span
, opaque_ty_span
)
1922 // As documented above, we need to create the lifetime
1923 // arguments to our opaque type. Continuing with our example,
1924 // we're creating the type arguments for the return type:
1927 // Bar<'a, 'b, '0, '1, '_>
1930 // For the "input" lifetime parameters, we wish to create
1931 // references to the parameters themselves, including the
1932 // "implicit" ones created from parameter types (`'a`, `'b`,
1935 // For the "output" lifetime parameters, we just want to
1937 let generic_args
= self.arena
.alloc_from_iter(collected_lifetimes
.into_iter().map(
1938 |(_
, lifetime
, res
)| {
1939 let id
= self.next_node_id();
1940 let span
= lifetime
.ident
.span
;
1942 let ident
= if lifetime
.ident
.name
== kw
::UnderscoreLifetime
{
1943 Ident
::with_dummy_span(kw
::UnderscoreLifetime
)
1948 let res
= res
.unwrap_or(
1949 self.resolver
.get_lifetime_res(lifetime
.id
).unwrap_or(LifetimeRes
::Error
),
1951 let l
= self.new_named_lifetime_with_res(id
, span
, ident
, res
);
1952 hir
::GenericArg
::Lifetime(l
)
1956 // Create the `Foo<...>` reference itself. Note that the `type
1957 // Foo = impl Trait` is, internally, created as a child of the
1958 // async fn, so the *type parameters* are inherited. It's
1959 // only the lifetime parameters that we must supply.
1961 hir
::TyKind
::OpaqueDef(hir
::ItemId { def_id: opaque_ty_def_id }
, generic_args
);
1962 let opaque_ty
= self.ty(opaque_ty_span
, opaque_ty_ref
);
1963 hir
::FnRetTy
::Return(self.arena
.alloc(opaque_ty
))
1966 /// Transforms `-> T` into `Future<Output = T>`.
1967 fn lower_async_fn_output_type_to_future_bound(
1970 fn_def_id
: LocalDefId
,
1972 ) -> hir
::GenericBound
<'hir
> {
1973 // Compute the `T` in `Future<Output = T>` from the return type.
1974 let output_ty
= match output
{
1975 FnRetTy
::Ty(ty
) => {
1976 // Not `OpaqueTyOrigin::AsyncFn`: that's only used for the
1977 // `impl Future` opaque type that `async fn` implicitly
1979 let context
= ImplTraitContext
::ReturnPositionOpaqueTy
{
1980 origin
: hir
::OpaqueTyOrigin
::FnReturn(fn_def_id
),
1982 self.lower_ty(ty
, context
)
1984 FnRetTy
::Default(ret_ty_span
) => self.arena
.alloc(self.ty_tup(*ret_ty_span
, &[])),
1988 let future_args
= self.arena
.alloc(hir
::GenericArgs
{
1990 bindings
: arena_vec
![self; self.output_ty_binding(span
, output_ty
)],
1991 parenthesized
: false,
1995 hir
::GenericBound
::LangItemTrait(
1996 // ::std::future::Future<future_params>
1997 hir
::LangItem
::Future
,
1998 self.lower_span(span
),
2004 #[instrument(level = "trace", skip(self))]
2005 fn lower_param_bound(
2008 itctx
: ImplTraitContext
,
2009 ) -> hir
::GenericBound
<'hir
> {
2011 GenericBound
::Trait(p
, modifier
) => hir
::GenericBound
::Trait(
2012 self.lower_poly_trait_ref(p
, itctx
),
2013 self.lower_trait_bound_modifier(*modifier
),
2015 GenericBound
::Outlives(lifetime
) => {
2016 hir
::GenericBound
::Outlives(self.lower_lifetime(lifetime
))
2021 fn lower_lifetime(&mut self, l
: &Lifetime
) -> hir
::Lifetime
{
2022 let span
= self.lower_span(l
.ident
.span
);
2023 let ident
= self.lower_ident(l
.ident
);
2024 self.new_named_lifetime(l
.id
, l
.id
, span
, ident
)
2027 #[tracing::instrument(level = "debug", skip(self))]
2028 fn new_named_lifetime_with_res(
2034 ) -> hir
::Lifetime
{
2035 let name
= match res
{
2036 LifetimeRes
::Param { param, .. }
=> {
2037 let p_name
= ParamName
::Plain(ident
);
2038 let param
= self.resolver
.get_remapped_def_id(param
);
2040 hir
::LifetimeName
::Param(param
, p_name
)
2042 LifetimeRes
::Fresh { param, .. }
=> {
2043 debug_assert_eq
!(ident
.name
, kw
::UnderscoreLifetime
);
2044 let param
= self.local_def_id(param
);
2046 hir
::LifetimeName
::Param(param
, ParamName
::Fresh
)
2048 LifetimeRes
::Infer
=> hir
::LifetimeName
::Infer
,
2049 LifetimeRes
::Static
=> hir
::LifetimeName
::Static
,
2050 LifetimeRes
::Error
=> hir
::LifetimeName
::Error
,
2051 res
=> panic
!("Unexpected lifetime resolution {:?} for {:?} at {:?}", res
, ident
, span
),
2055 hir
::Lifetime { hir_id: self.lower_node_id(id), span: self.lower_span(span), name }
2058 #[tracing::instrument(level = "debug", skip(self))]
2059 fn new_named_lifetime(
2065 ) -> hir
::Lifetime
{
2066 let res
= self.resolver
.get_lifetime_res(id
).unwrap_or(LifetimeRes
::Error
);
2067 self.new_named_lifetime_with_res(new_id
, span
, ident
, res
)
2070 fn lower_generic_params_mut
<'s
>(
2072 params
: &'s
[GenericParam
],
2073 ) -> impl Iterator
<Item
= hir
::GenericParam
<'hir
>> + Captures
<'a
> + Captures
<'s
> {
2074 params
.iter().map(move |param
| self.lower_generic_param(param
))
2077 fn lower_generic_params(&mut self, params
: &[GenericParam
]) -> &'hir
[hir
::GenericParam
<'hir
>] {
2078 self.arena
.alloc_from_iter(self.lower_generic_params_mut(params
))
2081 #[instrument(level = "trace", skip(self))]
2082 fn lower_generic_param(&mut self, param
: &GenericParam
) -> hir
::GenericParam
<'hir
> {
2083 let (name
, kind
) = self.lower_generic_param_kind(param
);
2085 let hir_id
= self.lower_node_id(param
.id
);
2086 self.lower_attrs(hir_id
, ¶m
.attrs
);
2090 span
: self.lower_span(param
.span()),
2091 pure_wrt_drop
: self.tcx
.sess
.contains_name(¶m
.attrs
, sym
::may_dangle
),
2093 colon_span
: param
.colon_span
.map(|s
| self.lower_span(s
)),
2097 fn lower_generic_param_kind(
2099 param
: &GenericParam
,
2100 ) -> (hir
::ParamName
, hir
::GenericParamKind
<'hir
>) {
2102 GenericParamKind
::Lifetime
=> {
2103 // AST resolution emitted an error on those parameters, so we lower them using
2104 // `ParamName::Error`.
2106 if let Some(LifetimeRes
::Error
) = self.resolver
.get_lifetime_res(param
.id
) {
2109 let ident
= self.lower_ident(param
.ident
);
2110 ParamName
::Plain(ident
)
2113 hir
::GenericParamKind
::Lifetime { kind: hir::LifetimeParamKind::Explicit }
;
2117 GenericParamKind
::Type { ref default, .. }
=> {
2118 let kind
= hir
::GenericParamKind
::Type
{
2119 default: default.as_ref().map(|x
| {
2120 self.lower_ty(x
, ImplTraitContext
::Disallowed(ImplTraitPosition
::Type
))
2125 (hir
::ParamName
::Plain(self.lower_ident(param
.ident
)), kind
)
2127 GenericParamKind
::Const { ref ty, kw_span: _, ref default }
=> {
2128 let ty
= self.lower_ty(&ty
, ImplTraitContext
::Disallowed(ImplTraitPosition
::Type
));
2129 let default = default.as_ref().map(|def
| self.lower_anon_const(def
));
2131 hir
::ParamName
::Plain(self.lower_ident(param
.ident
)),
2132 hir
::GenericParamKind
::Const { ty, default }
,
2138 fn lower_trait_ref(&mut self, p
: &TraitRef
, itctx
: ImplTraitContext
) -> hir
::TraitRef
<'hir
> {
2139 let path
= match self.lower_qpath(p
.ref_id
, &None
, &p
.path
, ParamMode
::Explicit
, itctx
) {
2140 hir
::QPath
::Resolved(None
, path
) => path
,
2141 qpath
=> panic
!("lower_trait_ref: unexpected QPath `{:?}`", qpath
),
2143 hir
::TraitRef { path, hir_ref_id: self.lower_node_id(p.ref_id) }
2146 #[tracing::instrument(level = "debug", skip(self))]
2147 fn lower_poly_trait_ref(
2150 itctx
: ImplTraitContext
,
2151 ) -> hir
::PolyTraitRef
<'hir
> {
2152 let bound_generic_params
=
2153 self.lower_lifetime_binder(p
.trait_ref
.ref_id
, &p
.bound_generic_params
);
2154 let trait_ref
= self.lower_trait_ref(&p
.trait_ref
, itctx
);
2155 hir
::PolyTraitRef { bound_generic_params, trait_ref, span: self.lower_span(p.span) }
2158 fn lower_mt(&mut self, mt
: &MutTy
, itctx
: ImplTraitContext
) -> hir
::MutTy
<'hir
> {
2159 hir
::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl }
2162 fn lower_param_bounds(
2164 bounds
: &[GenericBound
],
2165 itctx
: ImplTraitContext
,
2166 ) -> hir
::GenericBounds
<'hir
> {
2167 self.arena
.alloc_from_iter(self.lower_param_bounds_mut(bounds
, itctx
))
2170 fn lower_param_bounds_mut
<'s
>(
2172 bounds
: &'s
[GenericBound
],
2173 itctx
: ImplTraitContext
,
2174 ) -> impl Iterator
<Item
= hir
::GenericBound
<'hir
>> + Captures
<'s
> + Captures
<'a
> {
2175 bounds
.iter().map(move |bound
| self.lower_param_bound(bound
, itctx
))
2178 fn lower_generic_and_bounds(
2183 bounds
: &[GenericBound
],
2184 ) -> (hir
::GenericParam
<'hir
>, Option
<hir
::WherePredicate
<'hir
>>, hir
::TyKind
<'hir
>) {
2185 // Add a definition for the in-band `Param`.
2186 let def_id
= self.local_def_id(node_id
);
2188 // Set the name to `impl Bound1 + Bound2`.
2189 let param
= hir
::GenericParam
{
2190 hir_id
: self.lower_node_id(node_id
),
2191 name
: ParamName
::Plain(self.lower_ident(ident
)),
2192 pure_wrt_drop
: false,
2193 span
: self.lower_span(span
),
2194 kind
: hir
::GenericParamKind
::Type { default: None, synthetic: true }
,
2198 let preds
= self.lower_generic_bound_predicate(
2201 &GenericParamKind
::Type { default: None }
,
2203 ImplTraitContext
::Universal
,
2204 hir
::PredicateOrigin
::ImplTrait
,
2207 let ty
= hir
::TyKind
::Path(hir
::QPath
::Resolved(
2209 self.arena
.alloc(hir
::Path
{
2210 span
: self.lower_span(span
),
2211 res
: Res
::Def(DefKind
::TyParam
, def_id
.to_def_id()),
2212 segments
: arena_vec
![self; hir
::PathSegment
::from_ident(self.lower_ident(ident
))],
2219 /// Lowers a block directly to an expression, presuming that it
2220 /// has no attributes and is not targeted by a `break`.
2221 fn lower_block_expr(&mut self, b
: &Block
) -> hir
::Expr
<'hir
> {
2222 let block
= self.lower_block(b
, false);
2223 self.expr_block(block
, AttrVec
::new())
2226 fn lower_array_length(&mut self, c
: &AnonConst
) -> hir
::ArrayLen
{
2227 match c
.value
.kind
{
2228 ExprKind
::Underscore
=> {
2229 if self.tcx
.features().generic_arg_infer
{
2230 hir
::ArrayLen
::Infer(self.lower_node_id(c
.id
), c
.value
.span
)
2233 &self.tcx
.sess
.parse_sess
,
2234 sym
::generic_arg_infer
,
2236 "using `_` for array lengths is unstable",
2239 hir
::ArrayLen
::Body(self.lower_anon_const(c
))
2242 _
=> hir
::ArrayLen
::Body(self.lower_anon_const(c
)),
2246 fn lower_anon_const(&mut self, c
: &AnonConst
) -> hir
::AnonConst
{
2247 self.with_new_scopes(|this
| hir
::AnonConst
{
2248 hir_id
: this
.lower_node_id(c
.id
),
2249 body
: this
.lower_const_body(c
.value
.span
, Some(&c
.value
)),
2253 fn lower_unsafe_source(&mut self, u
: UnsafeSource
) -> hir
::UnsafeSource
{
2255 CompilerGenerated
=> hir
::UnsafeSource
::CompilerGenerated
,
2256 UserProvided
=> hir
::UnsafeSource
::UserProvided
,
2260 fn lower_trait_bound_modifier(&mut self, f
: TraitBoundModifier
) -> hir
::TraitBoundModifier
{
2262 TraitBoundModifier
::None
=> hir
::TraitBoundModifier
::None
,
2263 TraitBoundModifier
::MaybeConst
=> hir
::TraitBoundModifier
::MaybeConst
,
2265 // `MaybeConstMaybe` will cause an error during AST validation, but we need to pick a
2266 // placeholder for compilation to proceed.
2267 TraitBoundModifier
::MaybeConstMaybe
| TraitBoundModifier
::Maybe
=> {
2268 hir
::TraitBoundModifier
::Maybe
2273 // Helper methods for building HIR.
2275 fn stmt(&mut self, span
: Span
, kind
: hir
::StmtKind
<'hir
>) -> hir
::Stmt
<'hir
> {
2276 hir
::Stmt { span: self.lower_span(span), kind, hir_id: self.next_id() }
2279 fn stmt_expr(&mut self, span
: Span
, expr
: hir
::Expr
<'hir
>) -> hir
::Stmt
<'hir
> {
2280 self.stmt(span
, hir
::StmtKind
::Expr(self.arena
.alloc(expr
)))
2285 attrs
: Option
<&'hir
[Attribute
]>,
2287 init
: Option
<&'hir hir
::Expr
<'hir
>>,
2288 pat
: &'hir hir
::Pat
<'hir
>,
2289 source
: hir
::LocalSource
,
2290 ) -> hir
::Stmt
<'hir
> {
2291 let hir_id
= self.next_id();
2292 if let Some(a
) = attrs
{
2293 debug_assert
!(!a
.is_empty());
2294 self.attrs
.insert(hir_id
.local_id
, a
);
2296 let local
= hir
::Local
{
2302 span
: self.lower_span(span
),
2305 self.stmt(span
, hir
::StmtKind
::Local(self.arena
.alloc(local
)))
2308 fn block_expr(&mut self, expr
: &'hir hir
::Expr
<'hir
>) -> &'hir hir
::Block
<'hir
> {
2309 self.block_all(expr
.span
, &[], Some(expr
))
2315 stmts
: &'hir
[hir
::Stmt
<'hir
>],
2316 expr
: Option
<&'hir hir
::Expr
<'hir
>>,
2317 ) -> &'hir hir
::Block
<'hir
> {
2318 let blk
= hir
::Block
{
2321 hir_id
: self.next_id(),
2322 rules
: hir
::BlockCheckMode
::DefaultBlock
,
2323 span
: self.lower_span(span
),
2324 targeted_by_break
: false,
2326 self.arena
.alloc(blk
)
2329 fn pat_cf_continue(&mut self, span
: Span
, pat
: &'hir hir
::Pat
<'hir
>) -> &'hir hir
::Pat
<'hir
> {
2330 let field
= self.single_pat_field(span
, pat
);
2331 self.pat_lang_item_variant(span
, hir
::LangItem
::ControlFlowContinue
, field
, None
)
2334 fn pat_cf_break(&mut self, span
: Span
, pat
: &'hir hir
::Pat
<'hir
>) -> &'hir hir
::Pat
<'hir
> {
2335 let field
= self.single_pat_field(span
, pat
);
2336 self.pat_lang_item_variant(span
, hir
::LangItem
::ControlFlowBreak
, field
, None
)
2339 fn pat_some(&mut self, span
: Span
, pat
: &'hir hir
::Pat
<'hir
>) -> &'hir hir
::Pat
<'hir
> {
2340 let field
= self.single_pat_field(span
, pat
);
2341 self.pat_lang_item_variant(span
, hir
::LangItem
::OptionSome
, field
, None
)
2344 fn pat_none(&mut self, span
: Span
) -> &'hir hir
::Pat
<'hir
> {
2345 self.pat_lang_item_variant(span
, hir
::LangItem
::OptionNone
, &[], None
)
2348 fn single_pat_field(
2351 pat
: &'hir hir
::Pat
<'hir
>,
2352 ) -> &'hir
[hir
::PatField
<'hir
>] {
2353 let field
= hir
::PatField
{
2354 hir_id
: self.next_id(),
2355 ident
: Ident
::new(sym
::integer(0), self.lower_span(span
)),
2356 is_shorthand
: false,
2358 span
: self.lower_span(span
),
2360 arena_vec
![self; field
]
2363 fn pat_lang_item_variant(
2366 lang_item
: hir
::LangItem
,
2367 fields
: &'hir
[hir
::PatField
<'hir
>],
2368 hir_id
: Option
<hir
::HirId
>,
2369 ) -> &'hir hir
::Pat
<'hir
> {
2370 let qpath
= hir
::QPath
::LangItem(lang_item
, self.lower_span(span
), hir_id
);
2371 self.pat(span
, hir
::PatKind
::Struct(qpath
, fields
, false))
2374 fn pat_ident(&mut self, span
: Span
, ident
: Ident
) -> (&'hir hir
::Pat
<'hir
>, hir
::HirId
) {
2375 self.pat_ident_binding_mode(span
, ident
, hir
::BindingAnnotation
::Unannotated
)
2378 fn pat_ident_mut(&mut self, span
: Span
, ident
: Ident
) -> (hir
::Pat
<'hir
>, hir
::HirId
) {
2379 self.pat_ident_binding_mode_mut(span
, ident
, hir
::BindingAnnotation
::Unannotated
)
2382 fn pat_ident_binding_mode(
2386 bm
: hir
::BindingAnnotation
,
2387 ) -> (&'hir hir
::Pat
<'hir
>, hir
::HirId
) {
2388 let (pat
, hir_id
) = self.pat_ident_binding_mode_mut(span
, ident
, bm
);
2389 (self.arena
.alloc(pat
), hir_id
)
2392 fn pat_ident_binding_mode_mut(
2396 bm
: hir
::BindingAnnotation
,
2397 ) -> (hir
::Pat
<'hir
>, hir
::HirId
) {
2398 let hir_id
= self.next_id();
2403 kind
: hir
::PatKind
::Binding(bm
, hir_id
, self.lower_ident(ident
), None
),
2404 span
: self.lower_span(span
),
2405 default_binding_modes
: true,
2411 fn pat(&mut self, span
: Span
, kind
: hir
::PatKind
<'hir
>) -> &'hir hir
::Pat
<'hir
> {
2412 self.arena
.alloc(hir
::Pat
{
2413 hir_id
: self.next_id(),
2415 span
: self.lower_span(span
),
2416 default_binding_modes
: true,
2420 fn pat_without_dbm(&mut self, span
: Span
, kind
: hir
::PatKind
<'hir
>) -> hir
::Pat
<'hir
> {
2422 hir_id
: self.next_id(),
2424 span
: self.lower_span(span
),
2425 default_binding_modes
: false,
2431 mut hir_id
: hir
::HirId
,
2433 qpath
: hir
::QPath
<'hir
>,
2434 ) -> hir
::Ty
<'hir
> {
2435 let kind
= match qpath
{
2436 hir
::QPath
::Resolved(None
, path
) => {
2437 // Turn trait object paths into `TyKind::TraitObject` instead.
2439 Res
::Def(DefKind
::Trait
| DefKind
::TraitAlias
, _
) => {
2440 let principal
= hir
::PolyTraitRef
{
2441 bound_generic_params
: &[],
2442 trait_ref
: hir
::TraitRef { path, hir_ref_id: hir_id }
,
2443 span
: self.lower_span(span
),
2446 // The original ID is taken by the `PolyTraitRef`,
2447 // so the `Ty` itself needs a different one.
2448 hir_id
= self.next_id();
2449 hir
::TyKind
::TraitObject(
2450 arena_vec
![self; principal
],
2451 self.elided_dyn_bound(span
),
2452 TraitObjectSyntax
::None
,
2455 _
=> hir
::TyKind
::Path(hir
::QPath
::Resolved(None
, path
)),
2458 _
=> hir
::TyKind
::Path(qpath
),
2461 hir
::Ty { hir_id, kind, span: self.lower_span(span) }
2464 /// Invoked to create the lifetime argument(s) for an elided trait object
2465 /// bound, like the bound in `Box<dyn Debug>`. This method is not invoked
2466 /// when the bound is written, even if it is written with `'_` like in
2467 /// `Box<dyn Debug + '_>`. In those cases, `lower_lifetime` is invoked.
2468 fn elided_dyn_bound(&mut self, span
: Span
) -> hir
::Lifetime
{
2469 let r
= hir
::Lifetime
{
2470 hir_id
: self.next_id(),
2471 span
: self.lower_span(span
),
2472 name
: hir
::LifetimeName
::ImplicitObjectLifetimeDefault
,
2474 debug
!("elided_dyn_bound: r={:?}", r
);
2479 /// Helper struct for delayed construction of GenericArgs.
2480 struct GenericArgsCtor
<'hir
> {
2481 args
: SmallVec
<[hir
::GenericArg
<'hir
>; 4]>,
2482 bindings
: &'hir
[hir
::TypeBinding
<'hir
>],
2483 parenthesized
: bool
,
2487 impl<'hir
> GenericArgsCtor
<'hir
> {
2488 fn is_empty(&self) -> bool
{
2489 self.args
.is_empty() && self.bindings
.is_empty() && !self.parenthesized
2492 fn into_generic_args(self, this
: &LoweringContext
<'_
, 'hir
>) -> &'hir hir
::GenericArgs
<'hir
> {
2493 let ga
= hir
::GenericArgs
{
2494 args
: this
.arena
.alloc_from_iter(self.args
),
2495 bindings
: self.bindings
,
2496 parenthesized
: self.parenthesized
,
2497 span_ext
: this
.lower_span(self.span
),
2499 this
.arena
.alloc(ga
)