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)]
35 #![feature(never_type)]
36 #![recursion_limit = "256"]
37 #![allow(rustc::potential_query_instability)]
38 #![deny(rustc::untranslatable_diagnostic)]
39 #![deny(rustc::diagnostic_outside_of_impl)]
44 use crate::errors
::{AssocTyParentheses, AssocTyParenthesesSub, MisplacedImplTrait, TraitFnAsync}
;
46 use rustc_arena
::declare_arena
;
47 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
::fx
::FxHashMap
;
54 use rustc_data_structures
::sorted_map
::SortedMap
;
55 use rustc_data_structures
::stable_hasher
::{HashStable, StableHasher}
;
56 use rustc_data_structures
::sync
::Lrc
;
57 use rustc_errors
::{DiagnosticArgFromDisplay, Handler, StashKey}
;
59 use rustc_hir
::def
::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}
;
60 use rustc_hir
::def_id
::{LocalDefId, CRATE_DEF_ID}
;
61 use rustc_hir
::definitions
::DefPathData
;
62 use rustc_hir
::{ConstArg, GenericArg, ItemLocalId, ParamName, TraitCandidate}
;
63 use rustc_index
::vec
::{Idx, IndexVec}
;
64 use rustc_middle
::ty
::{ResolverAstLowering, TyCtxt}
;
65 use rustc_middle
::{bug, span_bug}
;
66 use rustc_session
::parse
::feature_err
;
67 use rustc_span
::hygiene
::MacroKind
;
68 use rustc_span
::source_map
::DesugaringKind
;
69 use rustc_span
::symbol
::{kw, sym, Ident, Symbol}
;
70 use rustc_span
::{Span, DUMMY_SP}
;
72 use smallvec
::SmallVec
;
73 use std
::collections
::hash_map
::Entry
;
75 macro_rules
! arena_vec
{
76 ($this
:expr
; $
($x
:expr
),*) => (
77 $this
.arena
.alloc_from_iter([$
($x
),*])
87 mod lifetime_collector
;
91 struct LoweringContext
<'a
, 'hir
> {
93 resolver
: &'a
mut ResolverAstLowering
,
95 /// Used to allocate HIR nodes.
96 arena
: &'hir hir
::Arena
<'hir
>,
98 /// Used to allocate temporary AST nodes for use during lowering.
99 /// This allows us to create "fake" AST -- these nodes can sometimes
100 /// be allocated on the stack, but other times we need them to live longer
101 /// than the current stack frame, so they can be collected into vectors
102 /// and things like that.
103 ast_arena
: &'a Arena
<'
static>,
105 /// Bodies inside the owner being lowered.
106 bodies
: Vec
<(hir
::ItemLocalId
, &'hir hir
::Body
<'hir
>)>,
107 /// Attributes inside the owner being lowered.
108 attrs
: SortedMap
<hir
::ItemLocalId
, &'hir
[Attribute
]>,
109 /// Collect items that were created by lowering the current owner.
110 children
: FxHashMap
<LocalDefId
, hir
::MaybeOwner
<&'hir hir
::OwnerInfo
<'hir
>>>,
112 generator_kind
: Option
<hir
::GeneratorKind
>,
114 /// When inside an `async` context, this is the `HirId` of the
115 /// `task_context` local bound to the resume argument of the generator.
116 task_context
: Option
<hir
::HirId
>,
118 /// Used to get the current `fn`'s def span to point to when using `await`
119 /// outside of an `async fn`.
120 current_item
: Option
<Span
>,
122 catch_scope
: Option
<NodeId
>,
123 loop_scope
: Option
<NodeId
>,
124 is_in_loop_condition
: bool
,
125 is_in_trait_impl
: bool
,
126 is_in_dyn_type
: bool
,
128 current_hir_id_owner
: hir
::OwnerId
,
129 item_local_id_counter
: hir
::ItemLocalId
,
130 local_id_to_def_id
: SortedMap
<ItemLocalId
, LocalDefId
>,
131 trait_map
: FxHashMap
<ItemLocalId
, Box
<[TraitCandidate
]>>,
133 impl_trait_defs
: Vec
<hir
::GenericParam
<'hir
>>,
134 impl_trait_bounds
: Vec
<hir
::WherePredicate
<'hir
>>,
136 /// NodeIds that are lowered inside the current HIR owner.
137 node_id_to_local_id
: FxHashMap
<NodeId
, hir
::ItemLocalId
>,
139 allow_try_trait
: Option
<Lrc
<[Symbol
]>>,
140 allow_gen_future
: Option
<Lrc
<[Symbol
]>>,
141 allow_into_future
: Option
<Lrc
<[Symbol
]>>,
143 /// Mapping from generics `def_id`s to TAIT generics `def_id`s.
144 /// For each captured lifetime (e.g., 'a), we create a new lifetime parameter that is a generic
145 /// defined on the TAIT, so we have type Foo<'a1> = ... and we establish a mapping in this
146 /// field from the original parameter 'a to the new parameter 'a1.
147 generics_def_id_map
: Vec
<FxHashMap
<LocalDefId
, LocalDefId
>>,
151 [] tys
: rustc_ast
::Ty
,
152 [] aba
: rustc_ast
::AngleBracketedArgs
,
153 [] ptr
: rustc_ast
::PolyTraitRef
,
154 // This _marker field is needed because `declare_arena` creates `Arena<'tcx>` and we need to
155 // use `'tcx`. If we don't have this we get a compile error.
156 [] _marker
: std
::marker
::PhantomData
<&'
tcx ()>,
159 trait ResolverAstLoweringExt
{
160 fn legacy_const_generic_args(&self, expr
: &Expr
) -> Option
<Vec
<usize>>;
161 fn get_partial_res(&self, id
: NodeId
) -> Option
<PartialRes
>;
162 fn get_import_res(&self, id
: NodeId
) -> PerNS
<Option
<Res
<NodeId
>>>;
163 // Clones the resolution (if any) on 'source' and applies it
164 // to 'target'. Used when desugaring a `UseTreeKind::Nested` to
165 // multiple `UseTreeKind::Simple`s
166 fn clone_res(&mut self, source
: NodeId
, target
: NodeId
);
167 fn get_label_res(&self, id
: NodeId
) -> Option
<NodeId
>;
168 fn get_lifetime_res(&self, id
: NodeId
) -> Option
<LifetimeRes
>;
169 fn take_extra_lifetime_params(&mut self, id
: NodeId
) -> Vec
<(Ident
, NodeId
, LifetimeRes
)>;
170 fn decl_macro_kind(&self, def_id
: LocalDefId
) -> MacroKind
;
173 impl ResolverAstLoweringExt
for ResolverAstLowering
{
174 fn legacy_const_generic_args(&self, expr
: &Expr
) -> Option
<Vec
<usize>> {
175 if let ExprKind
::Path(None
, path
) = &expr
.kind
{
176 // Don't perform legacy const generics rewriting if the path already
177 // has generic arguments.
178 if path
.segments
.last().unwrap().args
.is_some() {
182 if let Res
::Def(DefKind
::Fn
, def_id
) = self.partial_res_map
.get(&expr
.id
)?
.full_res()?
{
183 // We only support cross-crate argument rewriting. Uses
184 // within the same crate should be updated to use the new
185 // const generics style.
186 if def_id
.is_local() {
190 if let Some(v
) = self.legacy_const_generic_args
.get(&def_id
) {
199 fn clone_res(&mut self, source
: NodeId
, target
: NodeId
) {
200 if let Some(res
) = self.partial_res_map
.get(&source
) {
201 self.partial_res_map
.insert(target
, *res
);
205 /// Obtains resolution for a `NodeId` with a single resolution.
206 fn get_partial_res(&self, id
: NodeId
) -> Option
<PartialRes
> {
207 self.partial_res_map
.get(&id
).copied()
210 /// Obtains per-namespace resolutions for `use` statement with the given `NodeId`.
211 fn get_import_res(&self, id
: NodeId
) -> PerNS
<Option
<Res
<NodeId
>>> {
212 self.import_res_map
.get(&id
).copied().unwrap_or_default()
215 /// Obtains resolution for a label with the given `NodeId`.
216 fn get_label_res(&self, id
: NodeId
) -> Option
<NodeId
> {
217 self.label_res_map
.get(&id
).copied()
220 /// Obtains resolution for a lifetime with the given `NodeId`.
221 fn get_lifetime_res(&self, id
: NodeId
) -> Option
<LifetimeRes
> {
222 self.lifetimes_res_map
.get(&id
).copied()
225 /// Obtain the list of lifetimes parameters to add to an item.
227 /// Extra lifetime parameters should only be added in places that can appear
228 /// as a `binder` in `LifetimeRes`.
230 /// The extra lifetimes that appear from the parenthesized `Fn`-trait desugaring
231 /// should appear at the enclosing `PolyTraitRef`.
232 fn take_extra_lifetime_params(&mut self, id
: NodeId
) -> Vec
<(Ident
, NodeId
, LifetimeRes
)> {
233 self.extra_lifetime_params_map
.remove(&id
).unwrap_or_default()
236 fn decl_macro_kind(&self, def_id
: LocalDefId
) -> MacroKind
{
237 self.builtin_macro_kinds
.get(&def_id
).copied().unwrap_or(MacroKind
::Bang
)
241 /// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,
242 /// and if so, what meaning it has.
243 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
244 enum ImplTraitContext
{
245 /// Treat `impl Trait` as shorthand for a new universal generic parameter.
246 /// Example: `fn foo(x: impl Debug)`, where `impl Debug` is conceptually
247 /// equivalent to a fresh universal parameter like `fn foo<T: Debug>(x: T)`.
249 /// Newly generated parameters should be inserted into the given `Vec`.
252 /// Treat `impl Trait` as shorthand for a new opaque type.
253 /// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
254 /// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`.
256 ReturnPositionOpaqueTy
{
257 /// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn,
258 origin
: hir
::OpaqueTyOrigin
,
261 /// Impl trait in type aliases.
263 /// `impl Trait` is not accepted in this position.
264 Disallowed(ImplTraitPosition
),
267 /// Position in which `impl Trait` is disallowed.
268 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
269 enum ImplTraitPosition
{
291 impl std
::fmt
::Display
for ImplTraitPosition
{
292 fn fmt(&self, f
: &mut std
::fmt
::Formatter
<'_
>) -> std
::fmt
::Result
{
293 let name
= match self {
294 ImplTraitPosition
::Path
=> "path",
295 ImplTraitPosition
::Variable
=> "variable binding",
296 ImplTraitPosition
::Type
=> "type",
297 ImplTraitPosition
::Trait
=> "trait",
298 ImplTraitPosition
::AsyncBlock
=> "async block",
299 ImplTraitPosition
::Bound
=> "bound",
300 ImplTraitPosition
::Generic
=> "generic",
301 ImplTraitPosition
::ExternFnParam
=> "`extern fn` param",
302 ImplTraitPosition
::ClosureParam
=> "closure param",
303 ImplTraitPosition
::PointerParam
=> "`fn` pointer param",
304 ImplTraitPosition
::FnTraitParam
=> "`Fn` trait param",
305 ImplTraitPosition
::TraitParam
=> "trait method param",
306 ImplTraitPosition
::ImplParam
=> "`impl` method param",
307 ImplTraitPosition
::ExternFnReturn
=> "`extern fn` return",
308 ImplTraitPosition
::ClosureReturn
=> "closure return",
309 ImplTraitPosition
::PointerReturn
=> "`fn` pointer return",
310 ImplTraitPosition
::FnTraitReturn
=> "`Fn` trait return",
311 ImplTraitPosition
::TraitReturn
=> "trait method return",
312 ImplTraitPosition
::ImplReturn
=> "`impl` method return",
315 write
!(f
, "{}", name
)
319 #[derive(Debug, PartialEq, Eq)]
331 fn impl_trait_allowed(&self, tcx
: TyCtxt
<'_
>) -> bool
{
333 FnDeclKind
::Fn
| FnDeclKind
::Inherent
=> true,
334 FnDeclKind
::Impl
if tcx
.features().return_position_impl_trait_in_trait
=> true,
335 FnDeclKind
::Trait
if tcx
.features().return_position_impl_trait_in_trait
=> true,
340 fn async_fn_allowed(&self, tcx
: TyCtxt
<'_
>) -> bool
{
342 FnDeclKind
::Fn
| FnDeclKind
::Inherent
=> true,
343 FnDeclKind
::Impl
if tcx
.features().async_fn_in_trait
=> true,
344 FnDeclKind
::Trait
if tcx
.features().async_fn_in_trait
=> true,
350 #[derive(Copy, Clone)]
353 Crate(&'a ast
::Crate
),
355 AssocItem(&'a ast
::AssocItem
, visit
::AssocCtxt
),
356 ForeignItem(&'a ast
::ForeignItem
),
360 node_id_to_def_id
: &FxHashMap
<NodeId
, LocalDefId
>,
362 ) -> IndexVec
<LocalDefId
, AstOwner
<'a
>> {
363 let mut indexer
= Indexer { node_id_to_def_id, index: IndexVec::new() }
;
364 indexer
.index
.ensure_contains_elem(CRATE_DEF_ID
, || AstOwner
::NonOwner
);
365 indexer
.index
[CRATE_DEF_ID
] = AstOwner
::Crate(krate
);
366 visit
::walk_crate(&mut indexer
, krate
);
367 return indexer
.index
;
369 struct Indexer
<'s
, 'a
> {
370 node_id_to_def_id
: &'s FxHashMap
<NodeId
, LocalDefId
>,
371 index
: IndexVec
<LocalDefId
, AstOwner
<'a
>>,
374 impl<'a
> visit
::Visitor
<'a
> for Indexer
<'_
, 'a
> {
375 fn visit_attribute(&mut self, _
: &'a Attribute
) {
376 // We do not want to lower expressions that appear in attributes,
377 // as they are not accessible to the rest of the HIR.
380 fn visit_item(&mut self, item
: &'a ast
::Item
) {
381 let def_id
= self.node_id_to_def_id
[&item
.id
];
382 self.index
.ensure_contains_elem(def_id
, || AstOwner
::NonOwner
);
383 self.index
[def_id
] = AstOwner
::Item(item
);
384 visit
::walk_item(self, item
)
387 fn visit_assoc_item(&mut self, item
: &'a ast
::AssocItem
, ctxt
: visit
::AssocCtxt
) {
388 let def_id
= self.node_id_to_def_id
[&item
.id
];
389 self.index
.ensure_contains_elem(def_id
, || AstOwner
::NonOwner
);
390 self.index
[def_id
] = AstOwner
::AssocItem(item
, ctxt
);
391 visit
::walk_assoc_item(self, item
, ctxt
);
394 fn visit_foreign_item(&mut self, item
: &'a ast
::ForeignItem
) {
395 let def_id
= self.node_id_to_def_id
[&item
.id
];
396 self.index
.ensure_contains_elem(def_id
, || AstOwner
::NonOwner
);
397 self.index
[def_id
] = AstOwner
::ForeignItem(item
);
398 visit
::walk_foreign_item(self, item
);
403 /// Compute the hash for the HIR of the full crate.
404 /// This hash will then be part of the crate_hash which is stored in the metadata.
407 owners
: &IndexVec
<LocalDefId
, hir
::MaybeOwner
<&hir
::OwnerInfo
<'_
>>>,
409 let mut hir_body_nodes
: Vec
<_
> = owners
411 .filter_map(|(def_id
, info
)| {
412 let info
= info
.as_owner()?
;
413 let def_path_hash
= tcx
.hir().def_path_hash(def_id
);
414 Some((def_path_hash
, info
))
417 hir_body_nodes
.sort_unstable_by_key(|bn
| bn
.0);
419 tcx
.with_stable_hashing_context(|mut hcx
| {
420 let mut stable_hasher
= StableHasher
::new();
421 hir_body_nodes
.hash_stable(&mut hcx
, &mut stable_hasher
);
422 stable_hasher
.finish()
426 pub fn lower_to_hir
<'hir
>(tcx
: TyCtxt
<'hir
>, (): ()) -> hir
::Crate
<'hir
> {
428 let krate
= tcx
.untracked_crate
.steal();
429 let mut resolver
= tcx
.resolver_for_lowering(()).steal();
431 let ast_index
= index_crate(&resolver
.node_id_to_def_id
, &krate
);
432 let mut owners
= IndexVec
::from_fn_n(
433 |_
| hir
::MaybeOwner
::Phantom
,
434 tcx
.definitions_untracked().def_index_count(),
437 let ast_arena
= Arena
::default();
439 for def_id
in ast_index
.indices() {
442 resolver
: &mut resolver
,
443 ast_arena
: &ast_arena
,
444 ast_index
: &ast_index
,
450 // Drop AST to free memory
451 std
::mem
::drop(ast_index
);
452 sess
.time("drop_ast", || std
::mem
::drop(krate
));
454 // Discard hygiene data, which isn't required after lowering to HIR.
455 if !sess
.opts
.unstable_opts
.keep_hygiene_data
{
456 rustc_span
::hygiene
::clear_syntax_context_map();
459 let hir_hash
= compute_hir_hash(tcx
, &owners
);
460 hir
::Crate { owners, hir_hash }
463 #[derive(Copy, Clone, PartialEq, Debug)]
465 /// Any path in a type context.
467 /// Path in a type definition, where the anonymous lifetime `'_` is not allowed.
469 /// The `module::Type` in `module::Type::method` in an expression.
473 enum ParenthesizedGenericArgs
{
478 impl<'a
, 'hir
> LoweringContext
<'a
, 'hir
> {
482 node_id
: ast
::NodeId
,
485 debug_assert_ne
!(node_id
, ast
::DUMMY_NODE_ID
);
487 self.opt_local_def_id(node_id
).is_none(),
488 "adding a def'n for node-id {:?} and data {:?} but a previous def'n exists: {:?}",
491 self.tcx
.hir().def_key(self.local_def_id(node_id
)),
494 let def_id
= self.tcx
.create_def(parent
, data
);
496 debug
!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id
, node_id
);
497 self.resolver
.node_id_to_def_id
.insert(node_id
, def_id
);
502 fn next_node_id(&mut self) -> NodeId
{
503 let start
= self.resolver
.next_node_id
;
504 let next
= start
.as_u32().checked_add(1).expect("input too large; ran out of NodeIds");
505 self.resolver
.next_node_id
= ast
::NodeId
::from_u32(next
);
509 /// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name
510 /// resolver (if any).
511 fn orig_opt_local_def_id(&self, node
: NodeId
) -> Option
<LocalDefId
> {
512 self.resolver
.node_id_to_def_id
.get(&node
).map(|local_def_id
| *local_def_id
)
515 fn orig_local_def_id(&self, node
: NodeId
) -> LocalDefId
{
516 self.orig_opt_local_def_id(node
)
517 .unwrap_or_else(|| panic
!("no entry for node id: `{:?}`", node
))
520 /// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name
521 /// resolver (if any), after applying any remapping from `get_remapped_def_id`.
523 /// For example, in a function like `fn foo<'a>(x: &'a u32)`,
524 /// invoking with the id from the `ast::Lifetime` node found inside
525 /// the `&'a u32` type would return the `LocalDefId` of the
526 /// `'a` parameter declared on `foo`.
528 /// This function also applies remapping from `get_remapped_def_id`.
529 /// These are used when synthesizing opaque types from `-> impl Trait` return types and so forth.
530 /// For example, in a function like `fn foo<'a>() -> impl Debug + 'a`,
531 /// we would create an opaque type `type FooReturn<'a1> = impl Debug + 'a1`.
532 /// When lowering the `Debug + 'a` bounds, we add a remapping to map `'a` to `'a1`.
533 fn opt_local_def_id(&self, node
: NodeId
) -> Option
<LocalDefId
> {
534 self.orig_opt_local_def_id(node
).map(|local_def_id
| self.get_remapped_def_id(local_def_id
))
537 fn local_def_id(&self, node
: NodeId
) -> LocalDefId
{
538 self.opt_local_def_id(node
).unwrap_or_else(|| panic
!("no entry for node id: `{:?}`", node
))
541 /// Get the previously recorded `to` local def id given the `from` local def id, obtained using
542 /// `generics_def_id_map` field.
543 fn get_remapped_def_id(&self, local_def_id
: LocalDefId
) -> LocalDefId
{
544 // `generics_def_id_map` is a stack of mappings. As we go deeper in impl traits nesting we
545 // push new mappings, so we first need to get the latest (innermost) mappings, hence `iter().rev()`.
549 // `fn test<'a, 'b>() -> impl Trait<&'a u8, Ty = impl Sized + 'b> {}`
551 // We would end with a generics_def_id_map like:
553 // `[[fn#'b -> impl_trait#'b], [fn#'b -> impl_sized#'b]]`
555 // for the opaque type generated on `impl Sized + 'b`, we want the result to be: impl_sized#'b.
556 // So, if we were trying to find first from the start (outermost) would give the wrong result, impl_trait#'b.
557 self.generics_def_id_map
560 .find_map(|map
| map
.get(&local_def_id
).map(|local_def_id
| *local_def_id
))
561 .unwrap_or(local_def_id
)
564 /// Freshen the `LoweringContext` and ready it to lower a nested item.
565 /// The lowered item is registered into `self.children`.
567 /// This function sets up `HirId` lowering infrastructure,
568 /// and stashes the shared mutable state to avoid pollution by the closure.
569 #[instrument(level = "debug", skip(self, f))]
570 fn with_hir_id_owner(
573 f
: impl FnOnce(&mut Self) -> hir
::OwnerNode
<'hir
>,
575 let def_id
= self.local_def_id(owner
);
577 let current_attrs
= std
::mem
::take(&mut self.attrs
);
578 let current_bodies
= std
::mem
::take(&mut self.bodies
);
579 let current_node_ids
= std
::mem
::take(&mut self.node_id_to_local_id
);
580 let current_id_to_def_id
= std
::mem
::take(&mut self.local_id_to_def_id
);
581 let current_trait_map
= std
::mem
::take(&mut self.trait_map
);
583 std
::mem
::replace(&mut self.current_hir_id_owner
, hir
::OwnerId { def_id }
);
584 let current_local_counter
=
585 std
::mem
::replace(&mut self.item_local_id_counter
, hir
::ItemLocalId
::new(1));
586 let current_impl_trait_defs
= std
::mem
::take(&mut self.impl_trait_defs
);
587 let current_impl_trait_bounds
= std
::mem
::take(&mut self.impl_trait_bounds
);
589 // Do not reset `next_node_id` and `node_id_to_def_id`:
590 // we want `f` to be able to refer to the `LocalDefId`s that the caller created.
591 // and the caller to refer to some of the subdefinitions' nodes' `LocalDefId`s.
593 // Always allocate the first `HirId` for the owner itself.
594 let _old
= self.node_id_to_local_id
.insert(owner
, hir
::ItemLocalId
::new(0));
595 debug_assert_eq
!(_old
, None
);
598 debug_assert_eq
!(def_id
, item
.def_id().def_id
);
599 // `f` should have consumed all the elements in these vectors when constructing `item`.
600 debug_assert
!(self.impl_trait_defs
.is_empty());
601 debug_assert
!(self.impl_trait_bounds
.is_empty());
602 let info
= self.make_owner_info(item
);
604 self.attrs
= current_attrs
;
605 self.bodies
= current_bodies
;
606 self.node_id_to_local_id
= current_node_ids
;
607 self.local_id_to_def_id
= current_id_to_def_id
;
608 self.trait_map
= current_trait_map
;
609 self.current_hir_id_owner
= current_owner
;
610 self.item_local_id_counter
= current_local_counter
;
611 self.impl_trait_defs
= current_impl_trait_defs
;
612 self.impl_trait_bounds
= current_impl_trait_bounds
;
614 let _old
= self.children
.insert(def_id
, hir
::MaybeOwner
::Owner(info
));
615 debug_assert
!(_old
.is_none())
618 /// Installs the remapping `remap` in scope while `f` is being executed.
619 /// This causes references to the `LocalDefId` keys to be changed to
620 /// refer to the values instead.
622 /// The remapping is used when one piece of AST expands to multiple
623 /// pieces of HIR. For example, the function `fn foo<'a>(...) -> impl Debug + 'a`,
624 /// expands to both a function definition (`foo`) and a TAIT for the return value,
625 /// both of which have a lifetime parameter `'a`. The remapping allows us to
626 /// rewrite the `'a` in the return value to refer to the
627 /// `'a` declared on the TAIT, instead of the function.
628 fn with_remapping
<R
>(
630 remap
: FxHashMap
<LocalDefId
, LocalDefId
>,
631 f
: impl FnOnce(&mut Self) -> R
,
633 self.generics_def_id_map
.push(remap
);
635 self.generics_def_id_map
.pop();
639 fn make_owner_info(&mut self, node
: hir
::OwnerNode
<'hir
>) -> &'hir hir
::OwnerInfo
<'hir
> {
640 let attrs
= std
::mem
::take(&mut self.attrs
);
641 let mut bodies
= std
::mem
::take(&mut self.bodies
);
642 let local_id_to_def_id
= std
::mem
::take(&mut self.local_id_to_def_id
);
643 let trait_map
= std
::mem
::take(&mut self.trait_map
);
645 #[cfg(debug_assertions)]
646 for (id
, attrs
) in attrs
.iter() {
647 // Verify that we do not store empty slices in the map.
648 if attrs
.is_empty() {
649 panic
!("Stored empty attributes for {:?}", id
);
653 bodies
.sort_by_key(|(k
, _
)| *k
);
654 let bodies
= SortedMap
::from_presorted_elements(bodies
);
655 let (hash_including_bodies
, hash_without_bodies
) = self.hash_owner(node
, &bodies
);
656 let (nodes
, parenting
) =
657 index
::index_hir(self.tcx
.sess
, &*self.tcx
.definitions_untracked(), node
, &bodies
);
658 let nodes
= hir
::OwnerNodes
{
659 hash_including_bodies
,
666 let hash
= self.tcx
.with_stable_hashing_context(|mut hcx
| {
667 let mut stable_hasher
= StableHasher
::new();
668 attrs
.hash_stable(&mut hcx
, &mut stable_hasher
);
669 stable_hasher
.finish()
671 hir
::AttributeMap { map: attrs, hash }
674 self.arena
.alloc(hir
::OwnerInfo { nodes, parenting, attrs, trait_map }
)
677 /// Hash the HIR node twice, one deep and one shallow hash. This allows to differentiate
678 /// queries which depend on the full HIR tree and those which only depend on the item signature.
681 node
: hir
::OwnerNode
<'hir
>,
682 bodies
: &SortedMap
<hir
::ItemLocalId
, &'hir hir
::Body
<'hir
>>,
683 ) -> (Fingerprint
, Fingerprint
) {
684 self.tcx
.with_stable_hashing_context(|mut hcx
| {
685 let mut stable_hasher
= StableHasher
::new();
686 hcx
.with_hir_bodies(node
.def_id(), bodies
, |hcx
| {
687 node
.hash_stable(hcx
, &mut stable_hasher
)
689 let hash_including_bodies
= stable_hasher
.finish();
690 let mut stable_hasher
= StableHasher
::new();
691 hcx
.without_hir_bodies(|hcx
| node
.hash_stable(hcx
, &mut stable_hasher
));
692 let hash_without_bodies
= stable_hasher
.finish();
693 (hash_including_bodies
, hash_without_bodies
)
697 /// This method allocates a new `HirId` for the given `NodeId` and stores it in
698 /// the `LoweringContext`'s `NodeId => HirId` map.
699 /// Take care not to call this method if the resulting `HirId` is then not
700 /// actually used in the HIR, as that would trigger an assertion in the
701 /// `HirIdValidator` later on, which makes sure that all `NodeId`s got mapped
702 /// properly. Calling the method twice with the same `NodeId` is fine though.
703 #[instrument(level = "debug", skip(self), ret)]
704 fn lower_node_id(&mut self, ast_node_id
: NodeId
) -> hir
::HirId
{
705 assert_ne
!(ast_node_id
, DUMMY_NODE_ID
);
707 match self.node_id_to_local_id
.entry(ast_node_id
) {
708 Entry
::Occupied(o
) => {
709 hir
::HirId { owner: self.current_hir_id_owner, local_id: *o.get() }
711 Entry
::Vacant(v
) => {
712 // Generate a new `HirId`.
713 let owner
= self.current_hir_id_owner
;
714 let local_id
= self.item_local_id_counter
;
715 let hir_id
= hir
::HirId { owner, local_id }
;
718 self.item_local_id_counter
.increment_by(1);
720 assert_ne
!(local_id
, hir
::ItemLocalId
::new(0));
721 if let Some(def_id
) = self.opt_local_def_id(ast_node_id
) {
722 // Do not override a `MaybeOwner::Owner` that may already here.
723 self.children
.entry(def_id
).or_insert(hir
::MaybeOwner
::NonOwner(hir_id
));
724 self.local_id_to_def_id
.insert(local_id
, def_id
);
727 if let Some(traits
) = self.resolver
.trait_map
.remove(&ast_node_id
) {
728 self.trait_map
.insert(hir_id
.local_id
, traits
.into_boxed_slice());
736 /// Generate a new `HirId` without a backing `NodeId`.
737 #[instrument(level = "debug", skip(self), ret)]
738 fn next_id(&mut self) -> hir
::HirId
{
739 let owner
= self.current_hir_id_owner
;
740 let local_id
= self.item_local_id_counter
;
741 assert_ne
!(local_id
, hir
::ItemLocalId
::new(0));
742 self.item_local_id_counter
.increment_by(1);
743 hir
::HirId { owner, local_id }
746 #[instrument(level = "trace", skip(self))]
747 fn lower_res(&mut self, res
: Res
<NodeId
>) -> Res
{
748 let res
: Result
<Res
, ()> = res
.apply_id(|id
| {
749 let owner
= self.current_hir_id_owner
;
750 let local_id
= self.node_id_to_local_id
.get(&id
).copied().ok_or(())?
;
751 Ok(hir
::HirId { owner, local_id }
)
755 // We may fail to find a HirId when the Res points to a Local from an enclosing HIR owner.
756 // This can happen when trying to lower the return type `x` in erroneous code like
757 // async fn foo(x: u8) -> x {}
758 // In that case, `x` is lowered as a function parameter, and the return type is lowered as
759 // an opaque type as a synthesized HIR owner.
760 res
.unwrap_or(Res
::Err
)
763 fn expect_full_res(&mut self, id
: NodeId
) -> Res
<NodeId
> {
764 self.resolver
.get_partial_res(id
).map_or(Res
::Err
, |pr
| pr
.expect_full_res())
767 fn expect_full_res_from_use(&mut self, id
: NodeId
) -> impl Iterator
<Item
= Res
<NodeId
>> {
768 self.resolver
.get_import_res(id
).present_items()
771 fn diagnostic(&self) -> &Handler
{
772 self.tcx
.sess
.diagnostic()
775 /// Reuses the span but adds information like the kind of the desugaring and features that are
776 /// allowed inside this span.
777 fn mark_span_with_reason(
779 reason
: DesugaringKind
,
781 allow_internal_unstable
: Option
<Lrc
<[Symbol
]>>,
783 self.tcx
.with_stable_hashing_context(|hcx
| {
784 span
.mark_with_reason(allow_internal_unstable
, reason
, self.tcx
.sess
.edition(), hcx
)
788 /// Intercept all spans entering HIR.
789 /// Mark a span as relative to the current owning item.
790 fn lower_span(&self, span
: Span
) -> Span
{
791 if self.tcx
.sess
.opts
.unstable_opts
.incremental_relative_spans
{
792 span
.with_parent(Some(self.current_hir_id_owner
.def_id
))
794 // Do not make spans relative when not using incremental compilation.
799 fn lower_ident(&self, ident
: Ident
) -> Ident
{
800 Ident
::new(ident
.name
, self.lower_span(ident
.span
))
803 /// Converts a lifetime into a new generic parameter.
804 #[instrument(level = "debug", skip(self))]
805 fn lifetime_res_to_generic_param(
810 ) -> Option
<hir
::GenericParam
<'hir
>> {
811 let (name
, kind
) = match res
{
812 LifetimeRes
::Param { .. }
=> {
813 (hir
::ParamName
::Plain(ident
), hir
::LifetimeParamKind
::Explicit
)
815 LifetimeRes
::Fresh { param, .. }
=> {
816 // Late resolution delegates to us the creation of the `LocalDefId`.
817 let _def_id
= self.create_def(
818 self.current_hir_id_owner
.def_id
,
820 DefPathData
::LifetimeNs(kw
::UnderscoreLifetime
),
824 (hir
::ParamName
::Fresh
, hir
::LifetimeParamKind
::Elided
)
826 LifetimeRes
::Static
| LifetimeRes
::Error
=> return None
,
828 "Unexpected lifetime resolution {:?} for {:?} at {:?}",
829 res
, ident
, ident
.span
832 let hir_id
= self.lower_node_id(node_id
);
833 Some(hir
::GenericParam
{
836 span
: self.lower_span(ident
.span
),
837 pure_wrt_drop
: false,
838 kind
: hir
::GenericParamKind
::Lifetime { kind }
,
843 /// Lowers a lifetime binder that defines `generic_params`, returning the corresponding HIR
844 /// nodes. The returned list includes any "extra" lifetime parameters that were added by the
845 /// name resolver owing to lifetime elision; this also populates the resolver's node-id->def-id
846 /// map, so that later calls to `opt_node_id_to_def_id` that refer to these extra lifetime
847 /// parameters will be successful.
848 #[instrument(level = "debug", skip(self))]
850 fn lower_lifetime_binder(
853 generic_params
: &[GenericParam
],
854 ) -> &'hir
[hir
::GenericParam
<'hir
>] {
855 let mut generic_params
: Vec
<_
> = self.lower_generic_params_mut(generic_params
).collect();
856 let extra_lifetimes
= self.resolver
.take_extra_lifetime_params(binder
);
857 debug
!(?extra_lifetimes
);
858 generic_params
.extend(extra_lifetimes
.into_iter().filter_map(|(ident
, node_id
, res
)| {
859 self.lifetime_res_to_generic_param(ident
, node_id
, res
)
861 let generic_params
= self.arena
.alloc_from_iter(generic_params
);
862 debug
!(?generic_params
);
867 fn with_dyn_type_scope
<T
>(&mut self, in_scope
: bool
, f
: impl FnOnce(&mut Self) -> T
) -> T
{
868 let was_in_dyn_type
= self.is_in_dyn_type
;
869 self.is_in_dyn_type
= in_scope
;
871 let result
= f(self);
873 self.is_in_dyn_type
= was_in_dyn_type
;
878 fn with_new_scopes
<T
>(&mut self, f
: impl FnOnce(&mut Self) -> T
) -> T
{
879 let was_in_loop_condition
= self.is_in_loop_condition
;
880 self.is_in_loop_condition
= false;
882 let catch_scope
= self.catch_scope
.take();
883 let loop_scope
= self.loop_scope
.take();
885 self.catch_scope
= catch_scope
;
886 self.loop_scope
= loop_scope
;
888 self.is_in_loop_condition
= was_in_loop_condition
;
893 fn lower_attrs(&mut self, id
: hir
::HirId
, attrs
: &[Attribute
]) -> Option
<&'hir
[Attribute
]> {
894 if attrs
.is_empty() {
897 debug_assert_eq
!(id
.owner
, self.current_hir_id_owner
);
898 let ret
= self.arena
.alloc_from_iter(attrs
.iter().map(|a
| self.lower_attr(a
)));
899 debug_assert
!(!ret
.is_empty());
900 self.attrs
.insert(id
.local_id
, ret
);
905 fn lower_attr(&self, attr
: &Attribute
) -> Attribute
{
906 // Note that we explicitly do not walk the path. Since we don't really
907 // lower attributes (we use the AST version) there is nowhere to keep
908 // the `HirId`s. We don't actually need HIR version of attributes anyway.
909 // Tokens are also not needed after macro expansion and parsing.
910 let kind
= match attr
.kind
{
911 AttrKind
::Normal(ref normal
) => AttrKind
::Normal(P(NormalAttr
{
913 path
: normal
.item
.path
.clone(),
914 args
: self.lower_mac_args(&normal
.item
.args
),
919 AttrKind
::DocComment(comment_kind
, data
) => AttrKind
::DocComment(comment_kind
, data
),
922 Attribute { kind, id: attr.id, style: attr.style, span: self.lower_span(attr.span) }
925 fn alias_attrs(&mut self, id
: hir
::HirId
, target_id
: hir
::HirId
) {
926 debug_assert_eq
!(id
.owner
, self.current_hir_id_owner
);
927 debug_assert_eq
!(target_id
.owner
, self.current_hir_id_owner
);
928 if let Some(&a
) = self.attrs
.get(&target_id
.local_id
) {
929 debug_assert
!(!a
.is_empty());
930 self.attrs
.insert(id
.local_id
, a
);
934 fn lower_mac_args(&self, args
: &MacArgs
) -> MacArgs
{
936 MacArgs
::Empty
=> MacArgs
::Empty
,
937 MacArgs
::Delimited(dspan
, delim
, ref tokens
) => {
938 // This is either a non-key-value attribute, or a `macro_rules!` body.
939 // We either not have any nonterminals present (in the case of an attribute),
940 // or have tokens available for all nonterminals in the case of a nested
941 // `macro_rules`: e.g:
944 // macro_rules! outer {
946 // macro_rules! inner {
953 // In both cases, we don't want to synthesize any tokens
954 MacArgs
::Delimited(dspan
, delim
, tokens
.flattened())
956 // This is an inert key-value attribute - it will never be visible to macros
957 // after it gets lowered to HIR. Therefore, we can extract literals to handle
958 // nonterminals in `#[doc]` (e.g. `#[doc = $e]`).
959 MacArgs
::Eq(eq_span
, MacArgsEq
::Ast(ref expr
)) => {
960 // In valid code the value always ends up as a single literal. Otherwise, a dummy
961 // literal suffices because the error is handled elsewhere.
962 let lit
= if let ExprKind
::Lit(lit
) = &expr
.kind
{
966 token_lit
: token
::Lit
::new(token
::LitKind
::Err
, kw
::Empty
, None
),
971 MacArgs
::Eq(eq_span
, MacArgsEq
::Hir(lit
))
973 MacArgs
::Eq(_
, MacArgsEq
::Hir(ref lit
)) => {
974 unreachable
!("in literal form when lowering mac args eq: {:?}", lit
)
979 /// Given an associated type constraint like one of these:
981 /// ```ignore (illustrative)
982 /// T: Iterator<Item: Debug>
984 /// T: Iterator<Item = Debug>
988 /// returns a `hir::TypeBinding` representing `Item`.
989 #[instrument(level = "debug", skip(self))]
990 fn lower_assoc_ty_constraint(
992 constraint
: &AssocConstraint
,
993 itctx
: &ImplTraitContext
,
994 ) -> hir
::TypeBinding
<'hir
> {
995 debug
!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint
, itctx
);
996 // lower generic arguments of identifier in constraint
997 let gen_args
= if let Some(ref gen_args
) = constraint
.gen_args
{
998 let gen_args_ctor
= match gen_args
{
999 GenericArgs
::AngleBracketed(ref data
) => {
1000 self.lower_angle_bracketed_parameter_data(data
, ParamMode
::Explicit
, itctx
).0
1002 GenericArgs
::Parenthesized(ref data
) => {
1003 self.emit_bad_parenthesized_trait_in_assoc_ty(data
);
1004 let aba
= self.ast_arena
.aba
.alloc(data
.as_angle_bracketed_args());
1005 self.lower_angle_bracketed_parameter_data(aba
, ParamMode
::Explicit
, itctx
).0
1008 gen_args_ctor
.into_generic_args(self)
1010 self.arena
.alloc(hir
::GenericArgs
::none())
1012 let itctx_tait
= &ImplTraitContext
::TypeAliasesOpaqueTy
;
1014 let kind
= match constraint
.kind
{
1015 AssocConstraintKind
::Equality { ref term }
=> {
1016 let term
= match term
{
1017 Term
::Ty(ref ty
) => self.lower_ty(ty
, itctx
).into(),
1018 Term
::Const(ref c
) => self.lower_anon_const(c
).into(),
1020 hir
::TypeBindingKind
::Equality { term }
1022 AssocConstraintKind
::Bound { ref bounds }
=> {
1023 // Piggy-back on the `impl Trait` context to figure out the correct behavior.
1024 let (desugar_to_impl_trait
, itctx
) = match itctx
{
1025 // We are in the return position:
1027 // fn foo() -> impl Iterator<Item: Debug>
1031 // fn foo() -> impl Iterator<Item = impl Debug>
1032 ImplTraitContext
::ReturnPositionOpaqueTy { .. }
1033 | ImplTraitContext
::TypeAliasesOpaqueTy { .. }
=> (true, itctx
),
1035 // We are in the argument position, but within a dyn type:
1037 // fn foo(x: dyn Iterator<Item: Debug>)
1041 // fn foo(x: dyn Iterator<Item = impl Debug>)
1042 ImplTraitContext
::Universal
if self.is_in_dyn_type
=> (true, itctx
),
1044 // In `type Foo = dyn Iterator<Item: Debug>` we desugar to
1045 // `type Foo = dyn Iterator<Item = impl Debug>` but we have to override the
1046 // "impl trait context" to permit `impl Debug` in this position (it desugars
1047 // then to an opaque type).
1049 // FIXME: this is only needed until `impl Trait` is allowed in type aliases.
1050 ImplTraitContext
::Disallowed(_
) if self.is_in_dyn_type
=> (true, itctx_tait
),
1052 // We are in the parameter position, but not within a dyn type:
1054 // fn foo(x: impl Iterator<Item: Debug>)
1056 // so we leave it as is and this gets expanded in astconv to a bound like
1057 // `<T as Iterator>::Item: Debug` where `T` is the type parameter for the
1059 _
=> (false, itctx
),
1062 if desugar_to_impl_trait
{
1063 // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by
1064 // constructing the HIR for `impl bounds...` and then lowering that.
1066 let impl_trait_node_id
= self.next_node_id();
1068 self.with_dyn_type_scope(false, |this
| {
1069 let node_id
= this
.next_node_id();
1070 let ty
= this
.ast_arena
.tys
.alloc(Ty
{
1072 kind
: TyKind
::ImplTrait(impl_trait_node_id
, bounds
.clone()),
1073 span
: this
.lower_span(constraint
.span
),
1076 let ty
= this
.lower_ty(ty
, itctx
);
1078 hir
::TypeBindingKind
::Equality { term: ty.into() }
1081 // Desugar `AssocTy: Bounds` into a type binding where the
1082 // later desugars into a trait predicate.
1083 let bounds
= self.lower_param_bounds(bounds
, itctx
);
1085 hir
::TypeBindingKind
::Constraint { bounds }
1091 hir_id
: self.lower_node_id(constraint
.id
),
1092 ident
: self.lower_ident(constraint
.ident
),
1095 span
: self.lower_span(constraint
.span
),
1099 fn emit_bad_parenthesized_trait_in_assoc_ty(&self, data
: &ParenthesizedArgs
) {
1100 // Suggest removing empty parentheses: "Trait()" -> "Trait"
1101 let sub
= if data
.inputs
.is_empty() {
1102 let parentheses_span
=
1103 data
.inputs_span
.shrink_to_lo().to(data
.inputs_span
.shrink_to_hi());
1104 AssocTyParenthesesSub
::Empty { parentheses_span }
1106 // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
1108 // Start of parameters to the 1st argument
1109 let open_param
= data
.inputs_span
.shrink_to_lo().to(data
1115 // End of last argument to end of parameters
1117 data
.inputs
.last().unwrap().span
.shrink_to_hi().to(data
.inputs_span
.shrink_to_hi());
1118 AssocTyParenthesesSub
::NotEmpty { open_param, close_param }
1120 self.tcx
.sess
.emit_err(AssocTyParentheses { span: data.span, sub }
);
1123 #[instrument(level = "debug", skip(self))]
1124 fn lower_generic_arg(
1126 arg
: &ast
::GenericArg
,
1127 itctx
: &ImplTraitContext
,
1128 ) -> hir
::GenericArg
<'hir
> {
1130 ast
::GenericArg
::Lifetime(lt
) => GenericArg
::Lifetime(self.lower_lifetime(<
)),
1131 ast
::GenericArg
::Type(ty
) => {
1133 TyKind
::Infer
if self.tcx
.features().generic_arg_infer
=> {
1134 return GenericArg
::Infer(hir
::InferArg
{
1135 hir_id
: self.lower_node_id(ty
.id
),
1136 span
: self.lower_span(ty
.span
),
1139 // We parse const arguments as path types as we cannot distinguish them during
1140 // parsing. We try to resolve that ambiguity by attempting resolution in both the
1141 // type and value namespaces. If we resolved the path in the value namespace, we
1142 // transform it into a generic const argument.
1143 TyKind
::Path(ref qself
, ref path
) => {
1144 if let Some(res
) = self
1146 .get_partial_res(ty
.id
)
1147 .and_then(|partial_res
| partial_res
.full_res())
1149 if !res
.matches_ns(Namespace
::TypeNS
) {
1151 "lower_generic_arg: Lowering type argument as const argument: {:?}",
1155 // Construct an AnonConst where the expr is the "ty"'s path.
1157 let parent_def_id
= self.current_hir_id_owner
;
1158 let node_id
= self.next_node_id();
1160 // Add a definition for the in-band const def.
1162 parent_def_id
.def_id
,
1164 DefPathData
::AnonConst
,
1167 let span
= self.lower_span(ty
.span
);
1168 let path_expr
= Expr
{
1170 kind
: ExprKind
::Path(qself
.clone(), path
.clone()),
1172 attrs
: AttrVec
::new(),
1176 let ct
= self.with_new_scopes(|this
| hir
::AnonConst
{
1177 hir_id
: this
.lower_node_id(node_id
),
1178 body
: this
.lower_const_body(path_expr
.span
, Some(&path_expr
)),
1180 return GenericArg
::Const(ConstArg { value: ct, span }
);
1186 GenericArg
::Type(self.lower_ty(&ty
, itctx
))
1188 ast
::GenericArg
::Const(ct
) => GenericArg
::Const(ConstArg
{
1189 value
: self.lower_anon_const(&ct
),
1190 span
: self.lower_span(ct
.value
.span
),
1195 #[instrument(level = "debug", skip(self))]
1196 fn lower_ty(&mut self, t
: &Ty
, itctx
: &ImplTraitContext
) -> &'hir hir
::Ty
<'hir
> {
1197 self.arena
.alloc(self.lower_ty_direct(t
, itctx
))
1203 qself
: &Option
<QSelf
>,
1205 param_mode
: ParamMode
,
1206 itctx
: &ImplTraitContext
,
1207 ) -> hir
::Ty
<'hir
> {
1208 // Check whether we should interpret this as a bare trait object.
1209 // This check mirrors the one in late resolution. We only introduce this special case in
1210 // the rare occurrence we need to lower `Fresh` anonymous lifetimes.
1211 // The other cases when a qpath should be opportunistically made a trait object are handled
1214 && let Some(partial_res
) = self.resolver
.get_partial_res(t
.id
)
1215 && let Some(Res
::Def(DefKind
::Trait
| DefKind
::TraitAlias
, _
)) = partial_res
.full_res()
1217 let (bounds
, lifetime_bound
) = self.with_dyn_type_scope(true, |this
| {
1218 let poly_trait_ref
= this
.ast_arena
.ptr
.alloc(PolyTraitRef
{
1219 bound_generic_params
: vec
![],
1220 trait_ref
: TraitRef { path: path.clone(), ref_id: t.id }
,
1223 let bound
= this
.lower_poly_trait_ref(
1227 let bounds
= this
.arena
.alloc_from_iter([bound
]);
1228 let lifetime_bound
= this
.elided_dyn_bound(t
.span
);
1229 (bounds
, lifetime_bound
)
1231 let kind
= hir
::TyKind
::TraitObject(bounds
, &lifetime_bound
, TraitObjectSyntax
::None
);
1232 return hir
::Ty { kind, span: self.lower_span(t.span), hir_id: self.next_id() }
;
1235 let id
= self.lower_node_id(t
.id
);
1236 let qpath
= self.lower_qpath(t
.id
, qself
, path
, param_mode
, itctx
);
1237 self.ty_path(id
, t
.span
, qpath
)
1240 fn ty(&mut self, span
: Span
, kind
: hir
::TyKind
<'hir
>) -> hir
::Ty
<'hir
> {
1241 hir
::Ty { hir_id: self.next_id(), kind, span: self.lower_span(span) }
1244 fn ty_tup(&mut self, span
: Span
, tys
: &'hir
[hir
::Ty
<'hir
>]) -> hir
::Ty
<'hir
> {
1245 self.ty(span
, hir
::TyKind
::Tup(tys
))
1248 fn lower_ty_direct(&mut self, t
: &Ty
, itctx
: &ImplTraitContext
) -> hir
::Ty
<'hir
> {
1249 let kind
= match t
.kind
{
1250 TyKind
::Infer
=> hir
::TyKind
::Infer
,
1251 TyKind
::Err
=> hir
::TyKind
::Err
,
1252 TyKind
::Slice(ref ty
) => hir
::TyKind
::Slice(self.lower_ty(ty
, itctx
)),
1253 TyKind
::Ptr(ref mt
) => hir
::TyKind
::Ptr(self.lower_mt(mt
, itctx
)),
1254 TyKind
::Rptr(ref region
, ref mt
) => {
1255 let region
= region
.unwrap_or_else(|| {
1256 let id
= if let Some(LifetimeRes
::ElidedAnchor { start, end }
) =
1257 self.resolver
.get_lifetime_res(t
.id
)
1259 debug_assert_eq
!(start
.plus(1), end
);
1264 let span
= self.tcx
.sess
.source_map().start_point(t
.span
);
1265 Lifetime { ident: Ident::new(kw::UnderscoreLifetime, span), id }
1267 let lifetime
= self.lower_lifetime(®ion
);
1268 hir
::TyKind
::Rptr(lifetime
, self.lower_mt(mt
, itctx
))
1270 TyKind
::BareFn(ref f
) => {
1271 let generic_params
= self.lower_lifetime_binder(t
.id
, &f
.generic_params
);
1272 hir
::TyKind
::BareFn(self.arena
.alloc(hir
::BareFnTy
{
1274 unsafety
: self.lower_unsafety(f
.unsafety
),
1275 abi
: self.lower_extern(f
.ext
),
1276 decl
: self.lower_fn_decl(&f
.decl
, None
, t
.span
, FnDeclKind
::Pointer
, None
),
1277 param_names
: self.lower_fn_params_to_names(&f
.decl
),
1280 TyKind
::Never
=> hir
::TyKind
::Never
,
1281 TyKind
::Tup(ref tys
) => hir
::TyKind
::Tup(
1282 self.arena
.alloc_from_iter(tys
.iter().map(|ty
| self.lower_ty_direct(ty
, itctx
))),
1284 TyKind
::Paren(ref ty
) => {
1285 return self.lower_ty_direct(ty
, itctx
);
1287 TyKind
::Path(ref qself
, ref path
) => {
1288 return self.lower_path_ty(t
, qself
, path
, ParamMode
::Explicit
, itctx
);
1290 TyKind
::ImplicitSelf
=> {
1291 let hir_id
= self.next_id();
1292 let res
= self.expect_full_res(t
.id
);
1293 let res
= self.lower_res(res
);
1294 hir
::TyKind
::Path(hir
::QPath
::Resolved(
1296 self.arena
.alloc(hir
::Path
{
1298 segments
: arena_vec
![self; hir
::PathSegment
::new(
1299 Ident
::with_dummy_span(kw
::SelfUpper
),
1303 span
: self.lower_span(t
.span
),
1307 TyKind
::Array(ref ty
, ref length
) => {
1308 hir
::TyKind
::Array(self.lower_ty(ty
, itctx
), self.lower_array_length(length
))
1310 TyKind
::Typeof(ref expr
) => hir
::TyKind
::Typeof(self.lower_anon_const(expr
)),
1311 TyKind
::TraitObject(ref bounds
, kind
) => {
1312 let mut lifetime_bound
= None
;
1313 let (bounds
, lifetime_bound
) = self.with_dyn_type_scope(true, |this
| {
1315 this
.arena
.alloc_from_iter(bounds
.iter().filter_map(
1316 |bound
| match *bound
{
1317 GenericBound
::Trait(
1319 TraitBoundModifier
::None
| TraitBoundModifier
::MaybeConst
,
1320 ) => Some(this
.lower_poly_trait_ref(ty
, itctx
)),
1321 // `~const ?Bound` will cause an error during AST validation
1322 // anyways, so treat it like `?Bound` as compilation proceeds.
1323 GenericBound
::Trait(
1325 TraitBoundModifier
::Maybe
| TraitBoundModifier
::MaybeConstMaybe
,
1327 GenericBound
::Outlives(ref lifetime
) => {
1328 if lifetime_bound
.is_none() {
1329 lifetime_bound
= Some(this
.lower_lifetime(lifetime
));
1335 let lifetime_bound
=
1336 lifetime_bound
.unwrap_or_else(|| this
.elided_dyn_bound(t
.span
));
1337 (bounds
, lifetime_bound
)
1339 hir
::TyKind
::TraitObject(bounds
, lifetime_bound
, kind
)
1341 TyKind
::ImplTrait(def_node_id
, ref bounds
) => {
1344 ImplTraitContext
::ReturnPositionOpaqueTy { origin, in_trait }
=> self
1345 .lower_opaque_impl_trait(
1353 ImplTraitContext
::TypeAliasesOpaqueTy
=> self.lower_opaque_impl_trait(
1355 hir
::OpaqueTyOrigin
::TyAlias
,
1361 ImplTraitContext
::Universal
=> {
1363 self.current_hir_id_owner
.def_id
,
1365 DefPathData
::ImplTrait
,
1368 let ident
= Ident
::from_str_and_span(&pprust
::ty_to_string(t
), span
);
1369 let (param
, bounds
, path
) =
1370 self.lower_generic_and_bounds(def_node_id
, span
, ident
, bounds
);
1371 self.impl_trait_defs
.push(param
);
1372 if let Some(bounds
) = bounds
{
1373 self.impl_trait_bounds
.push(bounds
);
1377 ImplTraitContext
::Disallowed(
1378 position @
(ImplTraitPosition
::TraitReturn
| ImplTraitPosition
::ImplReturn
),
1382 .create_feature_err(
1383 MisplacedImplTrait
{
1385 position
: DiagnosticArgFromDisplay(&position
),
1387 sym
::return_position_impl_trait_in_trait
,
1392 ImplTraitContext
::Disallowed(position
) => {
1393 self.tcx
.sess
.emit_err(MisplacedImplTrait
{
1395 position
: DiagnosticArgFromDisplay(&position
),
1401 TyKind
::MacCall(_
) => panic
!("`TyKind::MacCall` should have been expanded by now"),
1402 TyKind
::CVarArgs
=> {
1403 self.tcx
.sess
.delay_span_bug(
1405 "`TyKind::CVarArgs` should have been handled elsewhere",
1411 hir
::Ty { kind, span: self.lower_span(t.span), hir_id: self.lower_node_id(t.id) }
1414 /// Lowers a `ReturnPositionOpaqueTy` (`-> impl Trait`) or a `TypeAliasesOpaqueTy` (`type F =
1415 /// impl Trait`): this creates the associated Opaque Type (TAIT) definition and then returns a
1416 /// HIR type that references the TAIT.
1418 /// Given a function definition like:
1421 /// fn test<'a, T: Debug>(x: &'a T) -> impl Debug + 'a {
1426 /// we will create a TAIT definition in the HIR like
1429 /// type TestReturn<'a, T, 'x> = impl Debug + 'x
1432 /// and return a type like `TestReturn<'static, T, 'a>`, so that the function looks like:
1435 /// fn test<'a, T: Debug>(x: &'a T) -> TestReturn<'static, T, 'a>
1438 /// Note the subtlety around type parameters! The new TAIT, `TestReturn`, inherits all the
1439 /// type parameters from the function `test` (this is implemented in the query layer, they aren't
1440 /// added explicitly in the HIR). But this includes all the lifetimes, and we only want to
1441 /// capture the lifetimes that are referenced in the bounds. Therefore, we add *extra* lifetime parameters
1442 /// for the lifetimes that get captured (`'x`, in our example above) and reference those.
1443 #[instrument(level = "debug", skip(self), ret)]
1444 fn lower_opaque_impl_trait(
1447 origin
: hir
::OpaqueTyOrigin
,
1448 opaque_ty_node_id
: NodeId
,
1449 bounds
: &GenericBounds
,
1451 itctx
: &ImplTraitContext
,
1452 ) -> hir
::TyKind
<'hir
> {
1453 // Make sure we know that some funky desugaring has been going on here.
1454 // This is a first: there is code in other places like for loop
1455 // desugaring that explicitly states that we don't want to track that.
1456 // Not tracking it makes lints in rustc and clippy very fragile, as
1457 // frequently opened issues show.
1458 let opaque_ty_span
= self.mark_span_with_reason(DesugaringKind
::OpaqueTy
, span
, None
);
1460 let opaque_ty_def_id
= match origin
{
1461 hir
::OpaqueTyOrigin
::TyAlias
=> self.create_def(
1462 self.current_hir_id_owner
.def_id
,
1464 DefPathData
::ImplTrait
,
1466 hir
::OpaqueTyOrigin
::FnReturn(fn_def_id
) => {
1467 self.create_def(fn_def_id
, opaque_ty_node_id
, DefPathData
::ImplTrait
)
1469 hir
::OpaqueTyOrigin
::AsyncFn(..) => bug
!("unreachable"),
1471 debug
!(?opaque_ty_def_id
);
1473 // Contains the new lifetime definitions created for the TAIT (if any).
1474 let mut collected_lifetimes
= Vec
::new();
1476 // If this came from a TAIT (as opposed to a function that returns an RPIT), we only want
1477 // to capture the lifetimes that appear in the bounds. So visit the bounds to find out
1478 // exactly which ones those are.
1479 let lifetimes_to_remap
= if origin
== hir
::OpaqueTyOrigin
::TyAlias
{
1480 // in a TAIT like `type Foo<'a> = impl Foo<'a>`, we don't keep all the lifetime parameters
1483 // in fn return position, like the `fn test<'a>() -> impl Debug + 'a` example,
1484 // we only keep the lifetimes that appear in the `impl Debug` itself:
1485 lifetime_collector
::lifetimes_in_bounds(&self.resolver
, bounds
)
1487 debug
!(?lifetimes_to_remap
);
1489 self.with_hir_id_owner(opaque_ty_node_id
, |lctx
| {
1490 let mut new_remapping
= FxHashMap
::default();
1492 // If this opaque type is only capturing a subset of the lifetimes (those that appear
1493 // in bounds), then create the new lifetime parameters required and create a mapping
1494 // from the old `'a` (on the function) to the new `'a` (on the opaque type).
1495 collected_lifetimes
= lctx
.create_lifetime_defs(
1497 &lifetimes_to_remap
,
1500 debug
!(?collected_lifetimes
);
1501 debug
!(?new_remapping
);
1503 // Install the remapping from old to new (if any):
1504 lctx
.with_remapping(new_remapping
, |lctx
| {
1505 // This creates HIR lifetime definitions as `hir::GenericParam`, in the given
1506 // example `type TestReturn<'a, T, 'x> = impl Debug + 'x`, it creates a collection
1507 // containing `&['x]`.
1508 let lifetime_defs
= lctx
.arena
.alloc_from_iter(collected_lifetimes
.iter().map(
1509 |&(new_node_id
, lifetime
)| {
1510 let hir_id
= lctx
.lower_node_id(new_node_id
);
1511 debug_assert_ne
!(lctx
.opt_local_def_id(new_node_id
), None
);
1513 let (name
, kind
) = if lifetime
.ident
.name
== kw
::UnderscoreLifetime
{
1514 (hir
::ParamName
::Fresh
, hir
::LifetimeParamKind
::Elided
)
1517 hir
::ParamName
::Plain(lifetime
.ident
),
1518 hir
::LifetimeParamKind
::Explicit
,
1525 span
: lifetime
.ident
.span
,
1526 pure_wrt_drop
: false,
1527 kind
: hir
::GenericParamKind
::Lifetime { kind }
,
1532 debug
!(?lifetime_defs
);
1534 // Then when we lower the param bounds, references to 'a are remapped to 'a1, so we
1535 // get back Debug + 'a1, which is suitable for use on the TAIT.
1536 let hir_bounds
= lctx
.lower_param_bounds(bounds
, itctx
);
1537 debug
!(?hir_bounds
);
1539 let opaque_ty_item
= hir
::OpaqueTy
{
1540 generics
: self.arena
.alloc(hir
::Generics
{
1541 params
: lifetime_defs
,
1543 has_where_clause_predicates
: false,
1544 where_clause_span
: lctx
.lower_span(span
),
1545 span
: lctx
.lower_span(span
),
1551 debug
!(?opaque_ty_item
);
1553 lctx
.generate_opaque_type(opaque_ty_def_id
, opaque_ty_item
, span
, opaque_ty_span
)
1557 // This creates HIR lifetime arguments as `hir::GenericArg`, in the given example `type
1558 // TestReturn<'a, T, 'x> = impl Debug + 'x`, it creates a collection containing `&['x]`.
1560 self.arena
.alloc_from_iter(collected_lifetimes
.into_iter().map(|(_
, lifetime
)| {
1561 let id
= self.next_node_id();
1562 let span
= lifetime
.ident
.span
;
1564 let ident
= if lifetime
.ident
.name
== kw
::UnderscoreLifetime
{
1565 Ident
::with_dummy_span(kw
::UnderscoreLifetime
)
1570 let l
= self.new_named_lifetime(lifetime
.id
, id
, span
, ident
);
1571 hir
::GenericArg
::Lifetime(l
)
1575 // `impl Trait` now just becomes `Foo<'a, 'b, ..>`.
1576 hir
::TyKind
::OpaqueDef(
1577 hir
::ItemId { owner_id: hir::OwnerId { def_id: opaque_ty_def_id }
},
1583 /// Registers a new opaque type with the proper `NodeId`s and
1584 /// returns the lowered node-ID for the opaque type.
1585 fn generate_opaque_type(
1587 opaque_ty_id
: LocalDefId
,
1588 opaque_ty_item
: hir
::OpaqueTy
<'hir
>,
1590 opaque_ty_span
: Span
,
1591 ) -> hir
::OwnerNode
<'hir
> {
1592 let opaque_ty_item_kind
= hir
::ItemKind
::OpaqueTy(opaque_ty_item
);
1593 // Generate an `type Foo = impl Trait;` declaration.
1594 trace
!("registering opaque type with id {:#?}", opaque_ty_id
);
1595 let opaque_ty_item
= hir
::Item
{
1596 owner_id
: hir
::OwnerId { def_id: opaque_ty_id }
,
1597 ident
: Ident
::empty(),
1598 kind
: opaque_ty_item_kind
,
1599 vis_span
: self.lower_span(span
.shrink_to_lo()),
1600 span
: self.lower_span(opaque_ty_span
),
1602 hir
::OwnerNode
::Item(self.arena
.alloc(opaque_ty_item
))
1605 /// Given a `parent_def_id`, a list of `lifetimes_in_bounds and a `remapping` hash to be
1606 /// filled, this function creates new definitions for `Param` and `Fresh` lifetimes, inserts the
1607 /// new definition, adds it to the remapping with the definition of the given lifetime and
1608 /// returns a list of lifetimes to be lowered afterwards.
1609 fn create_lifetime_defs(
1611 parent_def_id
: LocalDefId
,
1612 lifetimes_in_bounds
: &[Lifetime
],
1613 remapping
: &mut FxHashMap
<LocalDefId
, LocalDefId
>,
1614 ) -> Vec
<(NodeId
, Lifetime
)> {
1615 let mut result
= Vec
::new();
1617 for lifetime
in lifetimes_in_bounds
{
1618 let res
= self.resolver
.get_lifetime_res(lifetime
.id
).unwrap_or(LifetimeRes
::Error
);
1622 LifetimeRes
::Param { param: old_def_id, binder: _ }
=> {
1623 if remapping
.get(&old_def_id
).is_none() {
1624 let node_id
= self.next_node_id();
1626 let new_def_id
= self.create_def(
1629 DefPathData
::LifetimeNs(lifetime
.ident
.name
),
1631 remapping
.insert(old_def_id
, new_def_id
);
1633 result
.push((node_id
, *lifetime
));
1637 LifetimeRes
::Fresh { param, binder: _ }
=> {
1638 debug_assert_eq
!(lifetime
.ident
.name
, kw
::UnderscoreLifetime
);
1639 if let Some(old_def_id
) = self.orig_opt_local_def_id(param
) && remapping
.get(&old_def_id
).is_none() {
1640 let node_id
= self.next_node_id();
1642 let new_def_id
= self.create_def(
1645 DefPathData
::LifetimeNs(kw
::UnderscoreLifetime
),
1647 remapping
.insert(old_def_id
, new_def_id
);
1649 result
.push((node_id
, *lifetime
));
1653 LifetimeRes
::Static
| LifetimeRes
::Error
=> {}
1656 let bug_msg
= format
!(
1657 "Unexpected lifetime resolution {:?} for {:?} at {:?}",
1658 res
, lifetime
.ident
, lifetime
.ident
.span
1660 span_bug
!(lifetime
.ident
.span
, "{}", bug_msg
);
1668 fn lower_fn_params_to_names(&mut self, decl
: &FnDecl
) -> &'hir
[Ident
] {
1669 // Skip the `...` (`CVarArgs`) trailing arguments from the AST,
1670 // as they are not explicit in HIR/Ty function signatures.
1671 // (instead, the `c_variadic` flag is set to `true`)
1672 let mut inputs
= &decl
.inputs
[..];
1673 if decl
.c_variadic() {
1674 inputs
= &inputs
[..inputs
.len() - 1];
1676 self.arena
.alloc_from_iter(inputs
.iter().map(|param
| match param
.pat
.kind
{
1677 PatKind
::Ident(_
, ident
, _
) => self.lower_ident(ident
),
1678 _
=> Ident
::new(kw
::Empty
, self.lower_span(param
.pat
.span
)),
1682 // Lowers a function declaration.
1684 // `decl`: the unlowered (AST) function declaration.
1685 // `fn_def_id`: if `Some`, impl Trait arguments are lowered into generic parameters on the
1686 // given DefId, otherwise impl Trait is disallowed. Must be `Some` if
1687 // `make_ret_async` is also `Some`.
1688 // `make_ret_async`: if `Some`, converts `-> T` into `-> impl Future<Output = T>` in the
1689 // return type. This is used for `async fn` declarations. The `NodeId` is the ID of the
1690 // return type `impl Trait` item, and the `Span` points to the `async` keyword.
1691 #[instrument(level = "debug", skip(self))]
1695 fn_node_id
: Option
<NodeId
>,
1698 make_ret_async
: Option
<(NodeId
, Span
)>,
1699 ) -> &'hir hir
::FnDecl
<'hir
> {
1700 let c_variadic
= decl
.c_variadic();
1702 // Skip the `...` (`CVarArgs`) trailing arguments from the AST,
1703 // as they are not explicit in HIR/Ty function signatures.
1704 // (instead, the `c_variadic` flag is set to `true`)
1705 let mut inputs
= &decl
.inputs
[..];
1707 inputs
= &inputs
[..inputs
.len() - 1];
1709 let inputs
= self.arena
.alloc_from_iter(inputs
.iter().map(|param
| {
1710 if fn_node_id
.is_some() {
1711 self.lower_ty_direct(¶m
.ty
, &ImplTraitContext
::Universal
)
1713 self.lower_ty_direct(
1715 &ImplTraitContext
::Disallowed(match kind
{
1716 FnDeclKind
::Fn
| FnDeclKind
::Inherent
=> {
1717 unreachable
!("fn should allow in-band lifetimes")
1719 FnDeclKind
::ExternFn
=> ImplTraitPosition
::ExternFnParam
,
1720 FnDeclKind
::Closure
=> ImplTraitPosition
::ClosureParam
,
1721 FnDeclKind
::Pointer
=> ImplTraitPosition
::PointerParam
,
1722 FnDeclKind
::Trait
=> ImplTraitPosition
::TraitParam
,
1723 FnDeclKind
::Impl
=> ImplTraitPosition
::ImplParam
,
1729 let output
= if let Some((ret_id
, span
)) = make_ret_async
{
1730 if !kind
.async_fn_allowed(self.tcx
) {
1732 FnDeclKind
::Trait
| FnDeclKind
::Impl
=> {
1735 .create_feature_err(
1736 TraitFnAsync { fn_span, span }
,
1737 sym
::async_fn_in_trait
,
1742 self.tcx
.sess
.emit_err(TraitFnAsync { fn_span, span }
);
1747 self.lower_async_fn_ret_ty(
1749 fn_node_id
.expect("`make_ret_async` but no `fn_def_id`"),
1751 matches
!(kind
, FnDeclKind
::Trait
),
1755 FnRetTy
::Ty(ref ty
) => {
1756 let mut context
= match fn_node_id
{
1757 Some(fn_node_id
) if kind
.impl_trait_allowed(self.tcx
) => {
1758 let fn_def_id
= self.local_def_id(fn_node_id
);
1759 ImplTraitContext
::ReturnPositionOpaqueTy
{
1760 origin
: hir
::OpaqueTyOrigin
::FnReturn(fn_def_id
),
1761 in_trait
: matches
!(kind
, FnDeclKind
::Trait
),
1764 _
=> ImplTraitContext
::Disallowed(match kind
{
1765 FnDeclKind
::Fn
| FnDeclKind
::Inherent
=> {
1766 unreachable
!("fn should allow in-band lifetimes")
1768 FnDeclKind
::ExternFn
=> ImplTraitPosition
::ExternFnReturn
,
1769 FnDeclKind
::Closure
=> ImplTraitPosition
::ClosureReturn
,
1770 FnDeclKind
::Pointer
=> ImplTraitPosition
::PointerReturn
,
1771 FnDeclKind
::Trait
=> ImplTraitPosition
::TraitReturn
,
1772 FnDeclKind
::Impl
=> ImplTraitPosition
::ImplReturn
,
1775 hir
::FnRetTy
::Return(self.lower_ty(ty
, &mut context
))
1777 FnRetTy
::Default(span
) => hir
::FnRetTy
::DefaultReturn(self.lower_span(span
)),
1781 self.arena
.alloc(hir
::FnDecl
{
1785 implicit_self
: decl
.inputs
.get(0).map_or(hir
::ImplicitSelfKind
::None
, |arg
| {
1786 let is_mutable_pat
= matches
!(
1788 PatKind
::Ident(hir
::BindingAnnotation(_
, Mutability
::Mut
), ..)
1792 TyKind
::ImplicitSelf
if is_mutable_pat
=> hir
::ImplicitSelfKind
::Mut
,
1793 TyKind
::ImplicitSelf
=> hir
::ImplicitSelfKind
::Imm
,
1794 // Given we are only considering `ImplicitSelf` types, we needn't consider
1795 // the case where we have a mutable pattern to a reference as that would
1796 // no longer be an `ImplicitSelf`.
1797 TyKind
::Rptr(_
, ref mt
)
1798 if mt
.ty
.kind
.is_implicit_self() && mt
.mutbl
== ast
::Mutability
::Mut
=>
1800 hir
::ImplicitSelfKind
::MutRef
1802 TyKind
::Rptr(_
, ref mt
) if mt
.ty
.kind
.is_implicit_self() => {
1803 hir
::ImplicitSelfKind
::ImmRef
1805 _
=> hir
::ImplicitSelfKind
::None
,
1811 // Transforms `-> T` for `async fn` into `-> OpaqueTy { .. }`
1812 // combined with the following definition of `OpaqueTy`:
1814 // type OpaqueTy<generics_from_parent_fn> = impl Future<Output = T>;
1816 // `output`: unlowered output type (`T` in `-> T`)
1817 // `fn_def_id`: `DefId` of the parent function (used to create child impl trait definition)
1818 // `opaque_ty_node_id`: `NodeId` of the opaque `impl Trait` type that should be created
1819 #[instrument(level = "debug", skip(self))]
1820 fn lower_async_fn_ret_ty(
1824 opaque_ty_node_id
: NodeId
,
1826 ) -> hir
::FnRetTy
<'hir
> {
1827 let span
= output
.span();
1829 let opaque_ty_span
= self.mark_span_with_reason(DesugaringKind
::Async
, span
, None
);
1831 let opaque_ty_def_id
= self.local_def_id(opaque_ty_node_id
);
1832 let fn_def_id
= self.local_def_id(fn_node_id
);
1834 // When we create the opaque type for this async fn, it is going to have
1835 // to capture all the lifetimes involved in the signature (including in the
1836 // return type). This is done by introducing lifetime parameters for:
1838 // - all the explicitly declared lifetimes from the impl and function itself;
1839 // - all the elided lifetimes in the fn arguments;
1840 // - all the elided lifetimes in the return type.
1842 // So for example in this snippet:
1845 // impl<'a> Foo<'a> {
1846 // async fn bar<'b>(&self, x: &'b Vec<f64>, y: &str) -> &u32 {
1847 // // ^ '0 ^ '1 ^ '2
1848 // // elided lifetimes used below
1853 // we would create an opaque type like:
1856 // type Bar<'a, 'b, '0, '1, '2> = impl Future<Output = &'2 u32>;
1859 // and we would then desugar `bar` to the equivalent of:
1862 // impl<'a> Foo<'a> {
1863 // fn bar<'b, '0, '1>(&'0 self, x: &'b Vec<f64>, y: &'1 str) -> Bar<'a, 'b, '0, '1, '_>
1867 // Note that the final parameter to `Bar` is `'_`, not `'2` --
1868 // this is because the elided lifetimes from the return type
1869 // should be figured out using the ordinary elision rules, and
1870 // this desugaring achieves that.
1872 // Calculate all the lifetimes that should be captured
1873 // by the opaque type. This should include all in-scope
1874 // lifetime parameters, including those defined in-band.
1876 // Contains the new lifetime definitions created for the TAIT (if any) generated for the
1878 let mut collected_lifetimes
= Vec
::new();
1879 let mut new_remapping
= FxHashMap
::default();
1881 let extra_lifetime_params
= self.resolver
.take_extra_lifetime_params(opaque_ty_node_id
);
1882 debug
!(?extra_lifetime_params
);
1883 for (ident
, outer_node_id
, outer_res
) in extra_lifetime_params
{
1884 let outer_def_id
= self.orig_local_def_id(outer_node_id
);
1885 let inner_node_id
= self.next_node_id();
1887 // Add a definition for the in scope lifetime def.
1888 let inner_def_id
= self.create_def(
1891 DefPathData
::LifetimeNs(ident
.name
),
1893 new_remapping
.insert(outer_def_id
, inner_def_id
);
1895 let inner_res
= match outer_res
{
1896 // Input lifetime like `'a`:
1897 LifetimeRes
::Param { param, .. }
=> {
1898 LifetimeRes
::Param { param, binder: fn_node_id }
1900 // Input lifetime like `'1`:
1901 LifetimeRes
::Fresh { param, .. }
=> {
1902 LifetimeRes
::Fresh { param, binder: fn_node_id }
1904 LifetimeRes
::Static
| LifetimeRes
::Error
=> continue,
1907 "Unexpected lifetime resolution {:?} for {:?} at {:?}",
1908 res
, ident
, ident
.span
1913 let lifetime
= Lifetime { id: outer_node_id, ident }
;
1914 collected_lifetimes
.push((inner_node_id
, lifetime
, Some(inner_res
)));
1917 debug
!(?collected_lifetimes
);
1919 // We only want to capture the lifetimes that appear in the bounds. So visit the bounds to
1920 // find out exactly which ones those are.
1921 // in fn return position, like the `fn test<'a>() -> impl Debug + 'a` example,
1922 // we only keep the lifetimes that appear in the `impl Debug` itself:
1923 let lifetimes_to_remap
= lifetime_collector
::lifetimes_in_ret_ty(&self.resolver
, output
);
1924 debug
!(?lifetimes_to_remap
);
1926 self.with_hir_id_owner(opaque_ty_node_id
, |this
| {
1927 // If this opaque type is only capturing a subset of the lifetimes (those that appear
1928 // in bounds), then create the new lifetime parameters required and create a mapping
1929 // from the old `'a` (on the function) to the new `'a` (on the opaque type).
1930 collected_lifetimes
.extend(
1931 this
.create_lifetime_defs(
1933 &lifetimes_to_remap
,
1937 .map(|(new_node_id
, lifetime
)| (new_node_id
, lifetime
, None
)),
1939 debug
!(?collected_lifetimes
);
1940 debug
!(?new_remapping
);
1942 // Install the remapping from old to new (if any):
1943 this
.with_remapping(new_remapping
, |this
| {
1944 // We have to be careful to get elision right here. The
1945 // idea is that we create a lifetime parameter for each
1946 // lifetime in the return type. So, given a return type
1947 // like `async fn foo(..) -> &[&u32]`, we lower to `impl
1948 // Future<Output = &'1 [ &'2 u32 ]>`.
1950 // Then, we will create `fn foo(..) -> Foo<'_, '_>`, and
1951 // hence the elision takes place at the fn site.
1952 let future_bound
= this
.lower_async_fn_output_type_to_future_bound(
1955 if in_trait
&& !this
.tcx
.features().return_position_impl_trait_in_trait
{
1956 ImplTraitContext
::Disallowed(ImplTraitPosition
::TraitReturn
)
1958 ImplTraitContext
::ReturnPositionOpaqueTy
{
1959 origin
: hir
::OpaqueTyOrigin
::FnReturn(fn_def_id
),
1965 let generic_params
= this
.arena
.alloc_from_iter(collected_lifetimes
.iter().map(
1966 |&(new_node_id
, lifetime
, _
)| {
1967 let hir_id
= this
.lower_node_id(new_node_id
);
1968 debug_assert_ne
!(this
.opt_local_def_id(new_node_id
), None
);
1970 let (name
, kind
) = if lifetime
.ident
.name
== kw
::UnderscoreLifetime
{
1971 (hir
::ParamName
::Fresh
, hir
::LifetimeParamKind
::Elided
)
1974 hir
::ParamName
::Plain(lifetime
.ident
),
1975 hir
::LifetimeParamKind
::Explicit
,
1982 span
: lifetime
.ident
.span
,
1983 pure_wrt_drop
: false,
1984 kind
: hir
::GenericParamKind
::Lifetime { kind }
,
1989 debug
!("lower_async_fn_ret_ty: generic_params={:#?}", generic_params
);
1991 let opaque_ty_item
= hir
::OpaqueTy
{
1992 generics
: this
.arena
.alloc(hir
::Generics
{
1993 params
: generic_params
,
1995 has_where_clause_predicates
: false,
1996 where_clause_span
: this
.lower_span(span
),
1997 span
: this
.lower_span(span
),
1999 bounds
: arena_vec
![this
; future_bound
],
2000 origin
: hir
::OpaqueTyOrigin
::AsyncFn(fn_def_id
),
2004 trace
!("exist ty from async fn def id: {:#?}", opaque_ty_def_id
);
2005 this
.generate_opaque_type(opaque_ty_def_id
, opaque_ty_item
, span
, opaque_ty_span
)
2009 // As documented above, we need to create the lifetime
2010 // arguments to our opaque type. Continuing with our example,
2011 // we're creating the type arguments for the return type:
2014 // Bar<'a, 'b, '0, '1, '_>
2017 // For the "input" lifetime parameters, we wish to create
2018 // references to the parameters themselves, including the
2019 // "implicit" ones created from parameter types (`'a`, `'b`,
2022 // For the "output" lifetime parameters, we just want to
2024 let generic_args
= self.arena
.alloc_from_iter(collected_lifetimes
.into_iter().map(
2025 |(_
, lifetime
, res
)| {
2026 let id
= self.next_node_id();
2027 let span
= lifetime
.ident
.span
;
2029 let ident
= if lifetime
.ident
.name
== kw
::UnderscoreLifetime
{
2030 Ident
::with_dummy_span(kw
::UnderscoreLifetime
)
2035 let res
= res
.unwrap_or(
2036 self.resolver
.get_lifetime_res(lifetime
.id
).unwrap_or(LifetimeRes
::Error
),
2038 hir
::GenericArg
::Lifetime(self.new_named_lifetime_with_res(id
, span
, ident
, res
))
2042 // Create the `Foo<...>` reference itself. Note that the `type
2043 // Foo = impl Trait` is, internally, created as a child of the
2044 // async fn, so the *type parameters* are inherited. It's
2045 // only the lifetime parameters that we must supply.
2046 let opaque_ty_ref
= hir
::TyKind
::OpaqueDef(
2047 hir
::ItemId { owner_id: hir::OwnerId { def_id: opaque_ty_def_id }
},
2051 let opaque_ty
= self.ty(opaque_ty_span
, opaque_ty_ref
);
2052 hir
::FnRetTy
::Return(self.arena
.alloc(opaque_ty
))
2055 /// Transforms `-> T` into `Future<Output = T>`.
2056 fn lower_async_fn_output_type_to_future_bound(
2060 mut nested_impl_trait_context
: ImplTraitContext
,
2061 ) -> hir
::GenericBound
<'hir
> {
2062 // Compute the `T` in `Future<Output = T>` from the return type.
2063 let output_ty
= match output
{
2064 FnRetTy
::Ty(ty
) => {
2065 // Not `OpaqueTyOrigin::AsyncFn`: that's only used for the
2066 // `impl Future` opaque type that `async fn` implicitly
2068 self.lower_ty(ty
, &mut nested_impl_trait_context
)
2070 FnRetTy
::Default(ret_ty_span
) => self.arena
.alloc(self.ty_tup(*ret_ty_span
, &[])),
2074 let future_args
= self.arena
.alloc(hir
::GenericArgs
{
2076 bindings
: arena_vec
![self; self.output_ty_binding(span
, output_ty
)],
2077 parenthesized
: false,
2081 hir
::GenericBound
::LangItemTrait(
2082 // ::std::future::Future<future_params>
2083 hir
::LangItem
::Future
,
2084 self.lower_span(span
),
2090 #[instrument(level = "trace", skip(self))]
2091 fn lower_param_bound(
2094 itctx
: &ImplTraitContext
,
2095 ) -> hir
::GenericBound
<'hir
> {
2097 GenericBound
::Trait(p
, modifier
) => hir
::GenericBound
::Trait(
2098 self.lower_poly_trait_ref(p
, itctx
),
2099 self.lower_trait_bound_modifier(*modifier
),
2101 GenericBound
::Outlives(lifetime
) => {
2102 hir
::GenericBound
::Outlives(self.lower_lifetime(lifetime
))
2107 fn lower_lifetime(&mut self, l
: &Lifetime
) -> &'hir hir
::Lifetime
{
2108 let span
= self.lower_span(l
.ident
.span
);
2109 let ident
= self.lower_ident(l
.ident
);
2110 self.new_named_lifetime(l
.id
, l
.id
, span
, ident
)
2113 #[instrument(level = "debug", skip(self))]
2114 fn new_named_lifetime_with_res(
2120 ) -> &'hir hir
::Lifetime
{
2121 let name
= match res
{
2122 LifetimeRes
::Param { param, .. }
=> {
2123 let p_name
= ParamName
::Plain(ident
);
2124 let param
= self.get_remapped_def_id(param
);
2126 hir
::LifetimeName
::Param(param
, p_name
)
2128 LifetimeRes
::Fresh { param, .. }
=> {
2129 debug_assert_eq
!(ident
.name
, kw
::UnderscoreLifetime
);
2130 let param
= self.local_def_id(param
);
2132 hir
::LifetimeName
::Param(param
, ParamName
::Fresh
)
2134 LifetimeRes
::Infer
=> hir
::LifetimeName
::Infer
,
2135 LifetimeRes
::Static
=> hir
::LifetimeName
::Static
,
2136 LifetimeRes
::Error
=> hir
::LifetimeName
::Error
,
2137 res
=> panic
!("Unexpected lifetime resolution {:?} for {:?} at {:?}", res
, ident
, span
),
2141 self.arena
.alloc(hir
::Lifetime
{
2142 hir_id
: self.lower_node_id(id
),
2143 span
: self.lower_span(span
),
2148 #[instrument(level = "debug", skip(self))]
2149 fn new_named_lifetime(
2155 ) -> &'hir hir
::Lifetime
{
2156 let res
= self.resolver
.get_lifetime_res(id
).unwrap_or(LifetimeRes
::Error
);
2157 self.new_named_lifetime_with_res(new_id
, span
, ident
, res
)
2160 fn lower_generic_params_mut
<'s
>(
2162 params
: &'s
[GenericParam
],
2163 ) -> impl Iterator
<Item
= hir
::GenericParam
<'hir
>> + Captures
<'a
> + Captures
<'s
> {
2164 params
.iter().map(move |param
| self.lower_generic_param(param
))
2167 fn lower_generic_params(&mut self, params
: &[GenericParam
]) -> &'hir
[hir
::GenericParam
<'hir
>] {
2168 self.arena
.alloc_from_iter(self.lower_generic_params_mut(params
))
2171 #[instrument(level = "trace", skip(self))]
2172 fn lower_generic_param(&mut self, param
: &GenericParam
) -> hir
::GenericParam
<'hir
> {
2173 let (name
, kind
) = self.lower_generic_param_kind(param
);
2175 let hir_id
= self.lower_node_id(param
.id
);
2176 self.lower_attrs(hir_id
, ¶m
.attrs
);
2180 span
: self.lower_span(param
.span()),
2181 pure_wrt_drop
: self.tcx
.sess
.contains_name(¶m
.attrs
, sym
::may_dangle
),
2183 colon_span
: param
.colon_span
.map(|s
| self.lower_span(s
)),
2187 fn lower_generic_param_kind(
2189 param
: &GenericParam
,
2190 ) -> (hir
::ParamName
, hir
::GenericParamKind
<'hir
>) {
2192 GenericParamKind
::Lifetime
=> {
2193 // AST resolution emitted an error on those parameters, so we lower them using
2194 // `ParamName::Error`.
2196 if let Some(LifetimeRes
::Error
) = self.resolver
.get_lifetime_res(param
.id
) {
2199 let ident
= self.lower_ident(param
.ident
);
2200 ParamName
::Plain(ident
)
2203 hir
::GenericParamKind
::Lifetime { kind: hir::LifetimeParamKind::Explicit }
;
2207 GenericParamKind
::Type { ref default, .. }
=> {
2208 let kind
= hir
::GenericParamKind
::Type
{
2209 default: default.as_ref().map(|x
| {
2210 self.lower_ty(x
, &ImplTraitContext
::Disallowed(ImplTraitPosition
::Type
))
2215 (hir
::ParamName
::Plain(self.lower_ident(param
.ident
)), kind
)
2217 GenericParamKind
::Const { ref ty, kw_span: _, ref default }
=> {
2218 let ty
= self.lower_ty(&ty
, &ImplTraitContext
::Disallowed(ImplTraitPosition
::Type
));
2219 let default = default.as_ref().map(|def
| self.lower_anon_const(def
));
2221 hir
::ParamName
::Plain(self.lower_ident(param
.ident
)),
2222 hir
::GenericParamKind
::Const { ty, default }
,
2228 fn lower_trait_ref(&mut self, p
: &TraitRef
, itctx
: &ImplTraitContext
) -> hir
::TraitRef
<'hir
> {
2229 let path
= match self.lower_qpath(p
.ref_id
, &None
, &p
.path
, ParamMode
::Explicit
, itctx
) {
2230 hir
::QPath
::Resolved(None
, path
) => path
,
2231 qpath
=> panic
!("lower_trait_ref: unexpected QPath `{:?}`", qpath
),
2233 hir
::TraitRef { path, hir_ref_id: self.lower_node_id(p.ref_id) }
2236 #[instrument(level = "debug", skip(self))]
2237 fn lower_poly_trait_ref(
2240 itctx
: &ImplTraitContext
,
2241 ) -> hir
::PolyTraitRef
<'hir
> {
2242 let bound_generic_params
=
2243 self.lower_lifetime_binder(p
.trait_ref
.ref_id
, &p
.bound_generic_params
);
2244 let trait_ref
= self.lower_trait_ref(&p
.trait_ref
, itctx
);
2245 hir
::PolyTraitRef { bound_generic_params, trait_ref, span: self.lower_span(p.span) }
2248 fn lower_mt(&mut self, mt
: &MutTy
, itctx
: &ImplTraitContext
) -> hir
::MutTy
<'hir
> {
2249 hir
::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl }
2252 #[instrument(level = "debug", skip(self), ret)]
2253 fn lower_param_bounds(
2255 bounds
: &[GenericBound
],
2256 itctx
: &ImplTraitContext
,
2257 ) -> hir
::GenericBounds
<'hir
> {
2258 self.arena
.alloc_from_iter(self.lower_param_bounds_mut(bounds
, itctx
))
2261 fn lower_param_bounds_mut
<'s
>(
2263 bounds
: &'s
[GenericBound
],
2264 itctx
: &'s ImplTraitContext
,
2265 ) -> impl Iterator
<Item
= hir
::GenericBound
<'hir
>> + Captures
<'s
> + Captures
<'a
> {
2266 bounds
.iter().map(move |bound
| self.lower_param_bound(bound
, itctx
))
2269 #[instrument(level = "debug", skip(self), ret)]
2270 fn lower_generic_and_bounds(
2275 bounds
: &[GenericBound
],
2276 ) -> (hir
::GenericParam
<'hir
>, Option
<hir
::WherePredicate
<'hir
>>, hir
::TyKind
<'hir
>) {
2277 // Add a definition for the in-band `Param`.
2278 let def_id
= self.local_def_id(node_id
);
2280 // Set the name to `impl Bound1 + Bound2`.
2281 let param
= hir
::GenericParam
{
2282 hir_id
: self.lower_node_id(node_id
),
2283 name
: ParamName
::Plain(self.lower_ident(ident
)),
2284 pure_wrt_drop
: false,
2285 span
: self.lower_span(span
),
2286 kind
: hir
::GenericParamKind
::Type { default: None, synthetic: true }
,
2290 let preds
= self.lower_generic_bound_predicate(
2293 &GenericParamKind
::Type { default: None }
,
2295 &ImplTraitContext
::Universal
,
2296 hir
::PredicateOrigin
::ImplTrait
,
2299 let hir_id
= self.next_id();
2300 let res
= Res
::Def(DefKind
::TyParam
, def_id
.to_def_id());
2301 let ty
= hir
::TyKind
::Path(hir
::QPath
::Resolved(
2303 self.arena
.alloc(hir
::Path
{
2304 span
: self.lower_span(span
),
2307 arena_vec
![self; hir
::PathSegment
::new(self.lower_ident(ident
), hir_id
, res
)],
2314 /// Lowers a block directly to an expression, presuming that it
2315 /// has no attributes and is not targeted by a `break`.
2316 fn lower_block_expr(&mut self, b
: &Block
) -> hir
::Expr
<'hir
> {
2317 let block
= self.lower_block(b
, false);
2318 self.expr_block(block
, AttrVec
::new())
2321 fn lower_array_length(&mut self, c
: &AnonConst
) -> hir
::ArrayLen
{
2322 match c
.value
.kind
{
2323 ExprKind
::Underscore
=> {
2324 if self.tcx
.features().generic_arg_infer
{
2325 hir
::ArrayLen
::Infer(self.lower_node_id(c
.id
), c
.value
.span
)
2328 &self.tcx
.sess
.parse_sess
,
2329 sym
::generic_arg_infer
,
2331 "using `_` for array lengths is unstable",
2333 .stash(c
.value
.span
, StashKey
::UnderscoreForArrayLengths
);
2334 hir
::ArrayLen
::Body(self.lower_anon_const(c
))
2337 _
=> hir
::ArrayLen
::Body(self.lower_anon_const(c
)),
2341 fn lower_anon_const(&mut self, c
: &AnonConst
) -> hir
::AnonConst
{
2342 self.with_new_scopes(|this
| hir
::AnonConst
{
2343 hir_id
: this
.lower_node_id(c
.id
),
2344 body
: this
.lower_const_body(c
.value
.span
, Some(&c
.value
)),
2348 fn lower_unsafe_source(&mut self, u
: UnsafeSource
) -> hir
::UnsafeSource
{
2350 CompilerGenerated
=> hir
::UnsafeSource
::CompilerGenerated
,
2351 UserProvided
=> hir
::UnsafeSource
::UserProvided
,
2355 fn lower_trait_bound_modifier(&mut self, f
: TraitBoundModifier
) -> hir
::TraitBoundModifier
{
2357 TraitBoundModifier
::None
=> hir
::TraitBoundModifier
::None
,
2358 TraitBoundModifier
::MaybeConst
=> hir
::TraitBoundModifier
::MaybeConst
,
2360 // `MaybeConstMaybe` will cause an error during AST validation, but we need to pick a
2361 // placeholder for compilation to proceed.
2362 TraitBoundModifier
::MaybeConstMaybe
| TraitBoundModifier
::Maybe
=> {
2363 hir
::TraitBoundModifier
::Maybe
2368 // Helper methods for building HIR.
2370 fn stmt(&mut self, span
: Span
, kind
: hir
::StmtKind
<'hir
>) -> hir
::Stmt
<'hir
> {
2371 hir
::Stmt { span: self.lower_span(span), kind, hir_id: self.next_id() }
2374 fn stmt_expr(&mut self, span
: Span
, expr
: hir
::Expr
<'hir
>) -> hir
::Stmt
<'hir
> {
2375 self.stmt(span
, hir
::StmtKind
::Expr(self.arena
.alloc(expr
)))
2380 attrs
: Option
<&'hir
[Attribute
]>,
2382 init
: Option
<&'hir hir
::Expr
<'hir
>>,
2383 pat
: &'hir hir
::Pat
<'hir
>,
2384 source
: hir
::LocalSource
,
2385 ) -> hir
::Stmt
<'hir
> {
2386 let hir_id
= self.next_id();
2387 if let Some(a
) = attrs
{
2388 debug_assert
!(!a
.is_empty());
2389 self.attrs
.insert(hir_id
.local_id
, a
);
2391 let local
= hir
::Local
{
2397 span
: self.lower_span(span
),
2400 self.stmt(span
, hir
::StmtKind
::Local(self.arena
.alloc(local
)))
2403 fn block_expr(&mut self, expr
: &'hir hir
::Expr
<'hir
>) -> &'hir hir
::Block
<'hir
> {
2404 self.block_all(expr
.span
, &[], Some(expr
))
2410 stmts
: &'hir
[hir
::Stmt
<'hir
>],
2411 expr
: Option
<&'hir hir
::Expr
<'hir
>>,
2412 ) -> &'hir hir
::Block
<'hir
> {
2413 let blk
= hir
::Block
{
2416 hir_id
: self.next_id(),
2417 rules
: hir
::BlockCheckMode
::DefaultBlock
,
2418 span
: self.lower_span(span
),
2419 targeted_by_break
: false,
2421 self.arena
.alloc(blk
)
2424 fn pat_cf_continue(&mut self, span
: Span
, pat
: &'hir hir
::Pat
<'hir
>) -> &'hir hir
::Pat
<'hir
> {
2425 let field
= self.single_pat_field(span
, pat
);
2426 self.pat_lang_item_variant(span
, hir
::LangItem
::ControlFlowContinue
, field
, None
)
2429 fn pat_cf_break(&mut self, span
: Span
, pat
: &'hir hir
::Pat
<'hir
>) -> &'hir hir
::Pat
<'hir
> {
2430 let field
= self.single_pat_field(span
, pat
);
2431 self.pat_lang_item_variant(span
, hir
::LangItem
::ControlFlowBreak
, field
, None
)
2434 fn pat_some(&mut self, span
: Span
, pat
: &'hir hir
::Pat
<'hir
>) -> &'hir hir
::Pat
<'hir
> {
2435 let field
= self.single_pat_field(span
, pat
);
2436 self.pat_lang_item_variant(span
, hir
::LangItem
::OptionSome
, field
, None
)
2439 fn pat_none(&mut self, span
: Span
) -> &'hir hir
::Pat
<'hir
> {
2440 self.pat_lang_item_variant(span
, hir
::LangItem
::OptionNone
, &[], None
)
2443 fn single_pat_field(
2446 pat
: &'hir hir
::Pat
<'hir
>,
2447 ) -> &'hir
[hir
::PatField
<'hir
>] {
2448 let field
= hir
::PatField
{
2449 hir_id
: self.next_id(),
2450 ident
: Ident
::new(sym
::integer(0), self.lower_span(span
)),
2451 is_shorthand
: false,
2453 span
: self.lower_span(span
),
2455 arena_vec
![self; field
]
2458 fn pat_lang_item_variant(
2461 lang_item
: hir
::LangItem
,
2462 fields
: &'hir
[hir
::PatField
<'hir
>],
2463 hir_id
: Option
<hir
::HirId
>,
2464 ) -> &'hir hir
::Pat
<'hir
> {
2465 let qpath
= hir
::QPath
::LangItem(lang_item
, self.lower_span(span
), hir_id
);
2466 self.pat(span
, hir
::PatKind
::Struct(qpath
, fields
, false))
2469 fn pat_ident(&mut self, span
: Span
, ident
: Ident
) -> (&'hir hir
::Pat
<'hir
>, hir
::HirId
) {
2470 self.pat_ident_binding_mode(span
, ident
, hir
::BindingAnnotation
::NONE
)
2473 fn pat_ident_mut(&mut self, span
: Span
, ident
: Ident
) -> (hir
::Pat
<'hir
>, hir
::HirId
) {
2474 self.pat_ident_binding_mode_mut(span
, ident
, hir
::BindingAnnotation
::NONE
)
2477 fn pat_ident_binding_mode(
2481 bm
: hir
::BindingAnnotation
,
2482 ) -> (&'hir hir
::Pat
<'hir
>, hir
::HirId
) {
2483 let (pat
, hir_id
) = self.pat_ident_binding_mode_mut(span
, ident
, bm
);
2484 (self.arena
.alloc(pat
), hir_id
)
2487 fn pat_ident_binding_mode_mut(
2491 bm
: hir
::BindingAnnotation
,
2492 ) -> (hir
::Pat
<'hir
>, hir
::HirId
) {
2493 let hir_id
= self.next_id();
2498 kind
: hir
::PatKind
::Binding(bm
, hir_id
, self.lower_ident(ident
), None
),
2499 span
: self.lower_span(span
),
2500 default_binding_modes
: true,
2506 fn pat(&mut self, span
: Span
, kind
: hir
::PatKind
<'hir
>) -> &'hir hir
::Pat
<'hir
> {
2507 self.arena
.alloc(hir
::Pat
{
2508 hir_id
: self.next_id(),
2510 span
: self.lower_span(span
),
2511 default_binding_modes
: true,
2515 fn pat_without_dbm(&mut self, span
: Span
, kind
: hir
::PatKind
<'hir
>) -> hir
::Pat
<'hir
> {
2517 hir_id
: self.next_id(),
2519 span
: self.lower_span(span
),
2520 default_binding_modes
: false,
2526 mut hir_id
: hir
::HirId
,
2528 qpath
: hir
::QPath
<'hir
>,
2529 ) -> hir
::Ty
<'hir
> {
2530 let kind
= match qpath
{
2531 hir
::QPath
::Resolved(None
, path
) => {
2532 // Turn trait object paths into `TyKind::TraitObject` instead.
2534 Res
::Def(DefKind
::Trait
| DefKind
::TraitAlias
, _
) => {
2535 let principal
= hir
::PolyTraitRef
{
2536 bound_generic_params
: &[],
2537 trait_ref
: hir
::TraitRef { path, hir_ref_id: hir_id }
,
2538 span
: self.lower_span(span
),
2541 // The original ID is taken by the `PolyTraitRef`,
2542 // so the `Ty` itself needs a different one.
2543 hir_id
= self.next_id();
2544 hir
::TyKind
::TraitObject(
2545 arena_vec
![self; principal
],
2546 self.elided_dyn_bound(span
),
2547 TraitObjectSyntax
::None
,
2550 _
=> hir
::TyKind
::Path(hir
::QPath
::Resolved(None
, path
)),
2553 _
=> hir
::TyKind
::Path(qpath
),
2556 hir
::Ty { hir_id, kind, span: self.lower_span(span) }
2559 /// Invoked to create the lifetime argument(s) for an elided trait object
2560 /// bound, like the bound in `Box<dyn Debug>`. This method is not invoked
2561 /// when the bound is written, even if it is written with `'_` like in
2562 /// `Box<dyn Debug + '_>`. In those cases, `lower_lifetime` is invoked.
2563 fn elided_dyn_bound(&mut self, span
: Span
) -> &'hir hir
::Lifetime
{
2564 let r
= hir
::Lifetime
{
2565 hir_id
: self.next_id(),
2566 span
: self.lower_span(span
),
2567 name
: hir
::LifetimeName
::ImplicitObjectLifetimeDefault
,
2569 debug
!("elided_dyn_bound: r={:?}", r
);
2574 /// Helper struct for delayed construction of GenericArgs.
2575 struct GenericArgsCtor
<'hir
> {
2576 args
: SmallVec
<[hir
::GenericArg
<'hir
>; 4]>,
2577 bindings
: &'hir
[hir
::TypeBinding
<'hir
>],
2578 parenthesized
: bool
,
2582 impl<'hir
> GenericArgsCtor
<'hir
> {
2583 fn is_empty(&self) -> bool
{
2584 self.args
.is_empty() && self.bindings
.is_empty() && !self.parenthesized
2587 fn into_generic_args(self, this
: &LoweringContext
<'_
, 'hir
>) -> &'hir hir
::GenericArgs
<'hir
> {
2588 let ga
= hir
::GenericArgs
{
2589 args
: this
.arena
.alloc_from_iter(self.args
),
2590 bindings
: self.bindings
,
2591 parenthesized
: self.parenthesized
,
2592 span_ext
: this
.lower_span(self.span
),
2594 this
.arena
.alloc(ga
)