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 #![allow(internal_features)]
34 #![feature(rustdoc_internals)]
36 #![feature(box_patterns)]
37 #![feature(let_chains)]
38 #![recursion_limit = "256"]
39 #![deny(rustc::untranslatable_diagnostic)]
40 #![deny(rustc::diagnostic_outside_of_impl)]
45 use crate::errors
::{AssocTyParentheses, AssocTyParenthesesSub, MisplacedImplTrait}
;
47 use rustc_ast
::node_id
::NodeMap
;
48 use rustc_ast
::ptr
::P
;
49 use rustc_ast
::{self as ast, *}
;
50 use rustc_ast_pretty
::pprust
;
51 use rustc_data_structures
::captures
::Captures
;
52 use rustc_data_structures
::fingerprint
::Fingerprint
;
53 use rustc_data_structures
::sorted_map
::SortedMap
;
54 use rustc_data_structures
::stable_hasher
::{HashStable, StableHasher}
;
55 use rustc_data_structures
::sync
::Lrc
;
56 use rustc_errors
::{DiagnosticArgFromDisplay, StashKey}
;
58 use rustc_hir
::def
::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}
;
59 use rustc_hir
::def_id
::{LocalDefId, LocalDefIdMap, CRATE_DEF_ID, LOCAL_CRATE}
;
60 use rustc_hir
::{ConstArg, GenericArg, ItemLocalMap, ParamName, TraitCandidate}
;
61 use rustc_index
::{Idx, IndexSlice, IndexVec}
;
62 use rustc_middle
::span_bug
;
63 use rustc_middle
::ty
::{ResolverAstLowering, TyCtxt}
;
64 use rustc_session
::parse
::{add_feature_diagnostics, feature_err}
;
65 use rustc_span
::symbol
::{kw, sym, Ident, Symbol}
;
66 use rustc_span
::{DesugaringKind, Span, DUMMY_SP}
;
67 use smallvec
::SmallVec
;
68 use std
::collections
::hash_map
::Entry
;
69 use thin_vec
::ThinVec
;
71 macro_rules
! arena_vec
{
72 ($this
:expr
; $
($x
:expr
),*) => (
73 $this
.arena
.alloc_from_iter([$
($x
),*])
84 mod lifetime_collector
;
88 rustc_fluent_macro
::fluent_messages
! { "../messages.ftl" }
90 struct LoweringContext
<'a
, 'hir
> {
92 resolver
: &'a
mut ResolverAstLowering
,
94 /// Used to allocate HIR nodes.
95 arena
: &'hir hir
::Arena
<'hir
>,
97 /// Bodies inside the owner being lowered.
98 bodies
: Vec
<(hir
::ItemLocalId
, &'hir hir
::Body
<'hir
>)>,
99 /// Attributes inside the owner being lowered.
100 attrs
: SortedMap
<hir
::ItemLocalId
, &'hir
[Attribute
]>,
101 /// Collect items that were created by lowering the current owner.
102 children
: Vec
<(LocalDefId
, hir
::MaybeOwner
<&'hir hir
::OwnerInfo
<'hir
>>)>,
104 coroutine_kind
: Option
<hir
::CoroutineKind
>,
106 /// When inside an `async` context, this is the `HirId` of the
107 /// `task_context` local bound to the resume argument of the coroutine.
108 task_context
: Option
<hir
::HirId
>,
110 /// Used to get the current `fn`'s def span to point to when using `await`
111 /// outside of an `async fn`.
112 current_item
: Option
<Span
>,
114 catch_scope
: Option
<NodeId
>,
115 loop_scope
: Option
<NodeId
>,
116 is_in_loop_condition
: bool
,
117 is_in_trait_impl
: bool
,
118 is_in_dyn_type
: bool
,
120 current_hir_id_owner
: hir
::OwnerId
,
121 item_local_id_counter
: hir
::ItemLocalId
,
122 trait_map
: ItemLocalMap
<Box
<[TraitCandidate
]>>,
124 impl_trait_defs
: Vec
<hir
::GenericParam
<'hir
>>,
125 impl_trait_bounds
: Vec
<hir
::WherePredicate
<'hir
>>,
127 /// NodeIds that are lowered inside the current HIR owner.
128 node_id_to_local_id
: NodeMap
<hir
::ItemLocalId
>,
130 allow_try_trait
: Lrc
<[Symbol
]>,
131 allow_gen_future
: Lrc
<[Symbol
]>,
132 allow_async_iterator
: Lrc
<[Symbol
]>,
134 /// Mapping from generics `def_id`s to TAIT generics `def_id`s.
135 /// For each captured lifetime (e.g., 'a), we create a new lifetime parameter that is a generic
136 /// defined on the TAIT, so we have type Foo<'a1> = ... and we establish a mapping in this
137 /// field from the original parameter 'a to the new parameter 'a1.
138 generics_def_id_map
: Vec
<LocalDefIdMap
<LocalDefId
>>,
140 host_param_id
: Option
<LocalDefId
>,
143 impl<'a
, 'hir
> LoweringContext
<'a
, 'hir
> {
144 fn new(tcx
: TyCtxt
<'hir
>, resolver
: &'a
mut ResolverAstLowering
) -> Self {
149 arena
: tcx
.hir_arena
,
153 attrs
: SortedMap
::default(),
154 children
: Vec
::default(),
155 current_hir_id_owner
: hir
::CRATE_OWNER_ID
,
156 item_local_id_counter
: hir
::ItemLocalId
::new(0),
157 node_id_to_local_id
: Default
::default(),
158 trait_map
: Default
::default(),
163 is_in_loop_condition
: false,
164 is_in_trait_impl
: false,
165 is_in_dyn_type
: false,
166 coroutine_kind
: None
,
169 impl_trait_defs
: Vec
::new(),
170 impl_trait_bounds
: Vec
::new(),
171 allow_try_trait
: [sym
::try_trait_v2
, sym
::yeet_desugar_details
].into(),
172 allow_gen_future
: if tcx
.features().async_fn_track_caller
{
173 [sym
::gen_future
, sym
::closure_track_caller
].into()
175 [sym
::gen_future
].into()
177 // FIXME(gen_blocks): how does `closure_track_caller`/`async_fn_track_caller`
178 // interact with `gen`/`async gen` blocks
179 allow_async_iterator
: [sym
::gen_future
, sym
::async_iterator
].into(),
180 generics_def_id_map
: Default
::default(),
186 trait ResolverAstLoweringExt
{
187 fn legacy_const_generic_args(&self, expr
: &Expr
) -> Option
<Vec
<usize>>;
188 fn get_partial_res(&self, id
: NodeId
) -> Option
<PartialRes
>;
189 fn get_import_res(&self, id
: NodeId
) -> PerNS
<Option
<Res
<NodeId
>>>;
190 fn get_label_res(&self, id
: NodeId
) -> Option
<NodeId
>;
191 fn get_lifetime_res(&self, id
: NodeId
) -> Option
<LifetimeRes
>;
192 fn take_extra_lifetime_params(&mut self, id
: NodeId
) -> Vec
<(Ident
, NodeId
, LifetimeRes
)>;
193 fn remap_extra_lifetime_params(&mut self, from
: NodeId
, to
: NodeId
);
196 impl ResolverAstLoweringExt
for ResolverAstLowering
{
197 fn legacy_const_generic_args(&self, expr
: &Expr
) -> Option
<Vec
<usize>> {
198 if let ExprKind
::Path(None
, path
) = &expr
.kind
{
199 // Don't perform legacy const generics rewriting if the path already
200 // has generic arguments.
201 if path
.segments
.last().unwrap().args
.is_some() {
205 if let Res
::Def(DefKind
::Fn
, def_id
) = self.partial_res_map
.get(&expr
.id
)?
.full_res()?
{
206 // We only support cross-crate argument rewriting. Uses
207 // within the same crate should be updated to use the new
208 // const generics style.
209 if def_id
.is_local() {
213 if let Some(v
) = self.legacy_const_generic_args
.get(&def_id
) {
222 /// Obtains resolution for a `NodeId` with a single resolution.
223 fn get_partial_res(&self, id
: NodeId
) -> Option
<PartialRes
> {
224 self.partial_res_map
.get(&id
).copied()
227 /// Obtains per-namespace resolutions for `use` statement with the given `NodeId`.
228 fn get_import_res(&self, id
: NodeId
) -> PerNS
<Option
<Res
<NodeId
>>> {
229 self.import_res_map
.get(&id
).copied().unwrap_or_default()
232 /// Obtains resolution for a label with the given `NodeId`.
233 fn get_label_res(&self, id
: NodeId
) -> Option
<NodeId
> {
234 self.label_res_map
.get(&id
).copied()
237 /// Obtains resolution for a lifetime with the given `NodeId`.
238 fn get_lifetime_res(&self, id
: NodeId
) -> Option
<LifetimeRes
> {
239 self.lifetimes_res_map
.get(&id
).copied()
242 /// Obtain the list of lifetimes parameters to add to an item.
244 /// Extra lifetime parameters should only be added in places that can appear
245 /// as a `binder` in `LifetimeRes`.
247 /// The extra lifetimes that appear from the parenthesized `Fn`-trait desugaring
248 /// should appear at the enclosing `PolyTraitRef`.
249 fn take_extra_lifetime_params(&mut self, id
: NodeId
) -> Vec
<(Ident
, NodeId
, LifetimeRes
)> {
250 self.extra_lifetime_params_map
.remove(&id
).unwrap_or_default()
253 fn remap_extra_lifetime_params(&mut self, from
: NodeId
, to
: NodeId
) {
254 let lifetimes
= self.extra_lifetime_params_map
.remove(&from
).unwrap_or_default();
255 self.extra_lifetime_params_map
.insert(to
, lifetimes
);
259 /// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,
260 /// and if so, what meaning it has.
261 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
262 enum ImplTraitContext
{
263 /// Treat `impl Trait` as shorthand for a new universal generic parameter.
264 /// Example: `fn foo(x: impl Debug)`, where `impl Debug` is conceptually
265 /// equivalent to a fresh universal parameter like `fn foo<T: Debug>(x: T)`.
267 /// Newly generated parameters should be inserted into the given `Vec`.
270 /// Treat `impl Trait` as shorthand for a new opaque type.
271 /// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
272 /// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`.
274 ReturnPositionOpaqueTy
{
275 /// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn,
276 origin
: hir
::OpaqueTyOrigin
,
279 /// Impl trait in type aliases.
280 TypeAliasesOpaqueTy { in_assoc_ty: bool }
,
281 /// `impl Trait` is unstably accepted in this position.
282 FeatureGated(ImplTraitPosition
, Symbol
),
283 /// `impl Trait` is not accepted in this position.
284 Disallowed(ImplTraitPosition
),
287 /// Position in which `impl Trait` is disallowed.
288 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
289 enum ImplTraitPosition
{
316 impl std
::fmt
::Display
for ImplTraitPosition
{
317 fn fmt(&self, f
: &mut std
::fmt
::Formatter
<'_
>) -> std
::fmt
::Result
{
318 let name
= match self {
319 ImplTraitPosition
::Path
=> "paths",
320 ImplTraitPosition
::Variable
=> "variable bindings",
321 ImplTraitPosition
::Trait
=> "traits",
322 ImplTraitPosition
::AsyncBlock
=> "async blocks",
323 ImplTraitPosition
::Bound
=> "bounds",
324 ImplTraitPosition
::Generic
=> "generics",
325 ImplTraitPosition
::ExternFnParam
=> "`extern fn` params",
326 ImplTraitPosition
::ClosureParam
=> "closure params",
327 ImplTraitPosition
::PointerParam
=> "`fn` pointer params",
328 ImplTraitPosition
::FnTraitParam
=> "`Fn` trait params",
329 ImplTraitPosition
::TraitParam
=> "trait method params",
330 ImplTraitPosition
::ImplParam
=> "`impl` method params",
331 ImplTraitPosition
::ExternFnReturn
=> "`extern fn` return types",
332 ImplTraitPosition
::ClosureReturn
=> "closure return types",
333 ImplTraitPosition
::PointerReturn
=> "`fn` pointer return types",
334 ImplTraitPosition
::FnTraitReturn
=> "`Fn` trait return types",
335 ImplTraitPosition
::GenericDefault
=> "generic parameter defaults",
336 ImplTraitPosition
::ConstTy
=> "const types",
337 ImplTraitPosition
::StaticTy
=> "static types",
338 ImplTraitPosition
::AssocTy
=> "associated types",
339 ImplTraitPosition
::FieldTy
=> "field types",
340 ImplTraitPosition
::Cast
=> "cast types",
341 ImplTraitPosition
::ImplSelf
=> "impl headers",
342 ImplTraitPosition
::OffsetOf
=> "`offset_of!` params",
349 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
361 fn param_impl_trait_allowed(&self) -> bool
{
362 matches
!(self, FnDeclKind
::Fn
| FnDeclKind
::Inherent
| FnDeclKind
::Impl
| FnDeclKind
::Trait
)
365 fn return_impl_trait_allowed(&self) -> bool
{
367 FnDeclKind
::Fn
| FnDeclKind
::Inherent
| FnDeclKind
::Impl
| FnDeclKind
::Trait
=> true,
373 #[derive(Copy, Clone)]
376 Crate(&'a ast
::Crate
),
378 AssocItem(&'a ast
::AssocItem
, visit
::AssocCtxt
),
379 ForeignItem(&'a ast
::ForeignItem
),
383 node_id_to_def_id
: &NodeMap
<LocalDefId
>,
385 ) -> IndexVec
<LocalDefId
, AstOwner
<'a
>> {
386 let mut indexer
= Indexer { node_id_to_def_id, index: IndexVec::new() }
;
387 *indexer
.index
.ensure_contains_elem(CRATE_DEF_ID
, || AstOwner
::NonOwner
) =
388 AstOwner
::Crate(krate
);
389 visit
::walk_crate(&mut indexer
, krate
);
390 return indexer
.index
;
392 struct Indexer
<'s
, 'a
> {
393 node_id_to_def_id
: &'s NodeMap
<LocalDefId
>,
394 index
: IndexVec
<LocalDefId
, AstOwner
<'a
>>,
397 impl<'a
> visit
::Visitor
<'a
> for Indexer
<'_
, 'a
> {
398 fn visit_attribute(&mut self, _
: &'a Attribute
) {
399 // We do not want to lower expressions that appear in attributes,
400 // as they are not accessible to the rest of the HIR.
403 fn visit_item(&mut self, item
: &'a ast
::Item
) {
404 let def_id
= self.node_id_to_def_id
[&item
.id
];
405 *self.index
.ensure_contains_elem(def_id
, || AstOwner
::NonOwner
) = AstOwner
::Item(item
);
406 visit
::walk_item(self, item
)
409 fn visit_assoc_item(&mut self, item
: &'a ast
::AssocItem
, ctxt
: visit
::AssocCtxt
) {
410 let def_id
= self.node_id_to_def_id
[&item
.id
];
411 *self.index
.ensure_contains_elem(def_id
, || AstOwner
::NonOwner
) =
412 AstOwner
::AssocItem(item
, ctxt
);
413 visit
::walk_assoc_item(self, item
, ctxt
);
416 fn visit_foreign_item(&mut self, item
: &'a ast
::ForeignItem
) {
417 let def_id
= self.node_id_to_def_id
[&item
.id
];
418 *self.index
.ensure_contains_elem(def_id
, || AstOwner
::NonOwner
) =
419 AstOwner
::ForeignItem(item
);
420 visit
::walk_foreign_item(self, item
);
425 /// Compute the hash for the HIR of the full crate.
426 /// This hash will then be part of the crate_hash which is stored in the metadata.
429 owners
: &IndexSlice
<LocalDefId
, hir
::MaybeOwner
<&hir
::OwnerInfo
<'_
>>>,
431 let mut hir_body_nodes
: Vec
<_
> = owners
433 .filter_map(|(def_id
, info
)| {
434 let info
= info
.as_owner()?
;
435 let def_path_hash
= tcx
.hir().def_path_hash(def_id
);
436 Some((def_path_hash
, info
))
439 hir_body_nodes
.sort_unstable_by_key(|bn
| bn
.0);
441 tcx
.with_stable_hashing_context(|mut hcx
| {
442 let mut stable_hasher
= StableHasher
::new();
443 hir_body_nodes
.hash_stable(&mut hcx
, &mut stable_hasher
);
444 stable_hasher
.finish()
448 pub fn lower_to_hir(tcx
: TyCtxt
<'_
>, (): ()) -> hir
::Crate
<'_
> {
450 // Queries that borrow `resolver_for_lowering`.
451 tcx
.ensure_with_value().output_filenames(());
452 tcx
.ensure_with_value().early_lint_checks(());
453 tcx
.ensure_with_value().debugger_visualizers(LOCAL_CRATE
);
454 tcx
.ensure_with_value().get_lang_items(());
455 let (mut resolver
, krate
) = tcx
.resolver_for_lowering(()).steal();
457 let ast_index
= index_crate(&resolver
.node_id_to_def_id
, &krate
);
458 let mut owners
= IndexVec
::from_fn_n(
459 |_
| hir
::MaybeOwner
::Phantom
,
460 tcx
.definitions_untracked().def_index_count(),
463 for def_id
in ast_index
.indices() {
466 resolver
: &mut resolver
,
467 ast_index
: &ast_index
,
473 // Drop AST to free memory
475 sess
.time("drop_ast", || drop(krate
));
477 // Don't hash unless necessary, because it's expensive.
479 if tcx
.needs_crate_hash() { Some(compute_hir_hash(tcx, &owners)) }
else { None }
;
480 hir
::Crate { owners, opt_hir_hash }
483 #[derive(Copy, Clone, PartialEq, Debug)]
485 /// Any path in a type context.
487 /// Path in a type definition, where the anonymous lifetime `'_` is not allowed.
489 /// The `module::Type` in `module::Type::method` in an expression.
493 enum ParenthesizedGenericArgs
{
498 impl<'a
, 'hir
> LoweringContext
<'a
, 'hir
> {
502 node_id
: ast
::NodeId
,
507 debug_assert_ne
!(node_id
, ast
::DUMMY_NODE_ID
);
509 self.opt_local_def_id(node_id
).is_none(),
510 "adding a def'n for node-id {:?} and def kind {:?} but a previous def'n exists: {:?}",
513 self.tcx
.hir().def_key(self.local_def_id(node_id
)),
516 let def_id
= self.tcx
.at(span
).create_def(parent
, name
, def_kind
).def_id();
518 debug
!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id
, node_id
);
519 self.resolver
.node_id_to_def_id
.insert(node_id
, def_id
);
524 fn next_node_id(&mut self) -> NodeId
{
525 let start
= self.resolver
.next_node_id
;
526 let next
= start
.as_u32().checked_add(1).expect("input too large; ran out of NodeIds");
527 self.resolver
.next_node_id
= ast
::NodeId
::from_u32(next
);
531 /// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name
532 /// resolver (if any).
533 fn orig_opt_local_def_id(&self, node
: NodeId
) -> Option
<LocalDefId
> {
534 self.resolver
.node_id_to_def_id
.get(&node
).copied()
537 /// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name
538 /// resolver (if any), after applying any remapping from `get_remapped_def_id`.
540 /// For example, in a function like `fn foo<'a>(x: &'a u32)`,
541 /// invoking with the id from the `ast::Lifetime` node found inside
542 /// the `&'a u32` type would return the `LocalDefId` of the
543 /// `'a` parameter declared on `foo`.
545 /// This function also applies remapping from `get_remapped_def_id`.
546 /// These are used when synthesizing opaque types from `-> impl Trait` return types and so forth.
547 /// For example, in a function like `fn foo<'a>() -> impl Debug + 'a`,
548 /// we would create an opaque type `type FooReturn<'a1> = impl Debug + 'a1`.
549 /// When lowering the `Debug + 'a` bounds, we add a remapping to map `'a` to `'a1`.
550 fn opt_local_def_id(&self, node
: NodeId
) -> Option
<LocalDefId
> {
551 self.orig_opt_local_def_id(node
).map(|local_def_id
| self.get_remapped_def_id(local_def_id
))
554 fn local_def_id(&self, node
: NodeId
) -> LocalDefId
{
555 self.opt_local_def_id(node
).unwrap_or_else(|| panic
!("no entry for node id: `{node:?}`"))
558 /// Get the previously recorded `to` local def id given the `from` local def id, obtained using
559 /// `generics_def_id_map` field.
560 fn get_remapped_def_id(&self, local_def_id
: LocalDefId
) -> LocalDefId
{
561 // `generics_def_id_map` is a stack of mappings. As we go deeper in impl traits nesting we
562 // push new mappings, so we first need to get the latest (innermost) mappings, hence `iter().rev()`.
566 // `fn test<'a, 'b>() -> impl Trait<&'a u8, Ty = impl Sized + 'b> {}`
568 // We would end with a generics_def_id_map like:
570 // `[[fn#'b -> impl_trait#'b], [fn#'b -> impl_sized#'b]]`
572 // for the opaque type generated on `impl Sized + 'b`, we want the result to be: impl_sized#'b.
573 // So, if we were trying to find first from the start (outermost) would give the wrong result, impl_trait#'b.
574 self.generics_def_id_map
577 .find_map(|map
| map
.get(&local_def_id
).copied())
578 .unwrap_or(local_def_id
)
581 /// Freshen the `LoweringContext` and ready it to lower a nested item.
582 /// The lowered item is registered into `self.children`.
584 /// This function sets up `HirId` lowering infrastructure,
585 /// and stashes the shared mutable state to avoid pollution by the closure.
586 #[instrument(level = "debug", skip(self, f))]
587 fn with_hir_id_owner(
590 f
: impl FnOnce(&mut Self) -> hir
::OwnerNode
<'hir
>,
592 let def_id
= self.local_def_id(owner
);
594 let current_attrs
= std
::mem
::take(&mut self.attrs
);
595 let current_bodies
= std
::mem
::take(&mut self.bodies
);
596 let current_node_ids
= std
::mem
::take(&mut self.node_id_to_local_id
);
597 let current_trait_map
= std
::mem
::take(&mut self.trait_map
);
599 std
::mem
::replace(&mut self.current_hir_id_owner
, hir
::OwnerId { def_id }
);
600 let current_local_counter
=
601 std
::mem
::replace(&mut self.item_local_id_counter
, hir
::ItemLocalId
::new(1));
602 let current_impl_trait_defs
= std
::mem
::take(&mut self.impl_trait_defs
);
603 let current_impl_trait_bounds
= std
::mem
::take(&mut self.impl_trait_bounds
);
605 // Do not reset `next_node_id` and `node_id_to_def_id`:
606 // we want `f` to be able to refer to the `LocalDefId`s that the caller created.
607 // and the caller to refer to some of the subdefinitions' nodes' `LocalDefId`s.
609 // Always allocate the first `HirId` for the owner itself.
610 let _old
= self.node_id_to_local_id
.insert(owner
, hir
::ItemLocalId
::new(0));
611 debug_assert_eq
!(_old
, None
);
614 debug_assert_eq
!(def_id
, item
.def_id().def_id
);
615 // `f` should have consumed all the elements in these vectors when constructing `item`.
616 debug_assert
!(self.impl_trait_defs
.is_empty());
617 debug_assert
!(self.impl_trait_bounds
.is_empty());
618 let info
= self.make_owner_info(item
);
620 self.attrs
= current_attrs
;
621 self.bodies
= current_bodies
;
622 self.node_id_to_local_id
= current_node_ids
;
623 self.trait_map
= current_trait_map
;
624 self.current_hir_id_owner
= current_owner
;
625 self.item_local_id_counter
= current_local_counter
;
626 self.impl_trait_defs
= current_impl_trait_defs
;
627 self.impl_trait_bounds
= current_impl_trait_bounds
;
629 debug_assert
!(!self.children
.iter().any(|(id
, _
)| id
== &def_id
));
630 self.children
.push((def_id
, hir
::MaybeOwner
::Owner(info
)));
633 /// Installs the remapping `remap` in scope while `f` is being executed.
634 /// This causes references to the `LocalDefId` keys to be changed to
635 /// refer to the values instead.
637 /// The remapping is used when one piece of AST expands to multiple
638 /// pieces of HIR. For example, the function `fn foo<'a>(...) -> impl Debug + 'a`,
639 /// expands to both a function definition (`foo`) and a TAIT for the return value,
640 /// both of which have a lifetime parameter `'a`. The remapping allows us to
641 /// rewrite the `'a` in the return value to refer to the
642 /// `'a` declared on the TAIT, instead of the function.
643 fn with_remapping
<R
>(
645 remap
: LocalDefIdMap
<LocalDefId
>,
646 f
: impl FnOnce(&mut Self) -> R
,
648 self.generics_def_id_map
.push(remap
);
650 self.generics_def_id_map
.pop();
654 fn make_owner_info(&mut self, node
: hir
::OwnerNode
<'hir
>) -> &'hir hir
::OwnerInfo
<'hir
> {
655 let attrs
= std
::mem
::take(&mut self.attrs
);
656 let mut bodies
= std
::mem
::take(&mut self.bodies
);
657 let trait_map
= std
::mem
::take(&mut self.trait_map
);
659 #[cfg(debug_assertions)]
660 for (id
, attrs
) in attrs
.iter() {
661 // Verify that we do not store empty slices in the map.
662 if attrs
.is_empty() {
663 panic
!("Stored empty attributes for {:?}", id
);
667 bodies
.sort_by_key(|(k
, _
)| *k
);
668 let bodies
= SortedMap
::from_presorted_elements(bodies
);
670 // Don't hash unless necessary, because it's expensive.
671 let (opt_hash_including_bodies
, attrs_hash
) = if self.tcx
.needs_crate_hash() {
672 self.tcx
.with_stable_hashing_context(|mut hcx
| {
673 let mut stable_hasher
= StableHasher
::new();
674 hcx
.with_hir_bodies(node
.def_id(), &bodies
, |hcx
| {
675 node
.hash_stable(hcx
, &mut stable_hasher
)
677 let h1
= stable_hasher
.finish();
679 let mut stable_hasher
= StableHasher
::new();
680 attrs
.hash_stable(&mut hcx
, &mut stable_hasher
);
681 let h2
= stable_hasher
.finish();
688 let (nodes
, parenting
) = index
::index_hir(self.tcx
, node
, &bodies
);
689 let nodes
= hir
::OwnerNodes { opt_hash_including_bodies, nodes, bodies }
;
690 let attrs
= hir
::AttributeMap { map: attrs, opt_hash: attrs_hash }
;
692 self.arena
.alloc(hir
::OwnerInfo { nodes, parenting, attrs, trait_map }
)
695 /// This method allocates a new `HirId` for the given `NodeId` and stores it in
696 /// the `LoweringContext`'s `NodeId => HirId` map.
697 /// Take care not to call this method if the resulting `HirId` is then not
698 /// actually used in the HIR, as that would trigger an assertion in the
699 /// `HirIdValidator` later on, which makes sure that all `NodeId`s got mapped
700 /// properly. Calling the method twice with the same `NodeId` is fine though.
701 #[instrument(level = "debug", skip(self), ret)]
702 fn lower_node_id(&mut self, ast_node_id
: NodeId
) -> hir
::HirId
{
703 assert_ne
!(ast_node_id
, DUMMY_NODE_ID
);
705 match self.node_id_to_local_id
.entry(ast_node_id
) {
706 Entry
::Occupied(o
) => {
707 hir
::HirId { owner: self.current_hir_id_owner, local_id: *o.get() }
709 Entry
::Vacant(v
) => {
710 // Generate a new `HirId`.
711 let owner
= self.current_hir_id_owner
;
712 let local_id
= self.item_local_id_counter
;
713 let hir_id
= hir
::HirId { owner, local_id }
;
716 self.item_local_id_counter
.increment_by(1);
718 assert_ne
!(local_id
, hir
::ItemLocalId
::new(0));
719 if let Some(def_id
) = self.opt_local_def_id(ast_node_id
) {
720 self.children
.push((def_id
, hir
::MaybeOwner
::NonOwner(hir_id
)));
723 if let Some(traits
) = self.resolver
.trait_map
.remove(&ast_node_id
) {
724 self.trait_map
.insert(hir_id
.local_id
, traits
.into_boxed_slice());
732 /// Generate a new `HirId` without a backing `NodeId`.
733 #[instrument(level = "debug", skip(self), ret)]
734 fn next_id(&mut self) -> hir
::HirId
{
735 let owner
= self.current_hir_id_owner
;
736 let local_id
= self.item_local_id_counter
;
737 assert_ne
!(local_id
, hir
::ItemLocalId
::new(0));
738 self.item_local_id_counter
.increment_by(1);
739 hir
::HirId { owner, local_id }
742 #[instrument(level = "trace", skip(self))]
743 fn lower_res(&mut self, res
: Res
<NodeId
>) -> Res
{
744 let res
: Result
<Res
, ()> = res
.apply_id(|id
| {
745 let owner
= self.current_hir_id_owner
;
746 let local_id
= self.node_id_to_local_id
.get(&id
).copied().ok_or(())?
;
747 Ok(hir
::HirId { owner, local_id }
)
751 // We may fail to find a HirId when the Res points to a Local from an enclosing HIR owner.
752 // This can happen when trying to lower the return type `x` in erroneous code like
753 // async fn foo(x: u8) -> x {}
754 // In that case, `x` is lowered as a function parameter, and the return type is lowered as
755 // an opaque type as a synthesized HIR owner.
756 res
.unwrap_or(Res
::Err
)
759 fn expect_full_res(&mut self, id
: NodeId
) -> Res
<NodeId
> {
760 self.resolver
.get_partial_res(id
).map_or(Res
::Err
, |pr
| pr
.expect_full_res())
763 fn expect_full_res_from_use(&mut self, id
: NodeId
) -> impl Iterator
<Item
= Res
<NodeId
>> {
764 self.resolver
.get_import_res(id
).present_items()
767 fn make_lang_item_path(
769 lang_item
: hir
::LangItem
,
771 args
: Option
<&'hir hir
::GenericArgs
<'hir
>>,
772 ) -> &'hir hir
::Path
<'hir
> {
773 let def_id
= self.tcx
.require_lang_item(lang_item
, Some(span
));
774 let def_kind
= self.tcx
.def_kind(def_id
);
775 let res
= Res
::Def(def_kind
, def_id
);
776 self.arena
.alloc(hir
::Path
{
779 segments
: self.arena
.alloc_from_iter([hir
::PathSegment
{
780 ident
: Ident
::new(lang_item
.name(), span
),
781 hir_id
: self.next_id(),
789 /// Reuses the span but adds information like the kind of the desugaring and features that are
790 /// allowed inside this span.
791 fn mark_span_with_reason(
793 reason
: DesugaringKind
,
795 allow_internal_unstable
: Option
<Lrc
<[Symbol
]>>,
797 self.tcx
.with_stable_hashing_context(|hcx
| {
798 span
.mark_with_reason(allow_internal_unstable
, reason
, self.tcx
.sess
.edition(), hcx
)
802 /// Intercept all spans entering HIR.
803 /// Mark a span as relative to the current owning item.
804 fn lower_span(&self, span
: Span
) -> Span
{
805 if self.tcx
.sess
.opts
.incremental
.is_some() {
806 span
.with_parent(Some(self.current_hir_id_owner
.def_id
))
808 // Do not make spans relative when not using incremental compilation.
813 fn lower_ident(&self, ident
: Ident
) -> Ident
{
814 Ident
::new(ident
.name
, self.lower_span(ident
.span
))
817 /// Converts a lifetime into a new generic parameter.
818 #[instrument(level = "debug", skip(self))]
819 fn lifetime_res_to_generic_param(
824 source
: hir
::GenericParamSource
,
825 ) -> Option
<hir
::GenericParam
<'hir
>> {
826 let (name
, kind
) = match res
{
827 LifetimeRes
::Param { .. }
=> {
828 (hir
::ParamName
::Plain(ident
), hir
::LifetimeParamKind
::Explicit
)
830 LifetimeRes
::Fresh { param, .. }
=> {
831 // Late resolution delegates to us the creation of the `LocalDefId`.
832 let _def_id
= self.create_def(
833 self.current_hir_id_owner
.def_id
,
835 kw
::UnderscoreLifetime
,
836 DefKind
::LifetimeParam
,
841 (hir
::ParamName
::Fresh
, hir
::LifetimeParamKind
::Elided
)
843 LifetimeRes
::Static
| LifetimeRes
::Error
=> return None
,
845 "Unexpected lifetime resolution {:?} for {:?} at {:?}",
846 res
, ident
, ident
.span
849 let hir_id
= self.lower_node_id(node_id
);
850 let def_id
= self.local_def_id(node_id
);
851 Some(hir
::GenericParam
{
855 span
: self.lower_span(ident
.span
),
856 pure_wrt_drop
: false,
857 kind
: hir
::GenericParamKind
::Lifetime { kind }
,
863 /// Lowers a lifetime binder that defines `generic_params`, returning the corresponding HIR
864 /// nodes. The returned list includes any "extra" lifetime parameters that were added by the
865 /// name resolver owing to lifetime elision; this also populates the resolver's node-id->def-id
866 /// map, so that later calls to `opt_node_id_to_def_id` that refer to these extra lifetime
867 /// parameters will be successful.
868 #[instrument(level = "debug", skip(self))]
870 fn lower_lifetime_binder(
873 generic_params
: &[GenericParam
],
874 ) -> &'hir
[hir
::GenericParam
<'hir
>] {
875 let mut generic_params
: Vec
<_
> = self
876 .lower_generic_params_mut(generic_params
, hir
::GenericParamSource
::Binder
)
878 let extra_lifetimes
= self.resolver
.take_extra_lifetime_params(binder
);
879 debug
!(?extra_lifetimes
);
880 generic_params
.extend(extra_lifetimes
.into_iter().filter_map(|(ident
, node_id
, res
)| {
881 self.lifetime_res_to_generic_param(ident
, node_id
, res
, hir
::GenericParamSource
::Binder
)
883 let generic_params
= self.arena
.alloc_from_iter(generic_params
);
884 debug
!(?generic_params
);
889 fn with_dyn_type_scope
<T
>(&mut self, in_scope
: bool
, f
: impl FnOnce(&mut Self) -> T
) -> T
{
890 let was_in_dyn_type
= self.is_in_dyn_type
;
891 self.is_in_dyn_type
= in_scope
;
893 let result
= f(self);
895 self.is_in_dyn_type
= was_in_dyn_type
;
900 fn with_new_scopes
<T
>(&mut self, scope_span
: Span
, f
: impl FnOnce(&mut Self) -> T
) -> T
{
901 let current_item
= self.current_item
;
902 self.current_item
= Some(scope_span
);
904 let was_in_loop_condition
= self.is_in_loop_condition
;
905 self.is_in_loop_condition
= false;
907 let catch_scope
= self.catch_scope
.take();
908 let loop_scope
= self.loop_scope
.take();
910 self.catch_scope
= catch_scope
;
911 self.loop_scope
= loop_scope
;
913 self.is_in_loop_condition
= was_in_loop_condition
;
915 self.current_item
= current_item
;
920 fn lower_attrs(&mut self, id
: hir
::HirId
, attrs
: &[Attribute
]) -> Option
<&'hir
[Attribute
]> {
921 if attrs
.is_empty() {
924 debug_assert_eq
!(id
.owner
, self.current_hir_id_owner
);
925 let ret
= self.arena
.alloc_from_iter(attrs
.iter().map(|a
| self.lower_attr(a
)));
926 debug_assert
!(!ret
.is_empty());
927 self.attrs
.insert(id
.local_id
, ret
);
932 fn lower_attr(&self, attr
: &Attribute
) -> Attribute
{
933 // Note that we explicitly do not walk the path. Since we don't really
934 // lower attributes (we use the AST version) there is nowhere to keep
935 // the `HirId`s. We don't actually need HIR version of attributes anyway.
936 // Tokens are also not needed after macro expansion and parsing.
937 let kind
= match attr
.kind
{
938 AttrKind
::Normal(ref normal
) => AttrKind
::Normal(P(NormalAttr
{
940 path
: normal
.item
.path
.clone(),
941 args
: self.lower_attr_args(&normal
.item
.args
),
946 AttrKind
::DocComment(comment_kind
, data
) => AttrKind
::DocComment(comment_kind
, data
),
949 Attribute { kind, id: attr.id, style: attr.style, span: self.lower_span(attr.span) }
952 fn alias_attrs(&mut self, id
: hir
::HirId
, target_id
: hir
::HirId
) {
953 debug_assert_eq
!(id
.owner
, self.current_hir_id_owner
);
954 debug_assert_eq
!(target_id
.owner
, self.current_hir_id_owner
);
955 if let Some(&a
) = self.attrs
.get(&target_id
.local_id
) {
956 debug_assert
!(!a
.is_empty());
957 self.attrs
.insert(id
.local_id
, a
);
961 fn lower_attr_args(&self, args
: &AttrArgs
) -> AttrArgs
{
963 AttrArgs
::Empty
=> AttrArgs
::Empty
,
964 AttrArgs
::Delimited(args
) => AttrArgs
::Delimited(self.lower_delim_args(args
)),
965 // This is an inert key-value attribute - it will never be visible to macros
966 // after it gets lowered to HIR. Therefore, we can extract literals to handle
967 // nonterminals in `#[doc]` (e.g. `#[doc = $e]`).
968 AttrArgs
::Eq(eq_span
, AttrArgsEq
::Ast(expr
)) => {
969 // In valid code the value always ends up as a single literal. Otherwise, a dummy
970 // literal suffices because the error is handled elsewhere.
971 let lit
= if let ExprKind
::Lit(token_lit
) = expr
.kind
972 && let Ok(lit
) = MetaItemLit
::from_token_lit(token_lit
, expr
.span
)
983 AttrArgs
::Eq(*eq_span
, AttrArgsEq
::Hir(lit
))
985 AttrArgs
::Eq(_
, AttrArgsEq
::Hir(lit
)) => {
986 unreachable
!("in literal form when lowering mac args eq: {:?}", lit
)
991 fn lower_delim_args(&self, args
: &DelimArgs
) -> DelimArgs
{
992 DelimArgs { dspan: args.dspan, delim: args.delim, tokens: args.tokens.flattened() }
995 /// Given an associated type constraint like one of these:
997 /// ```ignore (illustrative)
998 /// T: Iterator<Item: Debug>
1000 /// T: Iterator<Item = Debug>
1004 /// returns a `hir::TypeBinding` representing `Item`.
1005 #[instrument(level = "debug", skip(self))]
1006 fn lower_assoc_ty_constraint(
1008 constraint
: &AssocConstraint
,
1009 itctx
: &ImplTraitContext
,
1010 ) -> hir
::TypeBinding
<'hir
> {
1011 debug
!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint
, itctx
);
1012 // lower generic arguments of identifier in constraint
1013 let gen_args
= if let Some(gen_args
) = &constraint
.gen_args
{
1014 let gen_args_ctor
= match gen_args
{
1015 GenericArgs
::AngleBracketed(data
) => {
1016 self.lower_angle_bracketed_parameter_data(data
, ParamMode
::Explicit
, itctx
).0
1018 GenericArgs
::Parenthesized(data
) => {
1019 if data
.inputs
.is_empty() && matches
!(data
.output
, FnRetTy
::Default(..)) {
1020 let parenthesized
= if self.tcx
.features().return_type_notation
{
1021 hir
::GenericArgsParentheses
::ReturnTypeNotation
1023 self.emit_bad_parenthesized_trait_in_assoc_ty(data
);
1024 hir
::GenericArgsParentheses
::No
1027 args
: Default
::default(),
1030 span
: data
.inputs_span
,
1032 } else if let Some(first_char
) = constraint
.ident
.as_str().chars().next()
1033 && first_char
.is_ascii_lowercase()
1035 let mut err
= if !data
.inputs
.is_empty() {
1036 self.tcx
.sess
.create_err(errors
::BadReturnTypeNotation
::Inputs
{
1037 span
: data
.inputs_span
,
1039 } else if let FnRetTy
::Ty(ty
) = &data
.output
{
1040 self.tcx
.sess
.create_err(errors
::BadReturnTypeNotation
::Output
{
1041 span
: data
.inputs_span
.shrink_to_hi().to(ty
.span
),
1044 unreachable
!("inputs are empty and return type is not provided")
1046 if !self.tcx
.features().return_type_notation
1047 && self.tcx
.sess
.is_nightly_build()
1049 add_feature_diagnostics(
1051 &self.tcx
.sess
.parse_sess
,
1052 sym
::return_type_notation
,
1057 args
: Default
::default(),
1059 parenthesized
: hir
::GenericArgsParentheses
::ReturnTypeNotation
,
1063 self.emit_bad_parenthesized_trait_in_assoc_ty(data
);
1064 // FIXME(return_type_notation): we could issue a feature error
1065 // if the parens are empty and there's no return type.
1066 self.lower_angle_bracketed_parameter_data(
1067 &data
.as_angle_bracketed_args(),
1068 ParamMode
::Explicit
,
1075 gen_args_ctor
.into_generic_args(self)
1077 self.arena
.alloc(hir
::GenericArgs
::none())
1079 let kind
= match &constraint
.kind
{
1080 AssocConstraintKind
::Equality { term }
=> {
1081 let term
= match term
{
1082 Term
::Ty(ty
) => self.lower_ty(ty
, itctx
).into(),
1083 Term
::Const(c
) => self.lower_anon_const(c
).into(),
1085 hir
::TypeBindingKind
::Equality { term }
1087 AssocConstraintKind
::Bound { bounds }
=> {
1088 enum DesugarKind
<'a
> {
1090 Error(&'a ImplTraitPosition
),
1094 // Piggy-back on the `impl Trait` context to figure out the correct behavior.
1095 let desugar_kind
= match itctx
{
1096 // We are in the return position:
1098 // fn foo() -> impl Iterator<Item: Debug>
1102 // fn foo() -> impl Iterator<Item = impl Debug>
1103 ImplTraitContext
::ReturnPositionOpaqueTy { .. }
1104 | ImplTraitContext
::TypeAliasesOpaqueTy { .. }
=> DesugarKind
::ImplTrait
,
1106 // We are in the argument position, but within a dyn type:
1108 // fn foo(x: dyn Iterator<Item: Debug>)
1112 // fn foo(x: dyn Iterator<Item = impl Debug>)
1113 ImplTraitContext
::Universal
if self.is_in_dyn_type
=> DesugarKind
::ImplTrait
,
1115 ImplTraitContext
::Disallowed(position
) if self.is_in_dyn_type
=> {
1116 DesugarKind
::Error(position
)
1119 // We are in the parameter position, but not within a dyn type:
1121 // fn foo(x: impl Iterator<Item: Debug>)
1123 // so we leave it as is and this gets expanded in astconv to a bound like
1124 // `<T as Iterator>::Item: Debug` where `T` is the type parameter for the
1126 _
=> DesugarKind
::Bound
,
1129 match desugar_kind
{
1130 DesugarKind
::ImplTrait
=> {
1131 // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by
1132 // constructing the HIR for `impl bounds...` and then lowering that.
1134 let impl_trait_node_id
= self.next_node_id();
1135 // Shift `impl Trait` lifetime captures from the associated type bound's
1136 // node id to the opaque node id, so that the opaque can actually use
1137 // these lifetime bounds.
1139 .remap_extra_lifetime_params(constraint
.id
, impl_trait_node_id
);
1141 self.with_dyn_type_scope(false, |this
| {
1142 let node_id
= this
.next_node_id();
1143 let ty
= this
.lower_ty(
1146 kind
: TyKind
::ImplTrait(impl_trait_node_id
, bounds
.clone()),
1147 span
: this
.lower_span(constraint
.span
),
1153 hir
::TypeBindingKind
::Equality { term: ty.into() }
1156 DesugarKind
::Bound
=> {
1157 // Desugar `AssocTy: Bounds` into a type binding where the
1158 // later desugars into a trait predicate.
1159 let bounds
= self.lower_param_bounds(bounds
, itctx
);
1161 hir
::TypeBindingKind
::Constraint { bounds }
1163 DesugarKind
::Error(position
) => {
1164 let guar
= self.tcx
.sess
.emit_err(errors
::MisplacedAssocTyBinding
{
1165 span
: constraint
.span
,
1166 position
: DiagnosticArgFromDisplay(position
),
1169 &*self.arena
.alloc(self.ty(constraint
.span
, hir
::TyKind
::Err(guar
)));
1170 hir
::TypeBindingKind
::Equality { term: err_ty.into() }
1177 hir_id
: self.lower_node_id(constraint
.id
),
1178 ident
: self.lower_ident(constraint
.ident
),
1181 span
: self.lower_span(constraint
.span
),
1185 fn emit_bad_parenthesized_trait_in_assoc_ty(&self, data
: &ParenthesizedArgs
) {
1186 // Suggest removing empty parentheses: "Trait()" -> "Trait"
1187 let sub
= if data
.inputs
.is_empty() {
1188 let parentheses_span
=
1189 data
.inputs_span
.shrink_to_lo().to(data
.inputs_span
.shrink_to_hi());
1190 AssocTyParenthesesSub
::Empty { parentheses_span }
1192 // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
1194 // Start of parameters to the 1st argument
1195 let open_param
= data
.inputs_span
.shrink_to_lo().to(data
1201 // End of last argument to end of parameters
1203 data
.inputs
.last().unwrap().span
.shrink_to_hi().to(data
.inputs_span
.shrink_to_hi());
1204 AssocTyParenthesesSub
::NotEmpty { open_param, close_param }
1206 self.tcx
.sess
.emit_err(AssocTyParentheses { span: data.span, sub }
);
1209 #[instrument(level = "debug", skip(self))]
1210 fn lower_generic_arg(
1212 arg
: &ast
::GenericArg
,
1213 itctx
: &ImplTraitContext
,
1214 ) -> hir
::GenericArg
<'hir
> {
1216 ast
::GenericArg
::Lifetime(lt
) => GenericArg
::Lifetime(self.lower_lifetime(lt
)),
1217 ast
::GenericArg
::Type(ty
) => {
1219 TyKind
::Infer
if self.tcx
.features().generic_arg_infer
=> {
1220 return GenericArg
::Infer(hir
::InferArg
{
1221 hir_id
: self.lower_node_id(ty
.id
),
1222 span
: self.lower_span(ty
.span
),
1225 // We parse const arguments as path types as we cannot distinguish them during
1226 // parsing. We try to resolve that ambiguity by attempting resolution in both the
1227 // type and value namespaces. If we resolved the path in the value namespace, we
1228 // transform it into a generic const argument.
1229 TyKind
::Path(None
, path
) => {
1230 if let Some(res
) = self
1232 .get_partial_res(ty
.id
)
1233 .and_then(|partial_res
| partial_res
.full_res())
1235 if !res
.matches_ns(Namespace
::TypeNS
)
1236 && path
.is_potential_trivial_const_arg()
1239 "lower_generic_arg: Lowering type argument as const argument: {:?}",
1243 // Construct an AnonConst where the expr is the "ty"'s path.
1245 let parent_def_id
= self.current_hir_id_owner
;
1246 let node_id
= self.next_node_id();
1247 let span
= self.lower_span(ty
.span
);
1249 // Add a definition for the in-band const def.
1250 let def_id
= self.create_def(
1251 parent_def_id
.def_id
,
1258 let path_expr
= Expr
{
1260 kind
: ExprKind
::Path(None
, path
.clone()),
1262 attrs
: AttrVec
::new(),
1266 let ct
= self.with_new_scopes(span
, |this
| hir
::AnonConst
{
1268 hir_id
: this
.lower_node_id(node_id
),
1269 body
: this
.lower_const_body(path_expr
.span
, Some(&path_expr
)),
1271 return GenericArg
::Const(ConstArg
{
1274 is_desugared_from_effects
: false,
1281 GenericArg
::Type(self.lower_ty(ty
, itctx
))
1283 ast
::GenericArg
::Const(ct
) => GenericArg
::Const(ConstArg
{
1284 value
: self.lower_anon_const(ct
),
1285 span
: self.lower_span(ct
.value
.span
),
1286 is_desugared_from_effects
: false,
1291 #[instrument(level = "debug", skip(self))]
1292 fn lower_ty(&mut self, t
: &Ty
, itctx
: &ImplTraitContext
) -> &'hir hir
::Ty
<'hir
> {
1293 self.arena
.alloc(self.lower_ty_direct(t
, itctx
))
1299 qself
: &Option
<ptr
::P
<QSelf
>>,
1301 param_mode
: ParamMode
,
1302 itctx
: &ImplTraitContext
,
1303 ) -> hir
::Ty
<'hir
> {
1304 // Check whether we should interpret this as a bare trait object.
1305 // This check mirrors the one in late resolution. We only introduce this special case in
1306 // the rare occurrence we need to lower `Fresh` anonymous lifetimes.
1307 // The other cases when a qpath should be opportunistically made a trait object are handled
1310 && let Some(partial_res
) = self.resolver
.get_partial_res(t
.id
)
1311 && let Some(Res
::Def(DefKind
::Trait
| DefKind
::TraitAlias
, _
)) = partial_res
.full_res()
1313 let (bounds
, lifetime_bound
) = self.with_dyn_type_scope(true, |this
| {
1314 let bound
= this
.lower_poly_trait_ref(
1316 bound_generic_params
: ThinVec
::new(),
1317 trait_ref
: TraitRef { path: path.clone(), ref_id: t.id }
,
1323 let bounds
= this
.arena
.alloc_from_iter([bound
]);
1324 let lifetime_bound
= this
.elided_dyn_bound(t
.span
);
1325 (bounds
, lifetime_bound
)
1327 let kind
= hir
::TyKind
::TraitObject(bounds
, lifetime_bound
, TraitObjectSyntax
::None
);
1328 return hir
::Ty { kind, span: self.lower_span(t.span), hir_id: self.next_id() }
;
1331 let id
= self.lower_node_id(t
.id
);
1332 let qpath
= self.lower_qpath(t
.id
, qself
, path
, param_mode
, itctx
, None
);
1333 self.ty_path(id
, t
.span
, qpath
)
1336 fn ty(&mut self, span
: Span
, kind
: hir
::TyKind
<'hir
>) -> hir
::Ty
<'hir
> {
1337 hir
::Ty { hir_id: self.next_id(), kind, span: self.lower_span(span) }
1340 fn ty_tup(&mut self, span
: Span
, tys
: &'hir
[hir
::Ty
<'hir
>]) -> hir
::Ty
<'hir
> {
1341 self.ty(span
, hir
::TyKind
::Tup(tys
))
1344 fn lower_ty_direct(&mut self, t
: &Ty
, itctx
: &ImplTraitContext
) -> hir
::Ty
<'hir
> {
1345 let kind
= match &t
.kind
{
1346 TyKind
::Infer
=> hir
::TyKind
::Infer
,
1348 hir
::TyKind
::Err(self.tcx
.sess
.span_delayed_bug(t
.span
, "TyKind::Err lowered"))
1350 // FIXME(unnamed_fields): IMPLEMENTATION IN PROGRESS
1351 #[allow(rustc::untranslatable_diagnostic)]
1352 #[allow(rustc::diagnostic_outside_of_impl)]
1353 TyKind
::AnonStruct(ref _fields
) => hir
::TyKind
::Err(
1354 self.tcx
.sess
.span_err(t
.span
, "anonymous structs are unimplemented"),
1356 // FIXME(unnamed_fields): IMPLEMENTATION IN PROGRESS
1357 #[allow(rustc::untranslatable_diagnostic)]
1358 #[allow(rustc::diagnostic_outside_of_impl)]
1359 TyKind
::AnonUnion(ref _fields
) => hir
::TyKind
::Err(
1360 self.tcx
.sess
.span_err(t
.span
, "anonymous unions are unimplemented"),
1362 TyKind
::Slice(ty
) => hir
::TyKind
::Slice(self.lower_ty(ty
, itctx
)),
1363 TyKind
::Ptr(mt
) => hir
::TyKind
::Ptr(self.lower_mt(mt
, itctx
)),
1364 TyKind
::Ref(region
, mt
) => {
1365 let region
= region
.unwrap_or_else(|| {
1366 let id
= if let Some(LifetimeRes
::ElidedAnchor { start, end }
) =
1367 self.resolver
.get_lifetime_res(t
.id
)
1369 debug_assert_eq
!(start
.plus(1), end
);
1374 let span
= self.tcx
.sess
.source_map().start_point(t
.span
).shrink_to_hi();
1375 Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id }
1377 let lifetime
= self.lower_lifetime(®ion
);
1378 hir
::TyKind
::Ref(lifetime
, self.lower_mt(mt
, itctx
))
1380 TyKind
::BareFn(f
) => {
1381 let generic_params
= self.lower_lifetime_binder(t
.id
, &f
.generic_params
);
1382 hir
::TyKind
::BareFn(self.arena
.alloc(hir
::BareFnTy
{
1384 unsafety
: self.lower_unsafety(f
.unsafety
),
1385 abi
: self.lower_extern(f
.ext
),
1386 decl
: self.lower_fn_decl(&f
.decl
, t
.id
, t
.span
, FnDeclKind
::Pointer
, None
),
1387 param_names
: self.lower_fn_params_to_names(&f
.decl
),
1390 TyKind
::Never
=> hir
::TyKind
::Never
,
1391 TyKind
::Tup(tys
) => hir
::TyKind
::Tup(
1392 self.arena
.alloc_from_iter(tys
.iter().map(|ty
| self.lower_ty_direct(ty
, itctx
))),
1394 TyKind
::Paren(ty
) => {
1395 return self.lower_ty_direct(ty
, itctx
);
1397 TyKind
::Path(qself
, path
) => {
1398 return self.lower_path_ty(t
, qself
, path
, ParamMode
::Explicit
, itctx
);
1400 TyKind
::ImplicitSelf
=> {
1401 let hir_id
= self.next_id();
1402 let res
= self.expect_full_res(t
.id
);
1403 let res
= self.lower_res(res
);
1404 hir
::TyKind
::Path(hir
::QPath
::Resolved(
1406 self.arena
.alloc(hir
::Path
{
1408 segments
: arena_vec
![self; hir
::PathSegment
::new(
1409 Ident
::with_dummy_span(kw
::SelfUpper
),
1413 span
: self.lower_span(t
.span
),
1417 TyKind
::Array(ty
, length
) => {
1418 hir
::TyKind
::Array(self.lower_ty(ty
, itctx
), self.lower_array_length(length
))
1420 TyKind
::Typeof(expr
) => hir
::TyKind
::Typeof(self.lower_anon_const(expr
)),
1421 TyKind
::TraitObject(bounds
, kind
) => {
1422 let mut lifetime_bound
= None
;
1423 let (bounds
, lifetime_bound
) = self.with_dyn_type_scope(true, |this
| {
1425 this
.arena
.alloc_from_iter(bounds
.iter().filter_map(|bound
| match bound
{
1426 GenericBound
::Trait(
1428 modifier @
(TraitBoundModifier
::None
1429 | TraitBoundModifier
::MaybeConst(_
)
1430 | TraitBoundModifier
::Negative
),
1432 Some(this
.lower_poly_trait_ref(ty
, itctx
, modifier
.to_constness()))
1434 // `~const ?Bound` will cause an error during AST validation
1435 // anyways, so treat it like `?Bound` as compilation proceeds.
1436 GenericBound
::Trait(
1438 TraitBoundModifier
::Maybe
1439 | TraitBoundModifier
::MaybeConstMaybe
1440 | TraitBoundModifier
::MaybeConstNegative
,
1442 GenericBound
::Outlives(lifetime
) => {
1443 if lifetime_bound
.is_none() {
1444 lifetime_bound
= Some(this
.lower_lifetime(lifetime
));
1449 let lifetime_bound
=
1450 lifetime_bound
.unwrap_or_else(|| this
.elided_dyn_bound(t
.span
));
1451 (bounds
, lifetime_bound
)
1453 hir
::TyKind
::TraitObject(bounds
, lifetime_bound
, *kind
)
1455 TyKind
::ImplTrait(def_node_id
, bounds
) => {
1458 ImplTraitContext
::ReturnPositionOpaqueTy { origin, fn_kind }
=> self
1459 .lower_opaque_impl_trait(
1467 &ImplTraitContext
::TypeAliasesOpaqueTy { in_assoc_ty }
=> self
1468 .lower_opaque_impl_trait(
1470 hir
::OpaqueTyOrigin
::TyAlias { in_assoc_ty }
,
1476 ImplTraitContext
::Universal
=> {
1479 // HACK: pprust breaks strings with newlines when the type
1480 // gets too long. We don't want these to show up in compiler
1481 // output or built artifacts, so replace them here...
1482 // Perhaps we should instead format APITs more robustly.
1483 let ident
= Ident
::from_str_and_span(
1484 &pprust
::ty_to_string(t
).replace('
\n'
, " "),
1489 self.current_hir_id_owner
.def_id
,
1495 let (param
, bounds
, path
) = self.lower_universal_param_and_bounds(
1501 self.impl_trait_defs
.push(param
);
1502 if let Some(bounds
) = bounds
{
1503 self.impl_trait_bounds
.push(bounds
);
1507 ImplTraitContext
::FeatureGated(position
, feature
) => {
1511 .create_feature_err(
1512 MisplacedImplTrait
{
1514 position
: DiagnosticArgFromDisplay(position
),
1519 hir
::TyKind
::Err(guar
)
1521 ImplTraitContext
::Disallowed(position
) => {
1522 let guar
= self.tcx
.sess
.emit_err(MisplacedImplTrait
{
1524 position
: DiagnosticArgFromDisplay(position
),
1526 hir
::TyKind
::Err(guar
)
1530 TyKind
::MacCall(_
) => panic
!("`TyKind::MacCall` should have been expanded by now"),
1531 TyKind
::CVarArgs
=> {
1532 let guar
= self.tcx
.sess
.span_delayed_bug(
1534 "`TyKind::CVarArgs` should have been handled elsewhere",
1536 hir
::TyKind
::Err(guar
)
1540 hir
::Ty { kind, span: self.lower_span(t.span), hir_id: self.lower_node_id(t.id) }
1543 /// Lowers a `ReturnPositionOpaqueTy` (`-> impl Trait`) or a `TypeAliasesOpaqueTy` (`type F =
1544 /// impl Trait`): this creates the associated Opaque Type (TAIT) definition and then returns a
1545 /// HIR type that references the TAIT.
1547 /// Given a function definition like:
1550 /// use std::fmt::Debug;
1552 /// fn test<'a, T: Debug>(x: &'a T) -> impl Debug + 'a {
1557 /// we will create a TAIT definition in the HIR like
1559 /// ```rust,ignore (pseudo-Rust)
1560 /// type TestReturn<'a, T, 'x> = impl Debug + 'x
1563 /// and return a type like `TestReturn<'static, T, 'a>`, so that the function looks like:
1565 /// ```rust,ignore (pseudo-Rust)
1566 /// fn test<'a, T: Debug>(x: &'a T) -> TestReturn<'static, T, 'a>
1569 /// Note the subtlety around type parameters! The new TAIT, `TestReturn`, inherits all the
1570 /// type parameters from the function `test` (this is implemented in the query layer, they aren't
1571 /// added explicitly in the HIR). But this includes all the lifetimes, and we only want to
1572 /// capture the lifetimes that are referenced in the bounds. Therefore, we add *extra* lifetime parameters
1573 /// for the lifetimes that get captured (`'x`, in our example above) and reference those.
1574 #[instrument(level = "debug", skip(self), ret)]
1575 fn lower_opaque_impl_trait(
1578 origin
: hir
::OpaqueTyOrigin
,
1579 opaque_ty_node_id
: NodeId
,
1580 bounds
: &GenericBounds
,
1581 fn_kind
: Option
<FnDeclKind
>,
1582 itctx
: &ImplTraitContext
,
1583 ) -> hir
::TyKind
<'hir
> {
1584 // Make sure we know that some funky desugaring has been going on here.
1585 // This is a first: there is code in other places like for loop
1586 // desugaring that explicitly states that we don't want to track that.
1587 // Not tracking it makes lints in rustc and clippy very fragile, as
1588 // frequently opened issues show.
1589 let opaque_ty_span
= self.mark_span_with_reason(DesugaringKind
::OpaqueTy
, span
, None
);
1591 let captured_lifetimes_to_duplicate
= match origin
{
1592 hir
::OpaqueTyOrigin
::TyAlias { .. }
=> {
1593 // in a TAIT like `type Foo<'a> = impl Foo<'a>`, we don't duplicate any
1594 // lifetimes, since we don't have the issue that any are late-bound.
1597 hir
::OpaqueTyOrigin
::FnReturn(..) => {
1599 fn_kind
.expect("expected RPITs to be lowered with a FnKind"),
1600 FnDeclKind
::Impl
| FnDeclKind
::Trait
1601 ) || self.tcx
.features().lifetime_capture_rules_2024
1602 || span
.at_least_rust_2024()
1604 // return-position impl trait in trait was decided to capture all
1605 // in-scope lifetimes, which we collect for all opaques during resolution.
1607 .take_extra_lifetime_params(opaque_ty_node_id
)
1609 .map(|(ident
, id
, _
)| Lifetime { id, ident }
)
1612 // in fn return position, like the `fn test<'a>() -> impl Debug + 'a`
1613 // example, we only need to duplicate lifetimes that appear in the
1614 // bounds, since those are the only ones that are captured by the opaque.
1615 lifetime_collector
::lifetimes_in_bounds(self.resolver
, bounds
)
1618 hir
::OpaqueTyOrigin
::AsyncFn(..) => {
1619 unreachable
!("should be using `lower_async_fn_ret_ty`")
1622 debug
!(?captured_lifetimes_to_duplicate
);
1624 self.lower_opaque_inner(
1627 matches
!(fn_kind
, Some(FnDeclKind
::Trait
)),
1628 captured_lifetimes_to_duplicate
,
1631 |this
| this
.lower_param_bounds(bounds
, itctx
),
1635 fn lower_opaque_inner(
1637 opaque_ty_node_id
: NodeId
,
1638 origin
: hir
::OpaqueTyOrigin
,
1640 captured_lifetimes_to_duplicate
: Vec
<Lifetime
>,
1642 opaque_ty_span
: Span
,
1643 lower_item_bounds
: impl FnOnce(&mut Self) -> &'hir
[hir
::GenericBound
<'hir
>],
1644 ) -> hir
::TyKind
<'hir
> {
1645 let opaque_ty_def_id
= self.create_def(
1646 self.current_hir_id_owner
.def_id
,
1652 debug
!(?opaque_ty_def_id
);
1654 // Map from captured (old) lifetime to synthetic (new) lifetime.
1655 // Used to resolve lifetimes in the bounds of the opaque.
1656 let mut captured_to_synthesized_mapping
= LocalDefIdMap
::default();
1657 // List of (early-bound) synthetic lifetimes that are owned by the opaque.
1658 // This is used to create the `hir::Generics` owned by the opaque.
1659 let mut synthesized_lifetime_definitions
= vec
![];
1660 // Pairs of lifetime arg (that resolves to the captured lifetime)
1661 // and the def-id of the (early-bound) synthetic lifetime definition.
1662 // This is used both to create generics for the `TyKind::OpaqueDef` that
1663 // we return, and also as a captured lifetime mapping for RPITITs.
1664 let mut synthesized_lifetime_args
= vec
![];
1666 for lifetime
in captured_lifetimes_to_duplicate
{
1667 let res
= self.resolver
.get_lifetime_res(lifetime
.id
).unwrap_or(LifetimeRes
::Error
);
1668 let old_def_id
= match res
{
1669 LifetimeRes
::Param { param: old_def_id, binder: _ }
=> old_def_id
,
1671 LifetimeRes
::Fresh { param, binder: _ }
=> {
1672 debug_assert_eq
!(lifetime
.ident
.name
, kw
::UnderscoreLifetime
);
1673 if let Some(old_def_id
) = self.orig_opt_local_def_id(param
) {
1678 .span_delayed_bug(lifetime
.ident
.span
, "no def-id for fresh lifetime");
1683 // Opaques do not capture `'static`
1684 LifetimeRes
::Static
| LifetimeRes
::Error
=> {
1689 let bug_msg
= format
!(
1690 "Unexpected lifetime resolution {:?} for {:?} at {:?}",
1691 res
, lifetime
.ident
, lifetime
.ident
.span
1693 span_bug
!(lifetime
.ident
.span
, "{}", bug_msg
);
1697 if captured_to_synthesized_mapping
.get(&old_def_id
).is_none() {
1698 // Create a new lifetime parameter local to the opaque.
1699 let duplicated_lifetime_node_id
= self.next_node_id();
1700 let duplicated_lifetime_def_id
= self.create_def(
1702 duplicated_lifetime_node_id
,
1703 lifetime
.ident
.name
,
1704 DefKind
::LifetimeParam
,
1705 self.lower_span(lifetime
.ident
.span
),
1707 captured_to_synthesized_mapping
.insert(old_def_id
, duplicated_lifetime_def_id
);
1708 // FIXME: Instead of doing this, we could move this whole loop
1709 // into the `with_hir_id_owner`, then just directly construct
1710 // the `hir::GenericParam` here.
1711 synthesized_lifetime_definitions
.push((
1712 duplicated_lifetime_node_id
,
1713 duplicated_lifetime_def_id
,
1714 self.lower_ident(lifetime
.ident
),
1717 // Now make an arg that we can use for the generic params of the opaque tykind.
1718 let id
= self.next_node_id();
1719 let lifetime_arg
= self.new_named_lifetime_with_res(id
, lifetime
.ident
, res
);
1720 let duplicated_lifetime_def_id
= self.local_def_id(duplicated_lifetime_node_id
);
1721 synthesized_lifetime_args
.push((lifetime_arg
, duplicated_lifetime_def_id
))
1725 self.with_hir_id_owner(opaque_ty_node_id
, |this
| {
1726 // Install the remapping from old to new (if any). This makes sure that
1727 // any lifetimes that would have resolved to the def-id of captured
1728 // lifetimes are remapped to the new *synthetic* lifetimes of the opaque.
1730 .with_remapping(captured_to_synthesized_mapping
, |this
| lower_item_bounds(this
));
1732 let generic_params
= this
.arena
.alloc_from_iter(
1733 synthesized_lifetime_definitions
.iter().map(|&(new_node_id
, new_def_id
, ident
)| {
1734 let hir_id
= this
.lower_node_id(new_node_id
);
1735 let (name
, kind
) = if ident
.name
== kw
::UnderscoreLifetime
{
1736 (hir
::ParamName
::Fresh
, hir
::LifetimeParamKind
::Elided
)
1738 (hir
::ParamName
::Plain(ident
), hir
::LifetimeParamKind
::Explicit
)
1746 pure_wrt_drop
: false,
1747 kind
: hir
::GenericParamKind
::Lifetime { kind }
,
1749 source
: hir
::GenericParamSource
::Generics
,
1753 debug
!("lower_async_fn_ret_ty: generic_params={:#?}", generic_params
);
1755 let lifetime_mapping
= self.arena
.alloc_slice(&synthesized_lifetime_args
);
1757 let opaque_ty_item
= hir
::OpaqueTy
{
1758 generics
: this
.arena
.alloc(hir
::Generics
{
1759 params
: generic_params
,
1761 has_where_clause_predicates
: false,
1762 where_clause_span
: this
.lower_span(span
),
1763 span
: this
.lower_span(span
),
1771 // Generate an `type Foo = impl Trait;` declaration.
1772 trace
!("registering opaque type with id {:#?}", opaque_ty_def_id
);
1773 let opaque_ty_item
= hir
::Item
{
1774 owner_id
: hir
::OwnerId { def_id: opaque_ty_def_id }
,
1775 ident
: Ident
::empty(),
1776 kind
: hir
::ItemKind
::OpaqueTy(this
.arena
.alloc(opaque_ty_item
)),
1777 vis_span
: this
.lower_span(span
.shrink_to_lo()),
1778 span
: this
.lower_span(opaque_ty_span
),
1781 hir
::OwnerNode
::Item(this
.arena
.alloc(opaque_ty_item
))
1784 let generic_args
= self.arena
.alloc_from_iter(
1785 synthesized_lifetime_args
1787 .map(|(lifetime
, _
)| hir
::GenericArg
::Lifetime(*lifetime
)),
1790 // Create the `Foo<...>` reference itself. Note that the `type
1791 // Foo = impl Trait` is, internally, created as a child of the
1792 // async fn, so the *type parameters* are inherited. It's
1793 // only the lifetime parameters that we must supply.
1794 hir
::TyKind
::OpaqueDef(
1795 hir
::ItemId { owner_id: hir::OwnerId { def_id: opaque_ty_def_id }
},
1801 fn lower_fn_params_to_names(&mut self, decl
: &FnDecl
) -> &'hir
[Ident
] {
1802 self.arena
.alloc_from_iter(decl
.inputs
.iter().map(|param
| match param
.pat
.kind
{
1803 PatKind
::Ident(_
, ident
, _
) => self.lower_ident(ident
),
1804 _
=> Ident
::new(kw
::Empty
, self.lower_span(param
.pat
.span
)),
1808 /// Lowers a function declaration.
1810 /// `decl`: the unlowered (AST) function declaration.
1812 /// `fn_node_id`: `impl Trait` arguments are lowered into generic parameters on the given
1815 /// `transform_return_type`: if `Some`, applies some conversion to the return type, such as is
1816 /// needed for `async fn` and `gen fn`. See [`CoroutineKind`] for more details.
1817 #[instrument(level = "debug", skip(self))]
1824 coro
: Option
<CoroutineKind
>,
1825 ) -> &'hir hir
::FnDecl
<'hir
> {
1826 let c_variadic
= decl
.c_variadic();
1828 // Skip the `...` (`CVarArgs`) trailing arguments from the AST,
1829 // as they are not explicit in HIR/Ty function signatures.
1830 // (instead, the `c_variadic` flag is set to `true`)
1831 let mut inputs
= &decl
.inputs
[..];
1833 inputs
= &inputs
[..inputs
.len() - 1];
1835 let inputs
= self.arena
.alloc_from_iter(inputs
.iter().map(|param
| {
1836 let itctx
= if kind
.param_impl_trait_allowed() {
1837 ImplTraitContext
::Universal
1839 ImplTraitContext
::Disallowed(match kind
{
1840 FnDeclKind
::Fn
| FnDeclKind
::Inherent
=> {
1841 unreachable
!("fn should allow APIT")
1843 FnDeclKind
::ExternFn
=> ImplTraitPosition
::ExternFnParam
,
1844 FnDeclKind
::Closure
=> ImplTraitPosition
::ClosureParam
,
1845 FnDeclKind
::Pointer
=> ImplTraitPosition
::PointerParam
,
1846 FnDeclKind
::Trait
=> ImplTraitPosition
::TraitParam
,
1847 FnDeclKind
::Impl
=> ImplTraitPosition
::ImplParam
,
1850 self.lower_ty_direct(¶m
.ty
, &itctx
)
1853 let output
= match coro
{
1855 let fn_def_id
= self.local_def_id(fn_node_id
);
1856 self.lower_coroutine_fn_ret_ty(&decl
.output
, fn_def_id
, coro
, kind
, fn_span
)
1858 None
=> match &decl
.output
{
1859 FnRetTy
::Ty(ty
) => {
1860 let context
= if kind
.return_impl_trait_allowed() {
1861 let fn_def_id
= self.local_def_id(fn_node_id
);
1862 ImplTraitContext
::ReturnPositionOpaqueTy
{
1863 origin
: hir
::OpaqueTyOrigin
::FnReturn(fn_def_id
),
1867 ImplTraitContext
::Disallowed(match kind
{
1869 | FnDeclKind
::Inherent
1871 | FnDeclKind
::Impl
=> {
1872 unreachable
!("fn should allow return-position impl trait in traits")
1874 FnDeclKind
::ExternFn
=> ImplTraitPosition
::ExternFnReturn
,
1875 FnDeclKind
::Closure
=> ImplTraitPosition
::ClosureReturn
,
1876 FnDeclKind
::Pointer
=> ImplTraitPosition
::PointerReturn
,
1879 hir
::FnRetTy
::Return(self.lower_ty(ty
, &context
))
1881 FnRetTy
::Default(span
) => hir
::FnRetTy
::DefaultReturn(self.lower_span(*span
)),
1885 self.arena
.alloc(hir
::FnDecl
{
1889 lifetime_elision_allowed
: self.resolver
.lifetime_elision_allowed
.contains(&fn_node_id
),
1890 implicit_self
: decl
.inputs
.get(0).map_or(hir
::ImplicitSelfKind
::None
, |arg
| {
1891 let is_mutable_pat
= matches
!(
1893 PatKind
::Ident(hir
::BindingAnnotation(_
, Mutability
::Mut
), ..)
1896 match &arg
.ty
.kind
{
1897 TyKind
::ImplicitSelf
if is_mutable_pat
=> hir
::ImplicitSelfKind
::Mut
,
1898 TyKind
::ImplicitSelf
=> hir
::ImplicitSelfKind
::Imm
,
1899 // Given we are only considering `ImplicitSelf` types, we needn't consider
1900 // the case where we have a mutable pattern to a reference as that would
1901 // no longer be an `ImplicitSelf`.
1902 TyKind
::Ref(_
, mt
) if mt
.ty
.kind
.is_implicit_self() => match mt
.mutbl
{
1903 hir
::Mutability
::Not
=> hir
::ImplicitSelfKind
::ImmRef
,
1904 hir
::Mutability
::Mut
=> hir
::ImplicitSelfKind
::MutRef
,
1906 _
=> hir
::ImplicitSelfKind
::None
,
1912 // Transforms `-> T` for `async fn` into `-> OpaqueTy { .. }`
1913 // combined with the following definition of `OpaqueTy`:
1915 // type OpaqueTy<generics_from_parent_fn> = impl Future<Output = T>;
1917 // `output`: unlowered output type (`T` in `-> T`)
1918 // `fn_node_id`: `NodeId` of the parent function (used to create child impl trait definition)
1919 // `opaque_ty_node_id`: `NodeId` of the opaque `impl Trait` type that should be created
1920 #[instrument(level = "debug", skip(self))]
1921 fn lower_coroutine_fn_ret_ty(
1924 fn_def_id
: LocalDefId
,
1925 coro
: CoroutineKind
,
1926 fn_kind
: FnDeclKind
,
1928 ) -> hir
::FnRetTy
<'hir
> {
1929 let span
= self.lower_span(fn_span
);
1931 let (opaque_ty_node_id
, allowed_features
) = match coro
{
1932 CoroutineKind
::Async { return_impl_trait_id, .. }
=> (return_impl_trait_id
, None
),
1933 CoroutineKind
::Gen { return_impl_trait_id, .. }
=> (return_impl_trait_id
, None
),
1934 CoroutineKind
::AsyncGen { return_impl_trait_id, .. }
=> {
1935 (return_impl_trait_id
, Some(self.allow_async_iterator
.clone()))
1939 let opaque_ty_span
=
1940 self.mark_span_with_reason(DesugaringKind
::Async
, span
, allowed_features
);
1942 let captured_lifetimes
: Vec
<_
> = self
1944 .take_extra_lifetime_params(opaque_ty_node_id
)
1946 .map(|(ident
, id
, _
)| Lifetime { id, ident }
)
1949 let opaque_ty_ref
= self.lower_opaque_inner(
1951 hir
::OpaqueTyOrigin
::AsyncFn(fn_def_id
),
1952 matches
!(fn_kind
, FnDeclKind
::Trait
),
1957 let bound
= this
.lower_coroutine_fn_output_type_to_bound(
1961 ImplTraitContext
::ReturnPositionOpaqueTy
{
1962 origin
: hir
::OpaqueTyOrigin
::FnReturn(fn_def_id
),
1966 arena_vec
![this
; bound
]
1970 let opaque_ty
= self.ty(opaque_ty_span
, opaque_ty_ref
);
1971 hir
::FnRetTy
::Return(self.arena
.alloc(opaque_ty
))
1974 /// Transforms `-> T` into `Future<Output = T>`.
1975 fn lower_coroutine_fn_output_type_to_bound(
1978 coro
: CoroutineKind
,
1979 opaque_ty_span
: Span
,
1980 nested_impl_trait_context
: ImplTraitContext
,
1981 ) -> hir
::GenericBound
<'hir
> {
1982 // Compute the `T` in `Future<Output = T>` from the return type.
1983 let output_ty
= match output
{
1984 FnRetTy
::Ty(ty
) => {
1985 // Not `OpaqueTyOrigin::AsyncFn`: that's only used for the
1986 // `impl Future` opaque type that `async fn` implicitly
1988 self.lower_ty(ty
, &nested_impl_trait_context
)
1990 FnRetTy
::Default(ret_ty_span
) => self.arena
.alloc(self.ty_tup(*ret_ty_span
, &[])),
1993 // "<$assoc_ty_name = T>"
1994 let (assoc_ty_name
, trait_lang_item
) = match coro
{
1995 CoroutineKind
::Async { .. }
=> (sym
::Output
, hir
::LangItem
::Future
),
1996 CoroutineKind
::Gen { .. }
=> (sym
::Item
, hir
::LangItem
::Iterator
),
1997 CoroutineKind
::AsyncGen { .. }
=> (sym
::Item
, hir
::LangItem
::AsyncIterator
),
2000 let bound_args
= self.arena
.alloc(hir
::GenericArgs
{
2002 bindings
: arena_vec
![self; self.assoc_ty_binding(assoc_ty_name
, opaque_ty_span
, output_ty
)],
2003 parenthesized
: hir
::GenericArgsParentheses
::No
,
2007 hir
::GenericBound
::Trait(
2009 bound_generic_params
: &[],
2010 trait_ref
: hir
::TraitRef
{
2011 path
: self.make_lang_item_path(
2016 hir_ref_id
: self.next_id(),
2018 span
: opaque_ty_span
,
2020 hir
::TraitBoundModifier
::None
,
2024 #[instrument(level = "trace", skip(self))]
2025 fn lower_param_bound(
2028 itctx
: &ImplTraitContext
,
2029 ) -> hir
::GenericBound
<'hir
> {
2031 GenericBound
::Trait(p
, modifier
) => hir
::GenericBound
::Trait(
2032 self.lower_poly_trait_ref(p
, itctx
, modifier
.to_constness()),
2033 self.lower_trait_bound_modifier(*modifier
),
2035 GenericBound
::Outlives(lifetime
) => {
2036 hir
::GenericBound
::Outlives(self.lower_lifetime(lifetime
))
2041 fn lower_lifetime(&mut self, l
: &Lifetime
) -> &'hir hir
::Lifetime
{
2042 let ident
= self.lower_ident(l
.ident
);
2043 self.new_named_lifetime(l
.id
, l
.id
, ident
)
2046 #[instrument(level = "debug", skip(self))]
2047 fn new_named_lifetime_with_res(
2052 ) -> &'hir hir
::Lifetime
{
2053 let res
= match res
{
2054 LifetimeRes
::Param { param, .. }
=> {
2055 let param
= self.get_remapped_def_id(param
);
2056 hir
::LifetimeName
::Param(param
)
2058 LifetimeRes
::Fresh { param, .. }
=> {
2059 let param
= self.local_def_id(param
);
2060 hir
::LifetimeName
::Param(param
)
2062 LifetimeRes
::Infer
=> hir
::LifetimeName
::Infer
,
2063 LifetimeRes
::Static
=> hir
::LifetimeName
::Static
,
2064 LifetimeRes
::Error
=> hir
::LifetimeName
::Error
,
2066 "Unexpected lifetime resolution {:?} for {:?} at {:?}",
2067 res
, ident
, ident
.span
2072 self.arena
.alloc(hir
::Lifetime
{
2073 hir_id
: self.lower_node_id(id
),
2074 ident
: self.lower_ident(ident
),
2079 #[instrument(level = "debug", skip(self))]
2080 fn new_named_lifetime(
2085 ) -> &'hir hir
::Lifetime
{
2086 let res
= self.resolver
.get_lifetime_res(id
).unwrap_or(LifetimeRes
::Error
);
2087 self.new_named_lifetime_with_res(new_id
, ident
, res
)
2090 fn lower_generic_params_mut
<'s
>(
2092 params
: &'s
[GenericParam
],
2093 source
: hir
::GenericParamSource
,
2094 ) -> impl Iterator
<Item
= hir
::GenericParam
<'hir
>> + Captures
<'a
> + Captures
<'s
> {
2095 params
.iter().map(move |param
| self.lower_generic_param(param
, source
))
2098 fn lower_generic_params(
2100 params
: &[GenericParam
],
2101 source
: hir
::GenericParamSource
,
2102 ) -> &'hir
[hir
::GenericParam
<'hir
>] {
2103 self.arena
.alloc_from_iter(self.lower_generic_params_mut(params
, source
))
2106 #[instrument(level = "trace", skip(self))]
2107 fn lower_generic_param(
2109 param
: &GenericParam
,
2110 source
: hir
::GenericParamSource
,
2111 ) -> hir
::GenericParam
<'hir
> {
2112 let (name
, kind
) = self.lower_generic_param_kind(param
);
2114 let hir_id
= self.lower_node_id(param
.id
);
2115 self.lower_attrs(hir_id
, ¶m
.attrs
);
2118 def_id
: self.local_def_id(param
.id
),
2120 span
: self.lower_span(param
.span()),
2121 pure_wrt_drop
: attr
::contains_name(¶m
.attrs
, sym
::may_dangle
),
2123 colon_span
: param
.colon_span
.map(|s
| self.lower_span(s
)),
2128 fn lower_generic_param_kind(
2130 param
: &GenericParam
,
2131 ) -> (hir
::ParamName
, hir
::GenericParamKind
<'hir
>) {
2133 GenericParamKind
::Lifetime
=> {
2134 // AST resolution emitted an error on those parameters, so we lower them using
2135 // `ParamName::Error`.
2137 if let Some(LifetimeRes
::Error
) = self.resolver
.get_lifetime_res(param
.id
) {
2140 let ident
= self.lower_ident(param
.ident
);
2141 ParamName
::Plain(ident
)
2144 hir
::GenericParamKind
::Lifetime { kind: hir::LifetimeParamKind::Explicit }
;
2148 GenericParamKind
::Type { default, .. }
=> {
2149 let kind
= hir
::GenericParamKind
::Type
{
2150 default: default.as_ref().map(|x
| {
2153 &ImplTraitContext
::Disallowed(ImplTraitPosition
::GenericDefault
),
2159 (hir
::ParamName
::Plain(self.lower_ident(param
.ident
)), kind
)
2161 GenericParamKind
::Const { ty, kw_span: _, default }
=> {
2163 .lower_ty(ty
, &ImplTraitContext
::Disallowed(ImplTraitPosition
::GenericDefault
));
2164 let default = default.as_ref().map(|def
| self.lower_anon_const(def
));
2166 hir
::ParamName
::Plain(self.lower_ident(param
.ident
)),
2167 hir
::GenericParamKind
::Const { ty, default, is_host_effect: false }
,
2175 constness
: ast
::Const
,
2177 itctx
: &ImplTraitContext
,
2178 ) -> hir
::TraitRef
<'hir
> {
2179 let path
= match self.lower_qpath(
2183 ParamMode
::Explicit
,
2187 hir
::QPath
::Resolved(None
, path
) => path
,
2188 qpath
=> panic
!("lower_trait_ref: unexpected QPath `{qpath:?}`"),
2190 hir
::TraitRef { path, hir_ref_id: self.lower_node_id(p.ref_id) }
2193 #[instrument(level = "debug", skip(self))]
2194 fn lower_poly_trait_ref(
2197 itctx
: &ImplTraitContext
,
2198 constness
: ast
::Const
,
2199 ) -> hir
::PolyTraitRef
<'hir
> {
2200 let bound_generic_params
=
2201 self.lower_lifetime_binder(p
.trait_ref
.ref_id
, &p
.bound_generic_params
);
2202 let trait_ref
= self.lower_trait_ref(constness
, &p
.trait_ref
, itctx
);
2203 hir
::PolyTraitRef { bound_generic_params, trait_ref, span: self.lower_span(p.span) }
2206 fn lower_mt(&mut self, mt
: &MutTy
, itctx
: &ImplTraitContext
) -> hir
::MutTy
<'hir
> {
2207 hir
::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl }
2210 #[instrument(level = "debug", skip(self), ret)]
2211 fn lower_param_bounds(
2213 bounds
: &[GenericBound
],
2214 itctx
: &ImplTraitContext
,
2215 ) -> hir
::GenericBounds
<'hir
> {
2216 self.arena
.alloc_from_iter(self.lower_param_bounds_mut(bounds
, itctx
))
2219 fn lower_param_bounds_mut
<'s
>(
2221 bounds
: &'s
[GenericBound
],
2222 itctx
: &'s ImplTraitContext
,
2223 ) -> impl Iterator
<Item
= hir
::GenericBound
<'hir
>> + Captures
<'s
> + Captures
<'a
> {
2224 bounds
.iter().map(move |bound
| self.lower_param_bound(bound
, itctx
))
2227 #[instrument(level = "debug", skip(self), ret)]
2228 fn lower_universal_param_and_bounds(
2233 bounds
: &[GenericBound
],
2234 ) -> (hir
::GenericParam
<'hir
>, Option
<hir
::WherePredicate
<'hir
>>, hir
::TyKind
<'hir
>) {
2235 // Add a definition for the in-band `Param`.
2236 let def_id
= self.local_def_id(node_id
);
2237 let span
= self.lower_span(span
);
2239 // Set the name to `impl Bound1 + Bound2`.
2240 let param
= hir
::GenericParam
{
2241 hir_id
: self.lower_node_id(node_id
),
2243 name
: ParamName
::Plain(self.lower_ident(ident
)),
2244 pure_wrt_drop
: false,
2246 kind
: hir
::GenericParamKind
::Type { default: None, synthetic: true }
,
2248 source
: hir
::GenericParamSource
::Generics
,
2251 let preds
= self.lower_generic_bound_predicate(
2254 &GenericParamKind
::Type { default: None }
,
2256 /* colon_span */ None
,
2258 &ImplTraitContext
::Universal
,
2259 hir
::PredicateOrigin
::ImplTrait
,
2262 let hir_id
= self.next_id();
2263 let res
= Res
::Def(DefKind
::TyParam
, def_id
.to_def_id());
2264 let ty
= hir
::TyKind
::Path(hir
::QPath
::Resolved(
2266 self.arena
.alloc(hir
::Path
{
2270 arena_vec
![self; hir
::PathSegment
::new(self.lower_ident(ident
), hir_id
, res
)],
2277 /// Lowers a block directly to an expression, presuming that it
2278 /// has no attributes and is not targeted by a `break`.
2279 fn lower_block_expr(&mut self, b
: &Block
) -> hir
::Expr
<'hir
> {
2280 let block
= self.lower_block(b
, false);
2281 self.expr_block(block
)
2284 fn lower_array_length(&mut self, c
: &AnonConst
) -> hir
::ArrayLen
{
2285 match c
.value
.kind
{
2286 ExprKind
::Underscore
=> {
2287 if self.tcx
.features().generic_arg_infer
{
2288 hir
::ArrayLen
::Infer(self.lower_node_id(c
.id
), self.lower_span(c
.value
.span
))
2291 &self.tcx
.sess
.parse_sess
,
2292 sym
::generic_arg_infer
,
2294 "using `_` for array lengths is unstable",
2296 .stash(c
.value
.span
, StashKey
::UnderscoreForArrayLengths
);
2297 hir
::ArrayLen
::Body(self.lower_anon_const(c
))
2300 _
=> hir
::ArrayLen
::Body(self.lower_anon_const(c
)),
2304 fn lower_anon_const(&mut self, c
: &AnonConst
) -> hir
::AnonConst
{
2305 self.with_new_scopes(c
.value
.span
, |this
| hir
::AnonConst
{
2306 def_id
: this
.local_def_id(c
.id
),
2307 hir_id
: this
.lower_node_id(c
.id
),
2308 body
: this
.lower_const_body(c
.value
.span
, Some(&c
.value
)),
2312 fn lower_unsafe_source(&mut self, u
: UnsafeSource
) -> hir
::UnsafeSource
{
2314 CompilerGenerated
=> hir
::UnsafeSource
::CompilerGenerated
,
2315 UserProvided
=> hir
::UnsafeSource
::UserProvided
,
2319 fn lower_trait_bound_modifier(&mut self, f
: TraitBoundModifier
) -> hir
::TraitBoundModifier
{
2321 TraitBoundModifier
::None
=> hir
::TraitBoundModifier
::None
,
2322 TraitBoundModifier
::MaybeConst(_
) => hir
::TraitBoundModifier
::MaybeConst
,
2324 TraitBoundModifier
::Negative
=> {
2325 if self.tcx
.features().negative_bounds
{
2326 hir
::TraitBoundModifier
::Negative
2328 hir
::TraitBoundModifier
::None
2332 // `MaybeConstMaybe` will cause an error during AST validation, but we need to pick a
2333 // placeholder for compilation to proceed.
2334 TraitBoundModifier
::MaybeConstMaybe
| TraitBoundModifier
::Maybe
=> {
2335 hir
::TraitBoundModifier
::Maybe
2337 TraitBoundModifier
::MaybeConstNegative
=> hir
::TraitBoundModifier
::MaybeConst
,
2341 // Helper methods for building HIR.
2343 fn stmt(&mut self, span
: Span
, kind
: hir
::StmtKind
<'hir
>) -> hir
::Stmt
<'hir
> {
2344 hir
::Stmt { span: self.lower_span(span), kind, hir_id: self.next_id() }
2347 fn stmt_expr(&mut self, span
: Span
, expr
: hir
::Expr
<'hir
>) -> hir
::Stmt
<'hir
> {
2348 self.stmt(span
, hir
::StmtKind
::Expr(self.arena
.alloc(expr
)))
2353 attrs
: Option
<&'hir
[Attribute
]>,
2355 init
: Option
<&'hir hir
::Expr
<'hir
>>,
2356 pat
: &'hir hir
::Pat
<'hir
>,
2357 source
: hir
::LocalSource
,
2358 ) -> hir
::Stmt
<'hir
> {
2359 let hir_id
= self.next_id();
2360 if let Some(a
) = attrs
{
2361 debug_assert
!(!a
.is_empty());
2362 self.attrs
.insert(hir_id
.local_id
, a
);
2364 let local
= hir
::Local
{
2370 span
: self.lower_span(span
),
2373 self.stmt(span
, hir
::StmtKind
::Local(self.arena
.alloc(local
)))
2376 fn block_expr(&mut self, expr
: &'hir hir
::Expr
<'hir
>) -> &'hir hir
::Block
<'hir
> {
2377 self.block_all(expr
.span
, &[], Some(expr
))
2383 stmts
: &'hir
[hir
::Stmt
<'hir
>],
2384 expr
: Option
<&'hir hir
::Expr
<'hir
>>,
2385 ) -> &'hir hir
::Block
<'hir
> {
2386 let blk
= hir
::Block
{
2389 hir_id
: self.next_id(),
2390 rules
: hir
::BlockCheckMode
::DefaultBlock
,
2391 span
: self.lower_span(span
),
2392 targeted_by_break
: false,
2394 self.arena
.alloc(blk
)
2397 fn pat_cf_continue(&mut self, span
: Span
, pat
: &'hir hir
::Pat
<'hir
>) -> &'hir hir
::Pat
<'hir
> {
2398 let field
= self.single_pat_field(span
, pat
);
2399 self.pat_lang_item_variant(span
, hir
::LangItem
::ControlFlowContinue
, field
)
2402 fn pat_cf_break(&mut self, span
: Span
, pat
: &'hir hir
::Pat
<'hir
>) -> &'hir hir
::Pat
<'hir
> {
2403 let field
= self.single_pat_field(span
, pat
);
2404 self.pat_lang_item_variant(span
, hir
::LangItem
::ControlFlowBreak
, field
)
2407 fn pat_some(&mut self, span
: Span
, pat
: &'hir hir
::Pat
<'hir
>) -> &'hir hir
::Pat
<'hir
> {
2408 let field
= self.single_pat_field(span
, pat
);
2409 self.pat_lang_item_variant(span
, hir
::LangItem
::OptionSome
, field
)
2412 fn pat_none(&mut self, span
: Span
) -> &'hir hir
::Pat
<'hir
> {
2413 self.pat_lang_item_variant(span
, hir
::LangItem
::OptionNone
, &[])
2416 fn single_pat_field(
2419 pat
: &'hir hir
::Pat
<'hir
>,
2420 ) -> &'hir
[hir
::PatField
<'hir
>] {
2421 let field
= hir
::PatField
{
2422 hir_id
: self.next_id(),
2423 ident
: Ident
::new(sym
::integer(0), self.lower_span(span
)),
2424 is_shorthand
: false,
2426 span
: self.lower_span(span
),
2428 arena_vec
![self; field
]
2431 fn pat_lang_item_variant(
2434 lang_item
: hir
::LangItem
,
2435 fields
: &'hir
[hir
::PatField
<'hir
>],
2436 ) -> &'hir hir
::Pat
<'hir
> {
2437 let qpath
= hir
::QPath
::LangItem(lang_item
, self.lower_span(span
));
2438 self.pat(span
, hir
::PatKind
::Struct(qpath
, fields
, false))
2441 fn pat_ident(&mut self, span
: Span
, ident
: Ident
) -> (&'hir hir
::Pat
<'hir
>, hir
::HirId
) {
2442 self.pat_ident_binding_mode(span
, ident
, hir
::BindingAnnotation
::NONE
)
2445 fn pat_ident_mut(&mut self, span
: Span
, ident
: Ident
) -> (hir
::Pat
<'hir
>, hir
::HirId
) {
2446 self.pat_ident_binding_mode_mut(span
, ident
, hir
::BindingAnnotation
::NONE
)
2449 fn pat_ident_binding_mode(
2453 bm
: hir
::BindingAnnotation
,
2454 ) -> (&'hir hir
::Pat
<'hir
>, hir
::HirId
) {
2455 let (pat
, hir_id
) = self.pat_ident_binding_mode_mut(span
, ident
, bm
);
2456 (self.arena
.alloc(pat
), hir_id
)
2459 fn pat_ident_binding_mode_mut(
2463 bm
: hir
::BindingAnnotation
,
2464 ) -> (hir
::Pat
<'hir
>, hir
::HirId
) {
2465 let hir_id
= self.next_id();
2470 kind
: hir
::PatKind
::Binding(bm
, hir_id
, self.lower_ident(ident
), None
),
2471 span
: self.lower_span(span
),
2472 default_binding_modes
: true,
2478 fn pat(&mut self, span
: Span
, kind
: hir
::PatKind
<'hir
>) -> &'hir hir
::Pat
<'hir
> {
2479 self.arena
.alloc(hir
::Pat
{
2480 hir_id
: self.next_id(),
2482 span
: self.lower_span(span
),
2483 default_binding_modes
: true,
2487 fn pat_without_dbm(&mut self, span
: Span
, kind
: hir
::PatKind
<'hir
>) -> hir
::Pat
<'hir
> {
2489 hir_id
: self.next_id(),
2491 span
: self.lower_span(span
),
2492 default_binding_modes
: false,
2498 mut hir_id
: hir
::HirId
,
2500 qpath
: hir
::QPath
<'hir
>,
2501 ) -> hir
::Ty
<'hir
> {
2502 let kind
= match qpath
{
2503 hir
::QPath
::Resolved(None
, path
) => {
2504 // Turn trait object paths into `TyKind::TraitObject` instead.
2506 Res
::Def(DefKind
::Trait
| DefKind
::TraitAlias
, _
) => {
2507 let principal
= hir
::PolyTraitRef
{
2508 bound_generic_params
: &[],
2509 trait_ref
: hir
::TraitRef { path, hir_ref_id: hir_id }
,
2510 span
: self.lower_span(span
),
2513 // The original ID is taken by the `PolyTraitRef`,
2514 // so the `Ty` itself needs a different one.
2515 hir_id
= self.next_id();
2516 hir
::TyKind
::TraitObject(
2517 arena_vec
![self; principal
],
2518 self.elided_dyn_bound(span
),
2519 TraitObjectSyntax
::None
,
2522 _
=> hir
::TyKind
::Path(hir
::QPath
::Resolved(None
, path
)),
2525 _
=> hir
::TyKind
::Path(qpath
),
2528 hir
::Ty { hir_id, kind, span: self.lower_span(span) }
2531 /// Invoked to create the lifetime argument(s) for an elided trait object
2532 /// bound, like the bound in `Box<dyn Debug>`. This method is not invoked
2533 /// when the bound is written, even if it is written with `'_` like in
2534 /// `Box<dyn Debug + '_>`. In those cases, `lower_lifetime` is invoked.
2535 fn elided_dyn_bound(&mut self, span
: Span
) -> &'hir hir
::Lifetime
{
2536 let r
= hir
::Lifetime
{
2537 hir_id
: self.next_id(),
2538 ident
: Ident
::new(kw
::Empty
, self.lower_span(span
)),
2539 res
: hir
::LifetimeName
::ImplicitObjectLifetimeDefault
,
2541 debug
!("elided_dyn_bound: r={:?}", r
);
2546 /// Helper struct for delayed construction of GenericArgs.
2547 struct GenericArgsCtor
<'hir
> {
2548 args
: SmallVec
<[hir
::GenericArg
<'hir
>; 4]>,
2549 bindings
: &'hir
[hir
::TypeBinding
<'hir
>],
2550 parenthesized
: hir
::GenericArgsParentheses
,
2554 impl<'hir
> GenericArgsCtor
<'hir
> {
2555 fn push_constness(&mut self, lcx
: &mut LoweringContext
<'_
, 'hir
>, constness
: ast
::Const
) {
2556 if !lcx
.tcx
.features().effects
{
2560 // if bound is non-const, don't add host effect param
2561 let ast
::Const
::Yes(span
) = constness
else { return }
;
2563 let span
= lcx
.lower_span(span
);
2565 let id
= lcx
.next_node_id();
2566 let hir_id
= lcx
.next_id();
2568 let Some(host_param_id
) = lcx
.host_param_id
else {
2569 lcx
.tcx
.sess
.span_delayed_bug(
2571 "no host param id for call in const yet no errors reported",
2576 let body
= lcx
.lower_body(|lcx
| {
2578 let hir_id
= lcx
.next_id();
2579 let res
= Res
::Def(DefKind
::ConstParam
, host_param_id
.to_def_id());
2580 let expr_kind
= hir
::ExprKind
::Path(hir
::QPath
::Resolved(
2582 lcx
.arena
.alloc(hir
::Path
{
2585 segments
: arena_vec
![lcx
; hir
::PathSegment
::new(Ident
{
2591 lcx
.expr(span
, expr_kind
)
2595 let def_id
= lcx
.create_def(
2596 lcx
.current_hir_id_owner
.def_id
,
2603 lcx
.children
.push((def_id
, hir
::MaybeOwner
::NonOwner(hir_id
)));
2604 self.args
.push(hir
::GenericArg
::Const(hir
::ConstArg
{
2605 value
: hir
::AnonConst { def_id, hir_id, body }
,
2607 is_desugared_from_effects
: true,
2611 fn is_empty(&self) -> bool
{
2612 self.args
.is_empty()
2613 && self.bindings
.is_empty()
2614 && self.parenthesized
== hir
::GenericArgsParentheses
::No
2617 fn into_generic_args(self, this
: &LoweringContext
<'_
, 'hir
>) -> &'hir hir
::GenericArgs
<'hir
> {
2618 let ga
= hir
::GenericArgs
{
2619 args
: this
.arena
.alloc_from_iter(self.args
),
2620 bindings
: self.bindings
,
2621 parenthesized
: self.parenthesized
,
2622 span_ext
: this
.lower_span(self.span
),
2624 this
.arena
.alloc(ga
)