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), then you 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(array_value_iter)]
34 #![feature(crate_visibility_modifier)]
35 #![feature(marker_trait_attr)]
36 #![feature(specialization)] // FIXME: min_specialization does not work
37 #![feature(or_patterns)]
38 #![recursion_limit = "256"]
41 use rustc_ast
::ast
::*;
43 use rustc_ast
::node_id
::NodeMap
;
44 use rustc_ast
::token
::{self, Nonterminal, Token}
;
45 use rustc_ast
::tokenstream
::{TokenStream, TokenTree}
;
46 use rustc_ast
::visit
::{self, AssocCtxt, Visitor}
;
47 use rustc_ast
::walk_list
;
48 use rustc_ast_pretty
::pprust
;
49 use rustc_data_structures
::captures
::Captures
;
50 use rustc_data_structures
::fx
::FxHashSet
;
51 use rustc_data_structures
::sync
::Lrc
;
52 use rustc_errors
::struct_span_err
;
54 use rustc_hir
::def
::{DefKind, Namespace, PartialRes, PerNS, Res}
;
55 use rustc_hir
::def_id
::{DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX}
;
56 use rustc_hir
::definitions
::{DefKey, DefPathData, Definitions}
;
57 use rustc_hir
::intravisit
;
58 use rustc_hir
::{ConstArg, GenericArg, ParamName}
;
59 use rustc_index
::vec
::IndexVec
;
60 use rustc_session
::config
::nightly_options
;
61 use rustc_session
::lint
::{builtin::BARE_TRAIT_OBJECTS, BuiltinLintDiagnostics, LintBuffer}
;
62 use rustc_session
::parse
::ParseSess
;
63 use rustc_session
::Session
;
64 use rustc_span
::hygiene
::ExpnId
;
65 use rustc_span
::source_map
::{respan, DesugaringKind, ExpnData, ExpnKind}
;
66 use rustc_span
::symbol
::{kw, sym, Ident, Symbol}
;
69 use log
::{debug, trace}
;
70 use smallvec
::{smallvec, SmallVec}
;
71 use std
::collections
::BTreeMap
;
74 macro_rules
! arena_vec
{
75 ($this
:expr
; $
($x
:expr
),*) => ({
77 $this
.arena
.alloc_from_iter(std
::array
::IntoIter
::new(a
))
86 const HIR_ID_COUNTER_LOCKED
: u32 = 0xFFFFFFFF;
88 rustc_hir
::arena_types
!(::arena
::declare_arena
, [], 'tcx
);
90 struct LoweringContext
<'a
, 'hir
: 'a
> {
91 crate_root
: Option
<Symbol
>,
93 /// Used to assign IDs to HIR nodes that do not directly correspond to AST nodes.
96 resolver
: &'a
mut dyn Resolver
,
98 /// HACK(Centril): there is a cyclic dependency between the parser and lowering
99 /// if we don't have this function pointer. To avoid that dependency so that
100 /// librustc_middle is independent of the parser, we use dynamic dispatch here.
101 nt_to_tokenstream
: NtToTokenstream
,
103 /// Used to allocate HIR nodes
104 arena
: &'hir Arena
<'hir
>,
106 /// The items being lowered are collected here.
107 items
: BTreeMap
<hir
::HirId
, hir
::Item
<'hir
>>,
109 trait_items
: BTreeMap
<hir
::TraitItemId
, hir
::TraitItem
<'hir
>>,
110 impl_items
: BTreeMap
<hir
::ImplItemId
, hir
::ImplItem
<'hir
>>,
111 bodies
: BTreeMap
<hir
::BodyId
, hir
::Body
<'hir
>>,
112 exported_macros
: Vec
<hir
::MacroDef
<'hir
>>,
113 non_exported_macro_attrs
: Vec
<ast
::Attribute
>,
115 trait_impls
: BTreeMap
<DefId
, Vec
<hir
::HirId
>>,
117 modules
: BTreeMap
<hir
::HirId
, hir
::ModuleItems
>,
119 generator_kind
: Option
<hir
::GeneratorKind
>,
121 /// When inside an `async` context, this is the `HirId` of the
122 /// `task_context` local bound to the resume argument of the generator.
123 task_context
: Option
<hir
::HirId
>,
125 /// Used to get the current `fn`'s def span to point to when using `await`
126 /// outside of an `async fn`.
127 current_item
: Option
<Span
>,
129 catch_scopes
: Vec
<NodeId
>,
130 loop_scopes
: Vec
<NodeId
>,
131 is_in_loop_condition
: bool
,
132 is_in_trait_impl
: bool
,
133 is_in_dyn_type
: bool
,
135 /// What to do when we encounter either an "anonymous lifetime
136 /// reference". The term "anonymous" is meant to encompass both
137 /// `'_` lifetimes as well as fully elided cases where nothing is
138 /// written at all (e.g., `&T` or `std::cell::Ref<T>`).
139 anonymous_lifetime_mode
: AnonymousLifetimeMode
,
141 /// Used to create lifetime definitions from in-band lifetime usages.
142 /// e.g., `fn foo(x: &'x u8) -> &'x u8` to `fn foo<'x>(x: &'x u8) -> &'x u8`
143 /// When a named lifetime is encountered in a function or impl header and
144 /// has not been defined
145 /// (i.e., it doesn't appear in the in_scope_lifetimes list), it is added
146 /// to this list. The results of this list are then added to the list of
147 /// lifetime definitions in the corresponding impl or function generics.
148 lifetimes_to_define
: Vec
<(Span
, ParamName
)>,
150 /// `true` if in-band lifetimes are being collected. This is used to
151 /// indicate whether or not we're in a place where new lifetimes will result
152 /// in in-band lifetime definitions, such a function or an impl header,
153 /// including implicit lifetimes from `impl_header_lifetime_elision`.
154 is_collecting_in_band_lifetimes
: bool
,
156 /// Currently in-scope lifetimes defined in impl headers, fn headers, or HRTB.
157 /// When `is_collectin_in_band_lifetimes` is true, each lifetime is checked
158 /// against this list to see if it is already in-scope, or if a definition
159 /// needs to be created for it.
161 /// We always store a `normalize_to_macros_2_0()` version of the param-name in this
163 in_scope_lifetimes
: Vec
<ParamName
>,
165 current_module
: hir
::HirId
,
167 type_def_lifetime_params
: DefIdMap
<usize>,
169 current_hir_id_owner
: Vec
<(LocalDefId
, u32)>,
170 item_local_id_counters
: NodeMap
<u32>,
171 node_id_to_hir_id
: IndexVec
<NodeId
, Option
<hir
::HirId
>>,
173 allow_try_trait
: Option
<Lrc
<[Symbol
]>>,
174 allow_gen_future
: Option
<Lrc
<[Symbol
]>>,
178 fn def_key(&mut self, id
: DefId
) -> DefKey
;
180 fn item_generics_num_lifetimes(&self, def
: DefId
, sess
: &Session
) -> usize;
182 /// Obtains resolution for a `NodeId` with a single resolution.
183 fn get_partial_res(&mut self, id
: NodeId
) -> Option
<PartialRes
>;
185 /// Obtains per-namespace resolutions for `use` statement with the given `NodeId`.
186 fn get_import_res(&mut self, id
: NodeId
) -> PerNS
<Option
<Res
<NodeId
>>>;
188 /// Obtains resolution for a label with the given `NodeId`.
189 fn get_label_res(&mut self, id
: NodeId
) -> Option
<NodeId
>;
191 /// We must keep the set of definitions up to date as we add nodes that weren't in the AST.
192 /// This should only return `None` during testing.
193 fn definitions(&mut self) -> &mut Definitions
;
195 /// Given suffix `["b", "c", "d"]`, creates an AST path for `[::crate_root]::b::c::d` and
196 /// resolves it based on `is_value`.
200 crate_root
: Option
<Symbol
>,
201 components
: &[Symbol
],
203 ) -> (ast
::Path
, Res
<NodeId
>);
205 fn lint_buffer(&mut self) -> &mut LintBuffer
;
207 fn next_node_id(&mut self) -> NodeId
;
210 type NtToTokenstream
= fn(&Nonterminal
, &ParseSess
, Span
) -> TokenStream
;
212 /// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,
213 /// and if so, what meaning it has.
215 enum ImplTraitContext
<'b
, 'a
> {
216 /// Treat `impl Trait` as shorthand for a new universal generic parameter.
217 /// Example: `fn foo(x: impl Debug)`, where `impl Debug` is conceptually
218 /// equivalent to a fresh universal parameter like `fn foo<T: Debug>(x: T)`.
220 /// Newly generated parameters should be inserted into the given `Vec`.
221 Universal(&'b
mut Vec
<hir
::GenericParam
<'a
>>),
223 /// Treat `impl Trait` as shorthand for a new opaque type.
224 /// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
225 /// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`.
227 /// We optionally store a `DefId` for the parent item here so we can look up necessary
228 /// information later. It is `None` when no information about the context should be stored
229 /// (e.g., for consts and statics).
230 OpaqueTy(Option
<DefId
> /* fn def-ID */, hir
::OpaqueTyOrigin
),
232 /// `impl Trait` is not accepted in this position.
233 Disallowed(ImplTraitPosition
),
236 /// Position in which `impl Trait` is disallowed.
237 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
238 enum ImplTraitPosition
{
239 /// Disallowed in `let` / `const` / `static` bindings.
242 /// All other posiitons.
246 impl<'a
> ImplTraitContext
<'_
, 'a
> {
248 fn disallowed() -> Self {
249 ImplTraitContext
::Disallowed(ImplTraitPosition
::Other
)
252 fn reborrow
<'this
>(&'this
mut self) -> ImplTraitContext
<'this
, 'a
> {
253 use self::ImplTraitContext
::*;
255 Universal(params
) => Universal(params
),
256 OpaqueTy(fn_def_id
, origin
) => OpaqueTy(*fn_def_id
, *origin
),
257 Disallowed(pos
) => Disallowed(*pos
),
262 pub fn lower_crate
<'a
, 'hir
>(
265 resolver
: &'a
mut dyn Resolver
,
266 nt_to_tokenstream
: NtToTokenstream
,
267 arena
: &'hir Arena
<'hir
>,
268 ) -> hir
::Crate
<'hir
> {
269 let _prof_timer
= sess
.prof
.verbose_generic_activity("hir_lowering");
272 crate_root
: sess
.parse_sess
.injected_crate_name
.get().copied(),
277 items
: BTreeMap
::new(),
278 trait_items
: BTreeMap
::new(),
279 impl_items
: BTreeMap
::new(),
280 bodies
: BTreeMap
::new(),
281 trait_impls
: BTreeMap
::new(),
282 modules
: BTreeMap
::new(),
283 exported_macros
: Vec
::new(),
284 non_exported_macro_attrs
: Vec
::new(),
285 catch_scopes
: Vec
::new(),
286 loop_scopes
: Vec
::new(),
287 is_in_loop_condition
: false,
288 is_in_trait_impl
: false,
289 is_in_dyn_type
: false,
290 anonymous_lifetime_mode
: AnonymousLifetimeMode
::PassThrough
,
291 type_def_lifetime_params
: Default
::default(),
292 current_module
: hir
::CRATE_HIR_ID
,
293 current_hir_id_owner
: vec
![(LocalDefId { local_def_index: CRATE_DEF_INDEX }
, 0)],
294 item_local_id_counters
: Default
::default(),
295 node_id_to_hir_id
: IndexVec
::new(),
296 generator_kind
: None
,
299 lifetimes_to_define
: Vec
::new(),
300 is_collecting_in_band_lifetimes
: false,
301 in_scope_lifetimes
: Vec
::new(),
302 allow_try_trait
: Some([sym
::try_trait
][..].into()),
303 allow_gen_future
: Some([sym
::gen_future
][..].into()),
308 #[derive(Copy, Clone, PartialEq)]
310 /// Any path in a type context.
312 /// Path in a type definition, where the anonymous lifetime `'_` is not allowed.
314 /// The `module::Type` in `module::Type::method` in an expression.
318 enum ParenthesizedGenericArgs
{
323 /// What to do when we encounter an **anonymous** lifetime
324 /// reference. Anonymous lifetime references come in two flavors. You
325 /// have implicit, or fully elided, references to lifetimes, like the
326 /// one in `&T` or `Ref<T>`, and you have `'_` lifetimes, like `&'_ T`
327 /// or `Ref<'_, T>`. These often behave the same, but not always:
329 /// - certain usages of implicit references are deprecated, like
330 /// `Ref<T>`, and we sometimes just give hard errors in those cases
332 /// - for object bounds there is a difference: `Box<dyn Foo>` is not
333 /// the same as `Box<dyn Foo + '_>`.
335 /// We describe the effects of the various modes in terms of three cases:
337 /// - **Modern** -- includes all uses of `'_`, but also the lifetime arg
338 /// of a `&` (e.g., the missing lifetime in something like `&T`)
339 /// - **Dyn Bound** -- if you have something like `Box<dyn Foo>`,
340 /// there is an elided lifetime bound (`Box<dyn Foo + 'X>`). These
341 /// elided bounds follow special rules. Note that this only covers
342 /// cases where *nothing* is written; the `'_` in `Box<dyn Foo +
343 /// '_>` is a case of "modern" elision.
344 /// - **Deprecated** -- this coverse cases like `Ref<T>`, where the lifetime
345 /// parameter to ref is completely elided. `Ref<'_, T>` would be the modern,
346 /// non-deprecated equivalent.
348 /// Currently, the handling of lifetime elision is somewhat spread out
349 /// between HIR lowering and -- as described below -- the
350 /// `resolve_lifetime` module. Often we "fallthrough" to that code by generating
351 /// an "elided" or "underscore" lifetime name. In the future, we probably want to move
352 /// everything into HIR lowering.
353 #[derive(Copy, Clone, Debug)]
354 enum AnonymousLifetimeMode
{
355 /// For **Modern** cases, create a new anonymous region parameter
356 /// and reference that.
358 /// For **Dyn Bound** cases, pass responsibility to
359 /// `resolve_lifetime` code.
361 /// For **Deprecated** cases, report an error.
364 /// Give a hard error when either `&` or `'_` is written. Used to
365 /// rule out things like `where T: Foo<'_>`. Does not imply an
366 /// error on default object bounds (e.g., `Box<dyn Foo>`).
369 /// Pass responsibility to `resolve_lifetime` code for all cases.
373 struct ImplTraitTypeIdVisitor
<'a
> {
374 ids
: &'a
mut SmallVec
<[NodeId
; 1]>,
377 impl Visitor
<'_
> for ImplTraitTypeIdVisitor
<'_
> {
378 fn visit_ty(&mut self, ty
: &Ty
) {
380 TyKind
::Typeof(_
) | TyKind
::BareFn(_
) => return,
382 TyKind
::ImplTrait(id
, _
) => self.ids
.push(id
),
385 visit
::walk_ty(self, ty
);
388 fn visit_path_segment(&mut self, path_span
: Span
, path_segment
: &PathSegment
) {
389 if let Some(ref p
) = path_segment
.args
{
390 if let GenericArgs
::Parenthesized(_
) = **p
{
394 visit
::walk_path_segment(self, path_span
, path_segment
)
398 impl<'a
, 'hir
> LoweringContext
<'a
, 'hir
> {
399 fn lower_crate(mut self, c
: &Crate
) -> hir
::Crate
<'hir
> {
400 /// Full-crate AST visitor that inserts into a fresh
401 /// `LoweringContext` any information that may be
402 /// needed from arbitrary locations in the crate,
403 /// e.g., the number of lifetime generic parameters
404 /// declared for every type and trait definition.
405 struct MiscCollector
<'tcx
, 'lowering
, 'hir
> {
406 lctx
: &'tcx
mut LoweringContext
<'lowering
, 'hir
>,
407 hir_id_owner
: Option
<NodeId
>,
410 impl MiscCollector
<'_
, '_
, '_
> {
411 fn allocate_use_tree_hir_id_counters(&mut self, tree
: &UseTree
, owner
: LocalDefId
) {
413 UseTreeKind
::Simple(_
, id1
, id2
) => {
414 for &id
in &[id1
, id2
] {
415 self.lctx
.resolver
.definitions().create_def_with_parent(
422 self.lctx
.allocate_hir_id_counter(id
);
425 UseTreeKind
::Glob
=> (),
426 UseTreeKind
::Nested(ref trees
) => {
427 for &(ref use_tree
, id
) in trees
{
428 let hir_id
= self.lctx
.allocate_hir_id_counter(id
);
429 self.allocate_use_tree_hir_id_counters(use_tree
, hir_id
.owner
);
435 fn with_hir_id_owner
<T
>(
437 owner
: Option
<NodeId
>,
438 f
: impl FnOnce(&mut Self) -> T
,
440 let old
= mem
::replace(&mut self.hir_id_owner
, owner
);
442 self.hir_id_owner
= old
;
447 impl<'tcx
> Visitor
<'tcx
> for MiscCollector
<'tcx
, '_
, '_
> {
448 fn visit_pat(&mut self, p
: &'tcx Pat
) {
449 if let PatKind
::Paren(..) | PatKind
::Rest
= p
.kind
{
450 // Doesn't generate a HIR node
451 } else if let Some(owner
) = self.hir_id_owner
{
452 self.lctx
.lower_node_id_with_owner(p
.id
, owner
);
455 visit
::walk_pat(self, p
)
458 fn visit_item(&mut self, item
: &'tcx Item
) {
459 let hir_id
= self.lctx
.allocate_hir_id_counter(item
.id
);
462 ItemKind
::Struct(_
, ref generics
)
463 | ItemKind
::Union(_
, ref generics
)
464 | ItemKind
::Enum(_
, ref generics
)
465 | ItemKind
::TyAlias(_
, ref generics
, ..)
466 | ItemKind
::Trait(_
, _
, ref generics
, ..) => {
467 let def_id
= self.lctx
.resolver
.definitions().local_def_id(item
.id
);
471 .filter(|param
| match param
.kind
{
472 ast
::GenericParamKind
::Lifetime { .. }
=> true,
476 self.lctx
.type_def_lifetime_params
.insert(def_id
.to_def_id(), count
);
478 ItemKind
::Use(ref use_tree
) => {
479 self.allocate_use_tree_hir_id_counters(use_tree
, hir_id
.owner
);
484 self.with_hir_id_owner(Some(item
.id
), |this
| {
485 visit
::walk_item(this
, item
);
489 fn visit_assoc_item(&mut self, item
: &'tcx AssocItem
, ctxt
: AssocCtxt
) {
490 self.lctx
.allocate_hir_id_counter(item
.id
);
491 let owner
= match (&item
.kind
, ctxt
) {
492 // Ignore patterns in trait methods without bodies.
493 (AssocItemKind
::Fn(_
, _
, _
, None
), AssocCtxt
::Trait
) => None
,
496 self.with_hir_id_owner(owner
, |this
| visit
::walk_assoc_item(this
, item
, ctxt
));
499 fn visit_foreign_item(&mut self, i
: &'tcx ForeignItem
) {
500 // Ignore patterns in foreign items
501 self.with_hir_id_owner(None
, |this
| visit
::walk_foreign_item(this
, i
));
504 fn visit_ty(&mut self, t
: &'tcx Ty
) {
506 // Mirrors the case in visit::walk_ty
507 TyKind
::BareFn(ref f
) => {
508 walk_list
!(self, visit_generic_param
, &f
.generic_params
);
509 // Mirrors visit::walk_fn_decl
510 for parameter
in &f
.decl
.inputs
{
511 // We don't lower the ids of argument patterns
512 self.with_hir_id_owner(None
, |this
| {
513 this
.visit_pat(¶meter
.pat
);
515 self.visit_ty(¶meter
.ty
)
517 self.visit_fn_ret_ty(&f
.decl
.output
)
519 _
=> visit
::walk_ty(self, t
),
524 self.lower_node_id(CRATE_NODE_ID
);
525 debug_assert
!(self.node_id_to_hir_id
[CRATE_NODE_ID
] == Some(hir
::CRATE_HIR_ID
));
527 visit
::walk_crate(&mut MiscCollector { lctx: &mut self, hir_id_owner: None }
, c
);
528 visit
::walk_crate(&mut item
::ItemLowerer { lctx: &mut self }
, c
);
530 let module
= self.lower_mod(&c
.module
);
531 let attrs
= self.lower_attrs(&c
.attrs
);
532 let body_ids
= body_ids(&self.bodies
);
534 c
.proc_macros
.iter().map(|id
| self.node_id_to_hir_id
[*id
].unwrap()).collect();
536 self.resolver
.definitions().init_node_id_to_hir_id_mapping(self.node_id_to_hir_id
);
539 item
: hir
::CrateItem { module, attrs, span: c.span }
,
540 exported_macros
: self.arena
.alloc_from_iter(self.exported_macros
),
541 non_exported_macro_attrs
: self.arena
.alloc_from_iter(self.non_exported_macro_attrs
),
543 trait_items
: self.trait_items
,
544 impl_items
: self.impl_items
,
547 trait_impls
: self.trait_impls
,
548 modules
: self.modules
,
553 fn insert_item(&mut self, item
: hir
::Item
<'hir
>) {
554 let id
= item
.hir_id
;
555 // FIXME: Use `debug_asset-rt`.
556 assert_eq
!(id
.local_id
, hir
::ItemLocalId
::from_u32(0));
557 self.items
.insert(id
, item
);
558 self.modules
.get_mut(&self.current_module
).unwrap().items
.insert(id
);
561 fn allocate_hir_id_counter(&mut self, owner
: NodeId
) -> hir
::HirId
{
562 // Set up the counter if needed.
563 self.item_local_id_counters
.entry(owner
).or_insert(0);
564 // Always allocate the first `HirId` for the owner itself.
565 let lowered
= self.lower_node_id_with_owner(owner
, owner
);
566 debug_assert_eq
!(lowered
.local_id
.as_u32(), 0);
570 fn lower_node_id_generic(
573 alloc_hir_id
: impl FnOnce(&mut Self) -> hir
::HirId
,
575 assert_ne
!(ast_node_id
, DUMMY_NODE_ID
);
577 let min_size
= ast_node_id
.as_usize() + 1;
579 if min_size
> self.node_id_to_hir_id
.len() {
580 self.node_id_to_hir_id
.resize(min_size
, None
);
583 if let Some(existing_hir_id
) = self.node_id_to_hir_id
[ast_node_id
] {
586 // Generate a new `HirId`.
587 let hir_id
= alloc_hir_id(self);
588 self.node_id_to_hir_id
[ast_node_id
] = Some(hir_id
);
594 fn with_hir_id_owner
<T
>(&mut self, owner
: NodeId
, f
: impl FnOnce(&mut Self) -> T
) -> T
{
596 .item_local_id_counters
597 .insert(owner
, HIR_ID_COUNTER_LOCKED
)
598 .unwrap_or_else(|| panic
!("no `item_local_id_counters` entry for {:?}", owner
));
599 let def_id
= self.resolver
.definitions().local_def_id(owner
);
600 self.current_hir_id_owner
.push((def_id
, counter
));
602 let (new_def_id
, new_counter
) = self.current_hir_id_owner
.pop().unwrap();
604 debug_assert
!(def_id
== new_def_id
);
605 debug_assert
!(new_counter
>= counter
);
607 let prev
= self.item_local_id_counters
.insert(owner
, new_counter
).unwrap();
608 debug_assert
!(prev
== HIR_ID_COUNTER_LOCKED
);
612 /// This method allocates a new `HirId` for the given `NodeId` and stores it in
613 /// the `LoweringContext`'s `NodeId => HirId` map.
614 /// Take care not to call this method if the resulting `HirId` is then not
615 /// actually used in the HIR, as that would trigger an assertion in the
616 /// `HirIdValidator` later on, which makes sure that all `NodeId`s got mapped
617 /// properly. Calling the method twice with the same `NodeId` is fine though.
618 fn lower_node_id(&mut self, ast_node_id
: NodeId
) -> hir
::HirId
{
619 self.lower_node_id_generic(ast_node_id
, |this
| {
620 let &mut (owner
, ref mut local_id_counter
) =
621 this
.current_hir_id_owner
.last_mut().unwrap();
622 let local_id
= *local_id_counter
;
623 *local_id_counter
+= 1;
624 hir
::HirId { owner, local_id: hir::ItemLocalId::from_u32(local_id) }
628 fn lower_node_id_with_owner(&mut self, ast_node_id
: NodeId
, owner
: NodeId
) -> hir
::HirId
{
629 self.lower_node_id_generic(ast_node_id
, |this
| {
630 let local_id_counter
= this
631 .item_local_id_counters
633 .expect("called `lower_node_id_with_owner` before `allocate_hir_id_counter`");
634 let local_id
= *local_id_counter
;
636 // We want to be sure not to modify the counter in the map while it
637 // is also on the stack. Otherwise we'll get lost updates when writing
638 // back from the stack to the map.
639 debug_assert
!(local_id
!= HIR_ID_COUNTER_LOCKED
);
641 *local_id_counter
+= 1;
642 let owner
= this
.resolver
.definitions().opt_local_def_id(owner
).expect(
643 "you forgot to call `create_def_with_parent` or are lowering node-IDs \
644 that do not belong to the current owner",
647 hir
::HirId { owner, local_id: hir::ItemLocalId::from_u32(local_id) }
651 fn next_id(&mut self) -> hir
::HirId
{
652 let node_id
= self.resolver
.next_node_id();
653 self.lower_node_id(node_id
)
656 fn lower_res(&mut self, res
: Res
<NodeId
>) -> Res
{
658 self.lower_node_id_generic(id
, |_
| {
659 panic
!("expected `NodeId` to be lowered already for res {:#?}", res
);
664 fn expect_full_res(&mut self, id
: NodeId
) -> Res
<NodeId
> {
665 self.resolver
.get_partial_res(id
).map_or(Res
::Err
, |pr
| {
666 if pr
.unresolved_segments() != 0 {
667 panic
!("path not fully resolved: {:?}", pr
);
673 fn expect_full_res_from_use(&mut self, id
: NodeId
) -> impl Iterator
<Item
= Res
<NodeId
>> {
674 self.resolver
.get_import_res(id
).present_items()
677 fn diagnostic(&self) -> &rustc_errors
::Handler
{
678 self.sess
.diagnostic()
681 /// Reuses the span but adds information like the kind of the desugaring and features that are
682 /// allowed inside this span.
683 fn mark_span_with_reason(
685 reason
: DesugaringKind
,
687 allow_internal_unstable
: Option
<Lrc
<[Symbol
]>>,
689 span
.fresh_expansion(ExpnData
{
690 allow_internal_unstable
,
691 ..ExpnData
::default(ExpnKind
::Desugaring(reason
), span
, self.sess
.edition(), None
)
695 fn with_anonymous_lifetime_mode
<R
>(
697 anonymous_lifetime_mode
: AnonymousLifetimeMode
,
698 op
: impl FnOnce(&mut Self) -> R
,
701 "with_anonymous_lifetime_mode(anonymous_lifetime_mode={:?})",
702 anonymous_lifetime_mode
,
704 let old_anonymous_lifetime_mode
= self.anonymous_lifetime_mode
;
705 self.anonymous_lifetime_mode
= anonymous_lifetime_mode
;
706 let result
= op(self);
707 self.anonymous_lifetime_mode
= old_anonymous_lifetime_mode
;
709 "with_anonymous_lifetime_mode: restoring anonymous_lifetime_mode={:?}",
710 old_anonymous_lifetime_mode
715 /// Creates a new `hir::GenericParam` for every new lifetime and
716 /// type parameter encountered while evaluating `f`. Definitions
717 /// are created with the parent provided. If no `parent_id` is
718 /// provided, no definitions will be returned.
720 /// Presuming that in-band lifetimes are enabled, then
721 /// `self.anonymous_lifetime_mode` will be updated to match the
722 /// parameter while `f` is running (and restored afterwards).
723 fn collect_in_band_defs
<T
>(
725 parent_def_id
: LocalDefId
,
726 anonymous_lifetime_mode
: AnonymousLifetimeMode
,
727 f
: impl FnOnce(&mut Self) -> (Vec
<hir
::GenericParam
<'hir
>>, T
),
728 ) -> (Vec
<hir
::GenericParam
<'hir
>>, T
) {
729 assert
!(!self.is_collecting_in_band_lifetimes
);
730 assert
!(self.lifetimes_to_define
.is_empty());
731 let old_anonymous_lifetime_mode
= self.anonymous_lifetime_mode
;
733 self.anonymous_lifetime_mode
= anonymous_lifetime_mode
;
734 self.is_collecting_in_band_lifetimes
= true;
736 let (in_band_ty_params
, res
) = f(self);
738 self.is_collecting_in_band_lifetimes
= false;
739 self.anonymous_lifetime_mode
= old_anonymous_lifetime_mode
;
741 let lifetimes_to_define
= self.lifetimes_to_define
.split_off(0);
743 let params
= lifetimes_to_define
745 .map(|(span
, hir_name
)| self.lifetime_to_generic_param(span
, hir_name
, parent_def_id
))
746 .chain(in_band_ty_params
.into_iter())
752 /// Converts a lifetime into a new generic parameter.
753 fn lifetime_to_generic_param(
757 parent_def_id
: LocalDefId
,
758 ) -> hir
::GenericParam
<'hir
> {
759 let node_id
= self.resolver
.next_node_id();
761 // Get the name we'll use to make the def-path. Note
762 // that collisions are ok here and this shouldn't
763 // really show up for end-user.
764 let (str_name
, kind
) = match hir_name
{
765 ParamName
::Plain(ident
) => (ident
.name
, hir
::LifetimeParamKind
::InBand
),
766 ParamName
::Fresh(_
) => (kw
::UnderscoreLifetime
, hir
::LifetimeParamKind
::Elided
),
767 ParamName
::Error
=> (kw
::UnderscoreLifetime
, hir
::LifetimeParamKind
::Error
),
770 // Add a definition for the in-band lifetime def.
771 self.resolver
.definitions().create_def_with_parent(
774 DefPathData
::LifetimeNs(str_name
),
780 hir_id
: self.lower_node_id(node_id
),
785 pure_wrt_drop
: false,
786 kind
: hir
::GenericParamKind
::Lifetime { kind }
,
790 /// When there is a reference to some lifetime `'a`, and in-band
791 /// lifetimes are enabled, then we want to push that lifetime into
792 /// the vector of names to define later. In that case, it will get
793 /// added to the appropriate generics.
794 fn maybe_collect_in_band_lifetime(&mut self, ident
: Ident
) {
795 if !self.is_collecting_in_band_lifetimes
{
799 if !self.sess
.features_untracked().in_band_lifetimes
{
803 if self.in_scope_lifetimes
.contains(&ParamName
::Plain(ident
.normalize_to_macros_2_0())) {
807 let hir_name
= ParamName
::Plain(ident
);
809 if self.lifetimes_to_define
.iter().any(|(_
, lt_name
)| {
810 lt_name
.normalize_to_macros_2_0() == hir_name
.normalize_to_macros_2_0()
815 self.lifetimes_to_define
.push((ident
.span
, hir_name
));
818 /// When we have either an elided or `'_` lifetime in an impl
819 /// header, we convert it to an in-band lifetime.
820 fn collect_fresh_in_band_lifetime(&mut self, span
: Span
) -> ParamName
{
821 assert
!(self.is_collecting_in_band_lifetimes
);
822 let index
= self.lifetimes_to_define
.len() + self.in_scope_lifetimes
.len();
823 let hir_name
= ParamName
::Fresh(index
);
824 self.lifetimes_to_define
.push((span
, hir_name
));
828 // Evaluates `f` with the lifetimes in `params` in-scope.
829 // This is used to track which lifetimes have already been defined, and
830 // which are new in-band lifetimes that need to have a definition created
832 fn with_in_scope_lifetime_defs
<T
>(
834 params
: &[GenericParam
],
835 f
: impl FnOnce(&mut Self) -> T
,
837 let old_len
= self.in_scope_lifetimes
.len();
838 let lt_def_names
= params
.iter().filter_map(|param
| match param
.kind
{
839 GenericParamKind
::Lifetime { .. }
=> {
840 Some(ParamName
::Plain(param
.ident
.normalize_to_macros_2_0()))
844 self.in_scope_lifetimes
.extend(lt_def_names
);
848 self.in_scope_lifetimes
.truncate(old_len
);
852 /// Appends in-band lifetime defs and argument-position `impl
853 /// Trait` defs to the existing set of generics.
855 /// Presuming that in-band lifetimes are enabled, then
856 /// `self.anonymous_lifetime_mode` will be updated to match the
857 /// parameter while `f` is running (and restored afterwards).
858 fn add_in_band_defs
<T
>(
861 parent_def_id
: LocalDefId
,
862 anonymous_lifetime_mode
: AnonymousLifetimeMode
,
863 f
: impl FnOnce(&mut Self, &mut Vec
<hir
::GenericParam
<'hir
>>) -> T
,
864 ) -> (hir
::Generics
<'hir
>, T
) {
865 let (in_band_defs
, (mut lowered_generics
, res
)) =
866 self.with_in_scope_lifetime_defs(&generics
.params
, |this
| {
867 this
.collect_in_band_defs(parent_def_id
, anonymous_lifetime_mode
, |this
| {
868 let mut params
= Vec
::new();
869 // Note: it is necessary to lower generics *before* calling `f`.
870 // When lowering `async fn`, there's a final step when lowering
871 // the return type that assumes that all in-scope lifetimes have
872 // already been added to either `in_scope_lifetimes` or
873 // `lifetimes_to_define`. If we swapped the order of these two,
874 // in-band-lifetimes introduced by generics or where-clauses
875 // wouldn't have been added yet.
877 this
.lower_generics_mut(generics
, ImplTraitContext
::Universal(&mut params
));
878 let res
= f(this
, &mut params
);
879 (params
, (generics
, res
))
883 let mut lowered_params
: Vec
<_
> =
884 lowered_generics
.params
.into_iter().chain(in_band_defs
).collect();
886 // FIXME(const_generics): the compiler doesn't always cope with
887 // unsorted generic parameters at the moment, so we make sure
888 // that they're ordered correctly here for now. (When we chain
889 // the `in_band_defs`, we might make the order unsorted.)
890 lowered_params
.sort_by_key(|param
| match param
.kind
{
891 hir
::GenericParamKind
::Lifetime { .. }
=> ParamKindOrd
::Lifetime
,
892 hir
::GenericParamKind
::Type { .. }
=> ParamKindOrd
::Type
,
893 hir
::GenericParamKind
::Const { .. }
=> ParamKindOrd
::Const
,
896 lowered_generics
.params
= lowered_params
.into();
898 let lowered_generics
= lowered_generics
.into_generics(self.arena
);
899 (lowered_generics
, res
)
902 fn with_dyn_type_scope
<T
>(&mut self, in_scope
: bool
, f
: impl FnOnce(&mut Self) -> T
) -> T
{
903 let was_in_dyn_type
= self.is_in_dyn_type
;
904 self.is_in_dyn_type
= in_scope
;
906 let result
= f(self);
908 self.is_in_dyn_type
= was_in_dyn_type
;
913 fn with_new_scopes
<T
>(&mut self, f
: impl FnOnce(&mut Self) -> T
) -> T
{
914 let was_in_loop_condition
= self.is_in_loop_condition
;
915 self.is_in_loop_condition
= false;
917 let catch_scopes
= mem
::take(&mut self.catch_scopes
);
918 let loop_scopes
= mem
::take(&mut self.loop_scopes
);
920 self.catch_scopes
= catch_scopes
;
921 self.loop_scopes
= loop_scopes
;
923 self.is_in_loop_condition
= was_in_loop_condition
;
928 fn lower_attrs(&mut self, attrs
: &[Attribute
]) -> &'hir
[Attribute
] {
929 self.arena
.alloc_from_iter(attrs
.iter().map(|a
| self.lower_attr(a
)))
932 fn lower_attr(&mut 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 let kind
= match attr
.kind
{
937 AttrKind
::Normal(ref item
) => AttrKind
::Normal(AttrItem
{
938 path
: item
.path
.clone(),
939 args
: self.lower_mac_args(&item
.args
),
941 AttrKind
::DocComment(comment
) => AttrKind
::DocComment(comment
),
944 Attribute { kind, id: attr.id, style: attr.style, span: attr.span }
947 fn lower_mac_args(&mut self, args
: &MacArgs
) -> MacArgs
{
949 MacArgs
::Empty
=> MacArgs
::Empty
,
950 MacArgs
::Delimited(dspan
, delim
, ref tokens
) => {
951 MacArgs
::Delimited(dspan
, delim
, self.lower_token_stream(tokens
.clone()))
953 MacArgs
::Eq(eq_span
, ref tokens
) => {
954 MacArgs
::Eq(eq_span
, self.lower_token_stream(tokens
.clone()))
959 fn lower_token_stream(&mut self, tokens
: TokenStream
) -> TokenStream
{
960 tokens
.into_trees().flat_map(|tree
| self.lower_token_tree(tree
).into_trees()).collect()
963 fn lower_token_tree(&mut self, tree
: TokenTree
) -> TokenStream
{
965 TokenTree
::Token(token
) => self.lower_token(token
),
966 TokenTree
::Delimited(span
, delim
, tts
) => {
967 TokenTree
::Delimited(span
, delim
, self.lower_token_stream(tts
)).into()
972 fn lower_token(&mut self, token
: Token
) -> TokenStream
{
974 token
::Interpolated(nt
) => {
975 let tts
= (self.nt_to_tokenstream
)(&nt
, &self.sess
.parse_sess
, token
.span
);
976 self.lower_token_stream(tts
)
978 _
=> TokenTree
::Token(token
).into(),
982 /// Given an associated type constraint like one of these:
985 /// T: Iterator<Item: Debug>
987 /// T: Iterator<Item = Debug>
991 /// returns a `hir::TypeBinding` representing `Item`.
992 fn lower_assoc_ty_constraint(
994 constraint
: &AssocTyConstraint
,
995 itctx
: ImplTraitContext
<'_
, 'hir
>,
996 ) -> hir
::TypeBinding
<'hir
> {
997 debug
!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint
, itctx
);
999 let kind
= match constraint
.kind
{
1000 AssocTyConstraintKind
::Equality { ref ty }
=> {
1001 hir
::TypeBindingKind
::Equality { ty: self.lower_ty(ty, itctx) }
1003 AssocTyConstraintKind
::Bound { ref bounds }
=> {
1004 // Piggy-back on the `impl Trait` context to figure out the correct behavior.
1005 let (desugar_to_impl_trait
, itctx
) = match itctx
{
1006 // We are in the return position:
1008 // fn foo() -> impl Iterator<Item: Debug>
1012 // fn foo() -> impl Iterator<Item = impl Debug>
1013 ImplTraitContext
::OpaqueTy(..) => (true, itctx
),
1015 // We are in the argument position, but within a dyn type:
1017 // fn foo(x: dyn Iterator<Item: Debug>)
1021 // fn foo(x: dyn Iterator<Item = impl Debug>)
1022 ImplTraitContext
::Universal(..) if self.is_in_dyn_type
=> (true, itctx
),
1024 // In `type Foo = dyn Iterator<Item: Debug>` we desugar to
1025 // `type Foo = dyn Iterator<Item = impl Debug>` but we have to override the
1026 // "impl trait context" to permit `impl Debug` in this position (it desugars
1027 // then to an opaque type).
1029 // FIXME: this is only needed until `impl Trait` is allowed in type aliases.
1030 ImplTraitContext
::Disallowed(_
) if self.is_in_dyn_type
=> {
1031 (true, ImplTraitContext
::OpaqueTy(None
, hir
::OpaqueTyOrigin
::Misc
))
1034 // We are in the parameter position, but not within a dyn type:
1036 // fn foo(x: impl Iterator<Item: Debug>)
1038 // so we leave it as is and this gets expanded in astconv to a bound like
1039 // `<T as Iterator>::Item: Debug` where `T` is the type parameter for the
1041 _
=> (false, itctx
),
1044 if desugar_to_impl_trait
{
1045 // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by
1046 // constructing the HIR for `impl bounds...` and then lowering that.
1048 let impl_trait_node_id
= self.resolver
.next_node_id();
1049 let parent_def_id
= self.current_hir_id_owner
.last().unwrap().0;
1050 self.resolver
.definitions().create_def_with_parent(
1053 DefPathData
::ImplTrait
,
1058 self.with_dyn_type_scope(false, |this
| {
1059 let node_id
= this
.resolver
.next_node_id();
1060 let ty
= this
.lower_ty(
1063 kind
: TyKind
::ImplTrait(impl_trait_node_id
, bounds
.clone()),
1064 span
: constraint
.span
,
1069 hir
::TypeBindingKind
::Equality { ty }
1072 // Desugar `AssocTy: Bounds` into a type binding where the
1073 // later desugars into a trait predicate.
1074 let bounds
= self.lower_param_bounds(bounds
, itctx
);
1076 hir
::TypeBindingKind
::Constraint { bounds }
1082 hir_id
: self.lower_node_id(constraint
.id
),
1083 ident
: constraint
.ident
,
1085 span
: constraint
.span
,
1089 fn lower_generic_arg(
1091 arg
: &ast
::GenericArg
,
1092 itctx
: ImplTraitContext
<'_
, 'hir
>,
1093 ) -> hir
::GenericArg
<'hir
> {
1095 ast
::GenericArg
::Lifetime(lt
) => GenericArg
::Lifetime(self.lower_lifetime(<
)),
1096 ast
::GenericArg
::Type(ty
) => {
1097 // We parse const arguments as path types as we cannot distinguish them during
1098 // parsing. We try to resolve that ambiguity by attempting resolution in both the
1099 // type and value namespaces. If we resolved the path in the value namespace, we
1100 // transform it into a generic const argument.
1101 if let TyKind
::Path(ref qself
, ref path
) = ty
.kind
{
1102 if let Some(partial_res
) = self.resolver
.get_partial_res(ty
.id
) {
1103 let res
= partial_res
.base_res();
1104 if !res
.matches_ns(Namespace
::TypeNS
) {
1106 "lower_generic_arg: Lowering type argument as const argument: {:?}",
1110 // Construct a AnonConst where the expr is the "ty"'s path.
1112 let parent_def_id
= self.current_hir_id_owner
.last().unwrap().0;
1113 let node_id
= self.resolver
.next_node_id();
1115 // Add a definition for the in-band const def.
1116 self.resolver
.definitions().create_def_with_parent(
1119 DefPathData
::AnonConst
,
1124 let path_expr
= Expr
{
1126 kind
: ExprKind
::Path(qself
.clone(), path
.clone()),
1128 attrs
: AttrVec
::new(),
1132 let ct
= self.with_new_scopes(|this
| hir
::AnonConst
{
1133 hir_id
: this
.lower_node_id(node_id
),
1134 body
: this
.lower_const_body(path_expr
.span
, Some(&path_expr
)),
1136 return GenericArg
::Const(ConstArg { value: ct, span: ty.span }
);
1140 GenericArg
::Type(self.lower_ty_direct(&ty
, itctx
))
1142 ast
::GenericArg
::Const(ct
) => GenericArg
::Const(ConstArg
{
1143 value
: self.lower_anon_const(&ct
),
1144 span
: ct
.value
.span
,
1149 fn lower_ty(&mut self, t
: &Ty
, itctx
: ImplTraitContext
<'_
, 'hir
>) -> &'hir hir
::Ty
<'hir
> {
1150 self.arena
.alloc(self.lower_ty_direct(t
, itctx
))
1156 qself
: &Option
<QSelf
>,
1158 param_mode
: ParamMode
,
1159 itctx
: ImplTraitContext
<'_
, 'hir
>,
1160 ) -> hir
::Ty
<'hir
> {
1161 let id
= self.lower_node_id(t
.id
);
1162 let qpath
= self.lower_qpath(t
.id
, qself
, path
, param_mode
, itctx
);
1163 let ty
= self.ty_path(id
, t
.span
, qpath
);
1164 if let hir
::TyKind
::TraitObject(..) = ty
.kind
{
1165 self.maybe_lint_bare_trait(t
.span
, t
.id
, qself
.is_none() && path
.is_global());
1170 fn ty(&mut self, span
: Span
, kind
: hir
::TyKind
<'hir
>) -> hir
::Ty
<'hir
> {
1171 hir
::Ty { hir_id: self.next_id(), kind, span }
1174 fn ty_tup(&mut self, span
: Span
, tys
: &'hir
[hir
::Ty
<'hir
>]) -> hir
::Ty
<'hir
> {
1175 self.ty(span
, hir
::TyKind
::Tup(tys
))
1178 fn lower_ty_direct(&mut self, t
: &Ty
, mut itctx
: ImplTraitContext
<'_
, 'hir
>) -> hir
::Ty
<'hir
> {
1179 let kind
= match t
.kind
{
1180 TyKind
::Infer
=> hir
::TyKind
::Infer
,
1181 TyKind
::Err
=> hir
::TyKind
::Err
,
1182 TyKind
::Slice(ref ty
) => hir
::TyKind
::Slice(self.lower_ty(ty
, itctx
)),
1183 TyKind
::Ptr(ref mt
) => hir
::TyKind
::Ptr(self.lower_mt(mt
, itctx
)),
1184 TyKind
::Rptr(ref region
, ref mt
) => {
1185 let span
= self.sess
.source_map().next_point(t
.span
.shrink_to_lo());
1186 let lifetime
= match *region
{
1187 Some(ref lt
) => self.lower_lifetime(lt
),
1188 None
=> self.elided_ref_lifetime(span
),
1190 hir
::TyKind
::Rptr(lifetime
, self.lower_mt(mt
, itctx
))
1192 TyKind
::BareFn(ref f
) => self.with_in_scope_lifetime_defs(&f
.generic_params
, |this
| {
1193 this
.with_anonymous_lifetime_mode(AnonymousLifetimeMode
::PassThrough
, |this
| {
1194 hir
::TyKind
::BareFn(this
.arena
.alloc(hir
::BareFnTy
{
1195 generic_params
: this
.lower_generic_params(
1197 &NodeMap
::default(),
1198 ImplTraitContext
::disallowed(),
1200 unsafety
: this
.lower_unsafety(f
.unsafety
),
1201 abi
: this
.lower_extern(f
.ext
),
1202 decl
: this
.lower_fn_decl(&f
.decl
, None
, false, None
),
1203 param_names
: this
.lower_fn_params_to_names(&f
.decl
),
1207 TyKind
::Never
=> hir
::TyKind
::Never
,
1208 TyKind
::Tup(ref tys
) => {
1209 hir
::TyKind
::Tup(self.arena
.alloc_from_iter(
1210 tys
.iter().map(|ty
| self.lower_ty_direct(ty
, itctx
.reborrow())),
1213 TyKind
::Paren(ref ty
) => {
1214 return self.lower_ty_direct(ty
, itctx
);
1216 TyKind
::Path(ref qself
, ref path
) => {
1217 return self.lower_path_ty(t
, qself
, path
, ParamMode
::Explicit
, itctx
);
1219 TyKind
::ImplicitSelf
=> {
1220 let res
= self.expect_full_res(t
.id
);
1221 let res
= self.lower_res(res
);
1222 hir
::TyKind
::Path(hir
::QPath
::Resolved(
1224 self.arena
.alloc(hir
::Path
{
1226 segments
: arena_vec
![self; hir
::PathSegment
::from_ident(
1227 Ident
::with_dummy_span(kw
::SelfUpper
)
1233 TyKind
::Array(ref ty
, ref length
) => {
1234 hir
::TyKind
::Array(self.lower_ty(ty
, itctx
), self.lower_anon_const(length
))
1236 TyKind
::Typeof(ref expr
) => hir
::TyKind
::Typeof(self.lower_anon_const(expr
)),
1237 TyKind
::TraitObject(ref bounds
, kind
) => {
1238 let mut lifetime_bound
= None
;
1239 let (bounds
, lifetime_bound
) = self.with_dyn_type_scope(true, |this
| {
1241 this
.arena
.alloc_from_iter(bounds
.iter().filter_map(
1242 |bound
| match *bound
{
1243 GenericBound
::Trait(
1245 TraitBoundModifier
::None
| TraitBoundModifier
::MaybeConst
,
1246 ) => Some(this
.lower_poly_trait_ref(ty
, itctx
.reborrow())),
1247 // `?const ?Bound` will cause an error during AST validation
1248 // anyways, so treat it like `?Bound` as compilation proceeds.
1249 GenericBound
::Trait(
1251 TraitBoundModifier
::Maybe
| TraitBoundModifier
::MaybeConstMaybe
,
1253 GenericBound
::Outlives(ref lifetime
) => {
1254 if lifetime_bound
.is_none() {
1255 lifetime_bound
= Some(this
.lower_lifetime(lifetime
));
1261 let lifetime_bound
=
1262 lifetime_bound
.unwrap_or_else(|| this
.elided_dyn_bound(t
.span
));
1263 (bounds
, lifetime_bound
)
1265 if kind
!= TraitObjectSyntax
::Dyn
{
1266 self.maybe_lint_bare_trait(t
.span
, t
.id
, false);
1268 hir
::TyKind
::TraitObject(bounds
, lifetime_bound
)
1270 TyKind
::ImplTrait(def_node_id
, ref bounds
) => {
1273 ImplTraitContext
::OpaqueTy(fn_def_id
, origin
) => {
1274 self.lower_opaque_impl_trait(span
, fn_def_id
, origin
, def_node_id
, |this
| {
1275 this
.lower_param_bounds(bounds
, itctx
)
1278 ImplTraitContext
::Universal(in_band_ty_params
) => {
1279 // Add a definition for the in-band `Param`.
1280 let def_id
= self.resolver
.definitions().local_def_id(def_node_id
);
1282 let hir_bounds
= self.lower_param_bounds(
1284 ImplTraitContext
::Universal(in_band_ty_params
),
1286 // Set the name to `impl Bound1 + Bound2`.
1287 let ident
= Ident
::from_str_and_span(&pprust
::ty_to_string(t
), span
);
1288 in_band_ty_params
.push(hir
::GenericParam
{
1289 hir_id
: self.lower_node_id(def_node_id
),
1290 name
: ParamName
::Plain(ident
),
1291 pure_wrt_drop
: false,
1295 kind
: hir
::GenericParamKind
::Type
{
1297 synthetic
: Some(hir
::SyntheticTyParamKind
::ImplTrait
),
1301 hir
::TyKind
::Path(hir
::QPath
::Resolved(
1303 self.arena
.alloc(hir
::Path
{
1305 res
: Res
::Def(DefKind
::TyParam
, def_id
.to_def_id()),
1306 segments
: arena_vec
![self; hir
::PathSegment
::from_ident(ident
)],
1310 ImplTraitContext
::Disallowed(pos
) => {
1311 let allowed_in
= if self.sess
.features_untracked().impl_trait_in_bindings
{
1312 "bindings or function and inherent method return types"
1314 "function and inherent method return types"
1316 let mut err
= struct_span_err
!(
1320 "`impl Trait` not allowed outside of {}",
1323 if pos
== ImplTraitPosition
::Binding
&& nightly_options
::is_nightly_build()
1326 "add `#![feature(impl_trait_in_bindings)]` to the crate \
1327 attributes to enable",
1335 TyKind
::MacCall(_
) => panic
!("`TyKind::MacCall` should have been expanded by now"),
1336 TyKind
::CVarArgs
=> {
1337 self.sess
.delay_span_bug(
1339 "`TyKind::CVarArgs` should have been handled elsewhere",
1345 hir
::Ty { kind, span: t.span, hir_id: self.lower_node_id(t.id) }
1348 fn lower_opaque_impl_trait(
1351 fn_def_id
: Option
<DefId
>,
1352 origin
: hir
::OpaqueTyOrigin
,
1353 opaque_ty_node_id
: NodeId
,
1354 lower_bounds
: impl FnOnce(&mut Self) -> hir
::GenericBounds
<'hir
>,
1355 ) -> hir
::TyKind
<'hir
> {
1357 "lower_opaque_impl_trait(fn_def_id={:?}, opaque_ty_node_id={:?}, span={:?})",
1358 fn_def_id
, opaque_ty_node_id
, span
,
1361 // Make sure we know that some funky desugaring has been going on here.
1362 // This is a first: there is code in other places like for loop
1363 // desugaring that explicitly states that we don't want to track that.
1364 // Not tracking it makes lints in rustc and clippy very fragile, as
1365 // frequently opened issues show.
1366 let opaque_ty_span
= self.mark_span_with_reason(DesugaringKind
::OpaqueTy
, span
, None
);
1368 let opaque_ty_def_id
= self.resolver
.definitions().local_def_id(opaque_ty_node_id
);
1370 self.allocate_hir_id_counter(opaque_ty_node_id
);
1372 let hir_bounds
= self.with_hir_id_owner(opaque_ty_node_id
, lower_bounds
);
1374 let (lifetimes
, lifetime_defs
) =
1375 self.lifetimes_from_impl_trait_bounds(opaque_ty_node_id
, opaque_ty_def_id
, &hir_bounds
);
1377 debug
!("lower_opaque_impl_trait: lifetimes={:#?}", lifetimes
,);
1379 debug
!("lower_opaque_impl_trait: lifetime_defs={:#?}", lifetime_defs
,);
1381 self.with_hir_id_owner(opaque_ty_node_id
, move |lctx
| {
1382 let opaque_ty_item
= hir
::OpaqueTy
{
1383 generics
: hir
::Generics
{
1384 params
: lifetime_defs
,
1385 where_clause
: hir
::WhereClause { predicates: &[], span }
,
1389 impl_trait_fn
: fn_def_id
,
1393 trace
!("lower_opaque_impl_trait: {:#?}", opaque_ty_def_id
);
1395 lctx
.generate_opaque_type(opaque_ty_node_id
, opaque_ty_item
, span
, opaque_ty_span
);
1397 // `impl Trait` now just becomes `Foo<'a, 'b, ..>`.
1398 hir
::TyKind
::Def(hir
::ItemId { id: opaque_ty_id }
, lifetimes
)
1402 /// Registers a new opaque type with the proper `NodeId`s and
1403 /// returns the lowered node-ID for the opaque type.
1404 fn generate_opaque_type(
1406 opaque_ty_node_id
: NodeId
,
1407 opaque_ty_item
: hir
::OpaqueTy
<'hir
>,
1409 opaque_ty_span
: Span
,
1411 let opaque_ty_item_kind
= hir
::ItemKind
::OpaqueTy(opaque_ty_item
);
1412 let opaque_ty_id
= self.lower_node_id(opaque_ty_node_id
);
1413 // Generate an `type Foo = impl Trait;` declaration.
1414 trace
!("registering opaque type with id {:#?}", opaque_ty_id
);
1415 let opaque_ty_item
= hir
::Item
{
1416 hir_id
: opaque_ty_id
,
1417 ident
: Ident
::invalid(),
1418 attrs
: Default
::default(),
1419 kind
: opaque_ty_item_kind
,
1420 vis
: respan(span
.shrink_to_lo(), hir
::VisibilityKind
::Inherited
),
1421 span
: opaque_ty_span
,
1424 // Insert the item into the global item list. This usually happens
1425 // automatically for all AST items. But this opaque type item
1426 // does not actually exist in the AST.
1427 self.insert_item(opaque_ty_item
);
1431 fn lifetimes_from_impl_trait_bounds(
1433 opaque_ty_id
: NodeId
,
1434 parent_def_id
: LocalDefId
,
1435 bounds
: hir
::GenericBounds
<'hir
>,
1436 ) -> (&'hir
[hir
::GenericArg
<'hir
>], &'hir
[hir
::GenericParam
<'hir
>]) {
1438 "lifetimes_from_impl_trait_bounds(opaque_ty_id={:?}, \
1439 parent_def_id={:?}, \
1441 opaque_ty_id
, parent_def_id
, bounds
,
1444 // This visitor walks over `impl Trait` bounds and creates defs for all lifetimes that
1445 // appear in the bounds, excluding lifetimes that are created within the bounds.
1446 // E.g., `'a`, `'b`, but not `'c` in `impl for<'c> SomeTrait<'a, 'b, 'c>`.
1447 struct ImplTraitLifetimeCollector
<'r
, 'a
, 'hir
> {
1448 context
: &'r
mut LoweringContext
<'a
, 'hir
>,
1450 opaque_ty_id
: NodeId
,
1451 collect_elided_lifetimes
: bool
,
1452 currently_bound_lifetimes
: Vec
<hir
::LifetimeName
>,
1453 already_defined_lifetimes
: FxHashSet
<hir
::LifetimeName
>,
1454 output_lifetimes
: Vec
<hir
::GenericArg
<'hir
>>,
1455 output_lifetime_params
: Vec
<hir
::GenericParam
<'hir
>>,
1458 impl<'r
, 'a
, 'v
, 'hir
> intravisit
::Visitor
<'v
> for ImplTraitLifetimeCollector
<'r
, 'a
, 'hir
> {
1459 type Map
= intravisit
::ErasedMap
<'v
>;
1461 fn nested_visit_map(&mut self) -> intravisit
::NestedVisitorMap
<Self::Map
> {
1462 intravisit
::NestedVisitorMap
::None
1465 fn visit_generic_args(&mut self, span
: Span
, parameters
: &'v hir
::GenericArgs
<'v
>) {
1466 // Don't collect elided lifetimes used inside of `Fn()` syntax.
1467 if parameters
.parenthesized
{
1468 let old_collect_elided_lifetimes
= self.collect_elided_lifetimes
;
1469 self.collect_elided_lifetimes
= false;
1470 intravisit
::walk_generic_args(self, span
, parameters
);
1471 self.collect_elided_lifetimes
= old_collect_elided_lifetimes
;
1473 intravisit
::walk_generic_args(self, span
, parameters
);
1477 fn visit_ty(&mut self, t
: &'v hir
::Ty
<'v
>) {
1478 // Don't collect elided lifetimes used inside of `fn()` syntax.
1479 if let hir
::TyKind
::BareFn(_
) = t
.kind
{
1480 let old_collect_elided_lifetimes
= self.collect_elided_lifetimes
;
1481 self.collect_elided_lifetimes
= false;
1483 // Record the "stack height" of `for<'a>` lifetime bindings
1484 // to be able to later fully undo their introduction.
1485 let old_len
= self.currently_bound_lifetimes
.len();
1486 intravisit
::walk_ty(self, t
);
1487 self.currently_bound_lifetimes
.truncate(old_len
);
1489 self.collect_elided_lifetimes
= old_collect_elided_lifetimes
;
1491 intravisit
::walk_ty(self, t
)
1495 fn visit_poly_trait_ref(
1497 trait_ref
: &'v hir
::PolyTraitRef
<'v
>,
1498 modifier
: hir
::TraitBoundModifier
,
1500 // Record the "stack height" of `for<'a>` lifetime bindings
1501 // to be able to later fully undo their introduction.
1502 let old_len
= self.currently_bound_lifetimes
.len();
1503 intravisit
::walk_poly_trait_ref(self, trait_ref
, modifier
);
1504 self.currently_bound_lifetimes
.truncate(old_len
);
1507 fn visit_generic_param(&mut self, param
: &'v hir
::GenericParam
<'v
>) {
1508 // Record the introduction of 'a in `for<'a> ...`.
1509 if let hir
::GenericParamKind
::Lifetime { .. }
= param
.kind
{
1510 // Introduce lifetimes one at a time so that we can handle
1511 // cases like `fn foo<'d>() -> impl for<'a, 'b: 'a, 'c: 'b + 'd>`.
1512 let lt_name
= hir
::LifetimeName
::Param(param
.name
);
1513 self.currently_bound_lifetimes
.push(lt_name
);
1516 intravisit
::walk_generic_param(self, param
);
1519 fn visit_lifetime(&mut self, lifetime
: &'v hir
::Lifetime
) {
1520 let name
= match lifetime
.name
{
1521 hir
::LifetimeName
::Implicit
| hir
::LifetimeName
::Underscore
=> {
1522 if self.collect_elided_lifetimes
{
1523 // Use `'_` for both implicit and underscore lifetimes in
1524 // `type Foo<'_> = impl SomeTrait<'_>;`.
1525 hir
::LifetimeName
::Underscore
1530 hir
::LifetimeName
::Param(_
) => lifetime
.name
,
1532 // Refers to some other lifetime that is "in
1533 // scope" within the type.
1534 hir
::LifetimeName
::ImplicitObjectLifetimeDefault
=> return,
1536 hir
::LifetimeName
::Error
| hir
::LifetimeName
::Static
=> return,
1539 if !self.currently_bound_lifetimes
.contains(&name
)
1540 && !self.already_defined_lifetimes
.contains(&name
)
1542 self.already_defined_lifetimes
.insert(name
);
1544 self.output_lifetimes
.push(hir
::GenericArg
::Lifetime(hir
::Lifetime
{
1545 hir_id
: self.context
.next_id(),
1546 span
: lifetime
.span
,
1550 let def_node_id
= self.context
.resolver
.next_node_id();
1552 self.context
.lower_node_id_with_owner(def_node_id
, self.opaque_ty_id
);
1553 self.context
.resolver
.definitions().create_def_with_parent(
1556 DefPathData
::LifetimeNs(name
.ident().name
),
1561 let (name
, kind
) = match name
{
1562 hir
::LifetimeName
::Underscore
=> (
1563 hir
::ParamName
::Plain(Ident
::with_dummy_span(kw
::UnderscoreLifetime
)),
1564 hir
::LifetimeParamKind
::Elided
,
1566 hir
::LifetimeName
::Param(param_name
) => {
1567 (param_name
, hir
::LifetimeParamKind
::Explicit
)
1569 _
=> panic
!("expected `LifetimeName::Param` or `ParamName::Plain`"),
1572 self.output_lifetime_params
.push(hir
::GenericParam
{
1575 span
: lifetime
.span
,
1576 pure_wrt_drop
: false,
1579 kind
: hir
::GenericParamKind
::Lifetime { kind }
,
1585 let mut lifetime_collector
= ImplTraitLifetimeCollector
{
1587 parent
: parent_def_id
,
1589 collect_elided_lifetimes
: true,
1590 currently_bound_lifetimes
: Vec
::new(),
1591 already_defined_lifetimes
: FxHashSet
::default(),
1592 output_lifetimes
: Vec
::new(),
1593 output_lifetime_params
: Vec
::new(),
1596 for bound
in bounds
{
1597 intravisit
::walk_param_bound(&mut lifetime_collector
, &bound
);
1600 let ImplTraitLifetimeCollector { output_lifetimes, output_lifetime_params, .. }
=
1604 self.arena
.alloc_from_iter(output_lifetimes
),
1605 self.arena
.alloc_from_iter(output_lifetime_params
),
1609 fn lower_local(&mut self, l
: &Local
) -> (hir
::Local
<'hir
>, SmallVec
<[NodeId
; 1]>) {
1610 let mut ids
= SmallVec
::<[NodeId
; 1]>::new();
1611 if self.sess
.features_untracked().impl_trait_in_bindings
{
1612 if let Some(ref ty
) = l
.ty
{
1613 let mut visitor
= ImplTraitTypeIdVisitor { ids: &mut ids }
;
1614 visitor
.visit_ty(ty
);
1617 let parent_def_id
= self.current_hir_id_owner
.last().unwrap().0;
1618 let ty
= l
.ty
.as_ref().map(|t
| {
1621 if self.sess
.features_untracked().impl_trait_in_bindings
{
1622 ImplTraitContext
::OpaqueTy(
1623 Some(parent_def_id
.to_def_id()),
1624 hir
::OpaqueTyOrigin
::Misc
,
1627 ImplTraitContext
::Disallowed(ImplTraitPosition
::Binding
)
1631 let init
= l
.init
.as_ref().map(|e
| self.lower_expr(e
));
1634 hir_id
: self.lower_node_id(l
.id
),
1636 pat
: self.lower_pat(&l
.pat
),
1639 attrs
: l
.attrs
.clone(),
1640 source
: hir
::LocalSource
::Normal
,
1646 fn lower_fn_params_to_names(&mut self, decl
: &FnDecl
) -> &'hir
[Ident
] {
1647 // Skip the `...` (`CVarArgs`) trailing arguments from the AST,
1648 // as they are not explicit in HIR/Ty function signatures.
1649 // (instead, the `c_variadic` flag is set to `true`)
1650 let mut inputs
= &decl
.inputs
[..];
1651 if decl
.c_variadic() {
1652 inputs
= &inputs
[..inputs
.len() - 1];
1654 self.arena
.alloc_from_iter(inputs
.iter().map(|param
| match param
.pat
.kind
{
1655 PatKind
::Ident(_
, ident
, _
) => ident
,
1656 _
=> Ident
::new(kw
::Invalid
, param
.pat
.span
),
1660 // Lowers a function declaration.
1662 // `decl`: the unlowered (AST) function declaration.
1663 // `fn_def_id`: if `Some`, impl Trait arguments are lowered into generic parameters on the
1664 // given DefId, otherwise impl Trait is disallowed. Must be `Some` if
1665 // `make_ret_async` is also `Some`.
1666 // `impl_trait_return_allow`: determines whether `impl Trait` can be used in return position.
1667 // This guards against trait declarations and implementations where `impl Trait` is
1669 // `make_ret_async`: if `Some`, converts `-> T` into `-> impl Future<Output = T>` in the
1670 // return type. This is used for `async fn` declarations. The `NodeId` is the ID of the
1671 // return type `impl Trait` item.
1675 mut in_band_ty_params
: Option
<(DefId
, &mut Vec
<hir
::GenericParam
<'hir
>>)>,
1676 impl_trait_return_allow
: bool
,
1677 make_ret_async
: Option
<NodeId
>,
1678 ) -> &'hir hir
::FnDecl
<'hir
> {
1682 in_band_ty_params: {:?}, \
1683 impl_trait_return_allow: {}, \
1684 make_ret_async: {:?})",
1685 decl
, in_band_ty_params
, impl_trait_return_allow
, make_ret_async
,
1687 let lt_mode
= if make_ret_async
.is_some() {
1688 // In `async fn`, argument-position elided lifetimes
1689 // must be transformed into fresh generic parameters so that
1690 // they can be applied to the opaque `impl Trait` return type.
1691 AnonymousLifetimeMode
::CreateParameter
1693 self.anonymous_lifetime_mode
1696 let c_variadic
= decl
.c_variadic();
1698 // Remember how many lifetimes were already around so that we can
1699 // only look at the lifetime parameters introduced by the arguments.
1700 let inputs
= self.with_anonymous_lifetime_mode(lt_mode
, |this
| {
1701 // Skip the `...` (`CVarArgs`) trailing arguments from the AST,
1702 // as they are not explicit in HIR/Ty function signatures.
1703 // (instead, the `c_variadic` flag is set to `true`)
1704 let mut inputs
= &decl
.inputs
[..];
1706 inputs
= &inputs
[..inputs
.len() - 1];
1708 this
.arena
.alloc_from_iter(inputs
.iter().map(|param
| {
1709 if let Some((_
, ibty
)) = &mut in_band_ty_params
{
1710 this
.lower_ty_direct(¶m
.ty
, ImplTraitContext
::Universal(ibty
))
1712 this
.lower_ty_direct(¶m
.ty
, ImplTraitContext
::disallowed())
1717 let output
= if let Some(ret_id
) = make_ret_async
{
1718 self.lower_async_fn_ret_ty(
1720 in_band_ty_params
.expect("`make_ret_async` but no `fn_def_id`").0,
1725 FnRetTy
::Ty(ref ty
) => {
1726 let context
= match in_band_ty_params
{
1727 Some((def_id
, _
)) if impl_trait_return_allow
=> {
1728 ImplTraitContext
::OpaqueTy(Some(def_id
), hir
::OpaqueTyOrigin
::FnReturn
)
1730 _
=> ImplTraitContext
::disallowed(),
1732 hir
::FnRetTy
::Return(self.lower_ty(ty
, context
))
1734 FnRetTy
::Default(span
) => hir
::FnRetTy
::DefaultReturn(span
),
1738 self.arena
.alloc(hir
::FnDecl
{
1742 implicit_self
: decl
.inputs
.get(0).map_or(hir
::ImplicitSelfKind
::None
, |arg
| {
1743 let is_mutable_pat
= match arg
.pat
.kind
{
1744 PatKind
::Ident(BindingMode
::ByValue(mt
) | BindingMode
::ByRef(mt
), _
, _
) => {
1745 mt
== Mutability
::Mut
1751 TyKind
::ImplicitSelf
if is_mutable_pat
=> hir
::ImplicitSelfKind
::Mut
,
1752 TyKind
::ImplicitSelf
=> hir
::ImplicitSelfKind
::Imm
,
1753 // Given we are only considering `ImplicitSelf` types, we needn't consider
1754 // the case where we have a mutable pattern to a reference as that would
1755 // no longer be an `ImplicitSelf`.
1756 TyKind
::Rptr(_
, ref mt
)
1757 if mt
.ty
.kind
.is_implicit_self() && mt
.mutbl
== ast
::Mutability
::Mut
=>
1759 hir
::ImplicitSelfKind
::MutRef
1761 TyKind
::Rptr(_
, ref mt
) if mt
.ty
.kind
.is_implicit_self() => {
1762 hir
::ImplicitSelfKind
::ImmRef
1764 _
=> hir
::ImplicitSelfKind
::None
,
1770 // Transforms `-> T` for `async fn` into `-> OpaqueTy { .. }`
1771 // combined with the following definition of `OpaqueTy`:
1773 // type OpaqueTy<generics_from_parent_fn> = impl Future<Output = T>;
1775 // `inputs`: lowered types of parameters to the function (used to collect lifetimes)
1776 // `output`: unlowered output type (`T` in `-> T`)
1777 // `fn_def_id`: `DefId` of the parent function (used to create child impl trait definition)
1778 // `opaque_ty_node_id`: `NodeId` of the opaque `impl Trait` type that should be created
1779 // `elided_lt_replacement`: replacement for elided lifetimes in the return type
1780 fn lower_async_fn_ret_ty(
1784 opaque_ty_node_id
: NodeId
,
1785 ) -> hir
::FnRetTy
<'hir
> {
1787 "lower_async_fn_ret_ty(\
1790 opaque_ty_node_id={:?})",
1791 output
, fn_def_id
, opaque_ty_node_id
,
1794 let span
= output
.span();
1796 let opaque_ty_span
= self.mark_span_with_reason(DesugaringKind
::Async
, span
, None
);
1798 let opaque_ty_def_id
= self.resolver
.definitions().local_def_id(opaque_ty_node_id
);
1800 self.allocate_hir_id_counter(opaque_ty_node_id
);
1802 // When we create the opaque type for this async fn, it is going to have
1803 // to capture all the lifetimes involved in the signature (including in the
1804 // return type). This is done by introducing lifetime parameters for:
1806 // - all the explicitly declared lifetimes from the impl and function itself;
1807 // - all the elided lifetimes in the fn arguments;
1808 // - all the elided lifetimes in the return type.
1810 // So for example in this snippet:
1813 // impl<'a> Foo<'a> {
1814 // async fn bar<'b>(&self, x: &'b Vec<f64>, y: &str) -> &u32 {
1815 // // ^ '0 ^ '1 ^ '2
1816 // // elided lifetimes used below
1821 // we would create an opaque type like:
1824 // type Bar<'a, 'b, '0, '1, '2> = impl Future<Output = &'2 u32>;
1827 // and we would then desugar `bar` to the equivalent of:
1830 // impl<'a> Foo<'a> {
1831 // fn bar<'b, '0, '1>(&'0 self, x: &'b Vec<f64>, y: &'1 str) -> Bar<'a, 'b, '0, '1, '_>
1835 // Note that the final parameter to `Bar` is `'_`, not `'2` --
1836 // this is because the elided lifetimes from the return type
1837 // should be figured out using the ordinary elision rules, and
1838 // this desugaring achieves that.
1840 // The variable `input_lifetimes_count` tracks the number of
1841 // lifetime parameters to the opaque type *not counting* those
1842 // lifetimes elided in the return type. This includes those
1843 // that are explicitly declared (`in_scope_lifetimes`) and
1844 // those elided lifetimes we found in the arguments (current
1845 // content of `lifetimes_to_define`). Next, we will process
1846 // the return type, which will cause `lifetimes_to_define` to
1848 let input_lifetimes_count
= self.in_scope_lifetimes
.len() + self.lifetimes_to_define
.len();
1850 let (opaque_ty_id
, lifetime_params
) = self.with_hir_id_owner(opaque_ty_node_id
, |this
| {
1851 // We have to be careful to get elision right here. The
1852 // idea is that we create a lifetime parameter for each
1853 // lifetime in the return type. So, given a return type
1854 // like `async fn foo(..) -> &[&u32]`, we lower to `impl
1855 // Future<Output = &'1 [ &'2 u32 ]>`.
1857 // Then, we will create `fn foo(..) -> Foo<'_, '_>`, and
1858 // hence the elision takes place at the fn site.
1859 let future_bound
= this
1860 .with_anonymous_lifetime_mode(AnonymousLifetimeMode
::CreateParameter
, |this
| {
1861 this
.lower_async_fn_output_type_to_future_bound(output
, fn_def_id
, span
)
1864 debug
!("lower_async_fn_ret_ty: future_bound={:#?}", future_bound
);
1866 // Calculate all the lifetimes that should be captured
1867 // by the opaque type. This should include all in-scope
1868 // lifetime parameters, including those defined in-band.
1870 // Note: this must be done after lowering the output type,
1871 // as the output type may introduce new in-band lifetimes.
1872 let lifetime_params
: Vec
<(Span
, ParamName
)> = this
1876 .map(|name
| (name
.ident().span
, name
))
1877 .chain(this
.lifetimes_to_define
.iter().cloned())
1880 debug
!("lower_async_fn_ret_ty: in_scope_lifetimes={:#?}", this
.in_scope_lifetimes
);
1881 debug
!("lower_async_fn_ret_ty: lifetimes_to_define={:#?}", this
.lifetimes_to_define
);
1882 debug
!("lower_async_fn_ret_ty: lifetime_params={:#?}", lifetime_params
);
1884 let generic_params
=
1885 this
.arena
.alloc_from_iter(lifetime_params
.iter().map(|(span
, hir_name
)| {
1886 this
.lifetime_to_generic_param(*span
, *hir_name
, opaque_ty_def_id
)
1889 let opaque_ty_item
= hir
::OpaqueTy
{
1890 generics
: hir
::Generics
{
1891 params
: generic_params
,
1892 where_clause
: hir
::WhereClause { predicates: &[], span }
,
1895 bounds
: arena_vec
![this
; future_bound
],
1896 impl_trait_fn
: Some(fn_def_id
),
1897 origin
: hir
::OpaqueTyOrigin
::AsyncFn
,
1900 trace
!("exist ty from async fn def id: {:#?}", opaque_ty_def_id
);
1902 this
.generate_opaque_type(opaque_ty_node_id
, opaque_ty_item
, span
, opaque_ty_span
);
1904 (opaque_ty_id
, lifetime_params
)
1907 // As documented above on the variable
1908 // `input_lifetimes_count`, we need to create the lifetime
1909 // arguments to our opaque type. Continuing with our example,
1910 // we're creating the type arguments for the return type:
1913 // Bar<'a, 'b, '0, '1, '_>
1916 // For the "input" lifetime parameters, we wish to create
1917 // references to the parameters themselves, including the
1918 // "implicit" ones created from parameter types (`'a`, `'b`,
1921 // For the "output" lifetime parameters, we just want to
1923 let mut generic_args
: Vec
<_
> = lifetime_params
[..input_lifetimes_count
]
1925 .map(|&(span
, hir_name
)| {
1926 // Input lifetime like `'a` or `'1`:
1927 GenericArg
::Lifetime(hir
::Lifetime
{
1928 hir_id
: self.next_id(),
1930 name
: hir
::LifetimeName
::Param(hir_name
),
1934 generic_args
.extend(lifetime_params
[input_lifetimes_count
..].iter().map(|&(span
, _
)|
1935 // Output lifetime like `'_`.
1936 GenericArg
::Lifetime(hir
::Lifetime
{
1937 hir_id
: self.next_id(),
1939 name
: hir
::LifetimeName
::Implicit
,
1941 let generic_args
= self.arena
.alloc_from_iter(generic_args
);
1943 // Create the `Foo<...>` reference itself. Note that the `type
1944 // Foo = impl Trait` is, internally, created as a child of the
1945 // async fn, so the *type parameters* are inherited. It's
1946 // only the lifetime parameters that we must supply.
1947 let opaque_ty_ref
= hir
::TyKind
::Def(hir
::ItemId { id: opaque_ty_id }
, generic_args
);
1948 let opaque_ty
= self.ty(opaque_ty_span
, opaque_ty_ref
);
1949 hir
::FnRetTy
::Return(self.arena
.alloc(opaque_ty
))
1952 /// Transforms `-> T` into `Future<Output = T>`
1953 fn lower_async_fn_output_type_to_future_bound(
1958 ) -> hir
::GenericBound
<'hir
> {
1959 // Compute the `T` in `Future<Output = T>` from the return type.
1960 let output_ty
= match output
{
1961 FnRetTy
::Ty(ty
) => {
1962 // Not `OpaqueTyOrigin::AsyncFn`: that's only used for the
1963 // `impl Future` opaque type that `async fn` implicitly
1966 ImplTraitContext
::OpaqueTy(Some(fn_def_id
), hir
::OpaqueTyOrigin
::FnReturn
);
1967 self.lower_ty(ty
, context
)
1969 FnRetTy
::Default(ret_ty_span
) => self.arena
.alloc(self.ty_tup(*ret_ty_span
, &[])),
1973 let future_params
= self.arena
.alloc(hir
::GenericArgs
{
1975 bindings
: arena_vec
![self; self.output_ty_binding(span
, output_ty
)],
1976 parenthesized
: false,
1979 // ::std::future::Future<future_params>
1981 self.std_path(span
, &[sym
::future
, sym
::Future
], Some(future_params
), false);
1983 hir
::GenericBound
::Trait(
1985 trait_ref
: hir
::TraitRef { path: future_path, hir_ref_id: self.next_id() }
,
1986 bound_generic_params
: &[],
1989 hir
::TraitBoundModifier
::None
,
1993 fn lower_param_bound(
1996 itctx
: ImplTraitContext
<'_
, 'hir
>,
1997 ) -> hir
::GenericBound
<'hir
> {
1999 GenericBound
::Trait(ref ty
, modifier
) => hir
::GenericBound
::Trait(
2000 self.lower_poly_trait_ref(ty
, itctx
),
2001 self.lower_trait_bound_modifier(modifier
),
2003 GenericBound
::Outlives(ref lifetime
) => {
2004 hir
::GenericBound
::Outlives(self.lower_lifetime(lifetime
))
2009 fn lower_lifetime(&mut self, l
: &Lifetime
) -> hir
::Lifetime
{
2010 let span
= l
.ident
.span
;
2012 ident
if ident
.name
== kw
::StaticLifetime
=> {
2013 self.new_named_lifetime(l
.id
, span
, hir
::LifetimeName
::Static
)
2015 ident
if ident
.name
== kw
::UnderscoreLifetime
=> match self.anonymous_lifetime_mode
{
2016 AnonymousLifetimeMode
::CreateParameter
=> {
2017 let fresh_name
= self.collect_fresh_in_band_lifetime(span
);
2018 self.new_named_lifetime(l
.id
, span
, hir
::LifetimeName
::Param(fresh_name
))
2021 AnonymousLifetimeMode
::PassThrough
=> {
2022 self.new_named_lifetime(l
.id
, span
, hir
::LifetimeName
::Underscore
)
2025 AnonymousLifetimeMode
::ReportError
=> self.new_error_lifetime(Some(l
.id
), span
),
2028 self.maybe_collect_in_band_lifetime(ident
);
2029 let param_name
= ParamName
::Plain(ident
);
2030 self.new_named_lifetime(l
.id
, span
, hir
::LifetimeName
::Param(param_name
))
2035 fn new_named_lifetime(
2039 name
: hir
::LifetimeName
,
2040 ) -> hir
::Lifetime
{
2041 hir
::Lifetime { hir_id: self.lower_node_id(id), span, name }
2044 fn lower_generic_params_mut
<'s
>(
2046 params
: &'s
[GenericParam
],
2047 add_bounds
: &'s NodeMap
<Vec
<GenericBound
>>,
2048 mut itctx
: ImplTraitContext
<'s
, 'hir
>,
2049 ) -> impl Iterator
<Item
= hir
::GenericParam
<'hir
>> + Captures
<'a
> + Captures
<'s
> {
2052 .map(move |param
| self.lower_generic_param(param
, add_bounds
, itctx
.reborrow()))
2055 fn lower_generic_params(
2057 params
: &[GenericParam
],
2058 add_bounds
: &NodeMap
<Vec
<GenericBound
>>,
2059 itctx
: ImplTraitContext
<'_
, 'hir
>,
2060 ) -> &'hir
[hir
::GenericParam
<'hir
>] {
2061 self.arena
.alloc_from_iter(self.lower_generic_params_mut(params
, add_bounds
, itctx
))
2064 fn lower_generic_param(
2066 param
: &GenericParam
,
2067 add_bounds
: &NodeMap
<Vec
<GenericBound
>>,
2068 mut itctx
: ImplTraitContext
<'_
, 'hir
>,
2069 ) -> hir
::GenericParam
<'hir
> {
2070 let mut bounds
: Vec
<_
> = self
2071 .with_anonymous_lifetime_mode(AnonymousLifetimeMode
::ReportError
, |this
| {
2072 this
.lower_param_bounds_mut(¶m
.bounds
, itctx
.reborrow()).collect()
2075 let (name
, kind
) = match param
.kind
{
2076 GenericParamKind
::Lifetime
=> {
2077 let was_collecting_in_band
= self.is_collecting_in_band_lifetimes
;
2078 self.is_collecting_in_band_lifetimes
= false;
2081 .with_anonymous_lifetime_mode(AnonymousLifetimeMode
::ReportError
, |this
| {
2082 this
.lower_lifetime(&Lifetime { id: param.id, ident: param.ident }
)
2084 let param_name
= match lt
.name
{
2085 hir
::LifetimeName
::Param(param_name
) => param_name
,
2086 hir
::LifetimeName
::Implicit
2087 | hir
::LifetimeName
::Underscore
2088 | hir
::LifetimeName
::Static
=> hir
::ParamName
::Plain(lt
.name
.ident()),
2089 hir
::LifetimeName
::ImplicitObjectLifetimeDefault
=> {
2090 self.sess
.diagnostic().span_bug(
2092 "object-lifetime-default should not occur here",
2095 hir
::LifetimeName
::Error
=> ParamName
::Error
,
2099 hir
::GenericParamKind
::Lifetime { kind: hir::LifetimeParamKind::Explicit }
;
2101 self.is_collecting_in_band_lifetimes
= was_collecting_in_band
;
2105 GenericParamKind
::Type { ref default, .. }
=> {
2106 let add_bounds
= add_bounds
.get(¶m
.id
).map_or(&[][..], |x
| &x
);
2107 if !add_bounds
.is_empty() {
2108 let params
= self.lower_param_bounds_mut(add_bounds
, itctx
.reborrow());
2109 bounds
.extend(params
);
2112 let kind
= hir
::GenericParamKind
::Type
{
2113 default: default.as_ref().map(|x
| {
2116 ImplTraitContext
::OpaqueTy(None
, hir
::OpaqueTyOrigin
::Misc
),
2122 .filter(|attr
| attr
.check_name(sym
::rustc_synthetic
))
2123 .map(|_
| hir
::SyntheticTyParamKind
::ImplTrait
)
2127 (hir
::ParamName
::Plain(param
.ident
), kind
)
2129 GenericParamKind
::Const { ref ty }
=> {
2131 .with_anonymous_lifetime_mode(AnonymousLifetimeMode
::ReportError
, |this
| {
2132 this
.lower_ty(&ty
, ImplTraitContext
::disallowed())
2135 (hir
::ParamName
::Plain(param
.ident
), hir
::GenericParamKind
::Const { ty }
)
2140 hir_id
: self.lower_node_id(param
.id
),
2142 span
: param
.ident
.span
,
2143 pure_wrt_drop
: attr
::contains_name(¶m
.attrs
, sym
::may_dangle
),
2144 attrs
: self.lower_attrs(¶m
.attrs
),
2145 bounds
: self.arena
.alloc_from_iter(bounds
),
2153 itctx
: ImplTraitContext
<'_
, 'hir
>,
2154 ) -> hir
::TraitRef
<'hir
> {
2155 let path
= match self.lower_qpath(p
.ref_id
, &None
, &p
.path
, ParamMode
::Explicit
, itctx
) {
2156 hir
::QPath
::Resolved(None
, path
) => path
,
2157 qpath
=> panic
!("lower_trait_ref: unexpected QPath `{:?}`", qpath
),
2159 hir
::TraitRef { path, hir_ref_id: self.lower_node_id(p.ref_id) }
2162 fn lower_poly_trait_ref(
2165 mut itctx
: ImplTraitContext
<'_
, 'hir
>,
2166 ) -> hir
::PolyTraitRef
<'hir
> {
2167 let bound_generic_params
= self.lower_generic_params(
2168 &p
.bound_generic_params
,
2169 &NodeMap
::default(),
2172 let trait_ref
= self.with_in_scope_lifetime_defs(&p
.bound_generic_params
, |this
| {
2173 this
.lower_trait_ref(&p
.trait_ref
, itctx
)
2176 hir
::PolyTraitRef { bound_generic_params, trait_ref, span: p.span }
2179 fn lower_mt(&mut self, mt
: &MutTy
, itctx
: ImplTraitContext
<'_
, 'hir
>) -> hir
::MutTy
<'hir
> {
2180 hir
::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl }
2183 fn lower_param_bounds(
2185 bounds
: &[GenericBound
],
2186 itctx
: ImplTraitContext
<'_
, 'hir
>,
2187 ) -> hir
::GenericBounds
<'hir
> {
2188 self.arena
.alloc_from_iter(self.lower_param_bounds_mut(bounds
, itctx
))
2191 fn lower_param_bounds_mut
<'s
>(
2193 bounds
: &'s
[GenericBound
],
2194 mut itctx
: ImplTraitContext
<'s
, 'hir
>,
2195 ) -> impl Iterator
<Item
= hir
::GenericBound
<'hir
>> + Captures
<'s
> + Captures
<'a
> {
2196 bounds
.iter().map(move |bound
| self.lower_param_bound(bound
, itctx
.reborrow()))
2199 fn lower_block(&mut self, b
: &Block
, targeted_by_break
: bool
) -> &'hir hir
::Block
<'hir
> {
2200 self.arena
.alloc(self.lower_block_noalloc(b
, targeted_by_break
))
2203 fn lower_block_noalloc(&mut self, b
: &Block
, targeted_by_break
: bool
) -> hir
::Block
<'hir
> {
2204 let mut stmts
= vec
![];
2205 let mut expr
: Option
<&'hir _
> = None
;
2207 for (index
, stmt
) in b
.stmts
.iter().enumerate() {
2208 if index
== b
.stmts
.len() - 1 {
2209 if let StmtKind
::Expr(ref e
) = stmt
.kind
{
2210 expr
= Some(self.lower_expr(e
));
2212 stmts
.extend(self.lower_stmt(stmt
));
2215 stmts
.extend(self.lower_stmt(stmt
));
2220 hir_id
: self.lower_node_id(b
.id
),
2221 stmts
: self.arena
.alloc_from_iter(stmts
),
2223 rules
: self.lower_block_check_mode(&b
.rules
),
2229 /// Lowers a block directly to an expression, presuming that it
2230 /// has no attributes and is not targeted by a `break`.
2231 fn lower_block_expr(&mut self, b
: &Block
) -> hir
::Expr
<'hir
> {
2232 let block
= self.lower_block(b
, false);
2233 self.expr_block(block
, AttrVec
::new())
2236 fn lower_anon_const(&mut self, c
: &AnonConst
) -> hir
::AnonConst
{
2237 self.with_new_scopes(|this
| hir
::AnonConst
{
2238 hir_id
: this
.lower_node_id(c
.id
),
2239 body
: this
.lower_const_body(c
.value
.span
, Some(&c
.value
)),
2243 fn lower_stmt(&mut self, s
: &Stmt
) -> SmallVec
<[hir
::Stmt
<'hir
>; 1]> {
2244 let kind
= match s
.kind
{
2245 StmtKind
::Local(ref l
) => {
2246 let (l
, item_ids
) = self.lower_local(l
);
2247 let mut ids
: SmallVec
<[hir
::Stmt
<'hir
>; 1]> = item_ids
2250 let item_id
= hir
::ItemId { id: self.lower_node_id(item_id) }
;
2251 self.stmt(s
.span
, hir
::StmtKind
::Item(item_id
))
2256 hir_id
: self.lower_node_id(s
.id
),
2257 kind
: hir
::StmtKind
::Local(self.arena
.alloc(l
)),
2263 StmtKind
::Item(ref it
) => {
2264 // Can only use the ID once.
2265 let mut id
= Some(s
.id
);
2272 .map(|id
| self.lower_node_id(id
))
2273 .unwrap_or_else(|| self.next_id());
2275 hir
::Stmt { hir_id, kind: hir::StmtKind::Item(item_id), span: s.span }
2279 StmtKind
::Expr(ref e
) => hir
::StmtKind
::Expr(self.lower_expr(e
)),
2280 StmtKind
::Semi(ref e
) => hir
::StmtKind
::Semi(self.lower_expr(e
)),
2281 StmtKind
::Empty
=> return smallvec
![],
2282 StmtKind
::MacCall(..) => panic
!("shouldn't exist here"),
2284 smallvec
![hir
::Stmt { hir_id: self.lower_node_id(s.id), kind, span: s.span }
]
2287 fn lower_block_check_mode(&mut self, b
: &BlockCheckMode
) -> hir
::BlockCheckMode
{
2289 BlockCheckMode
::Default
=> hir
::BlockCheckMode
::DefaultBlock
,
2290 BlockCheckMode
::Unsafe(u
) => {
2291 hir
::BlockCheckMode
::UnsafeBlock(self.lower_unsafe_source(u
))
2296 fn lower_unsafe_source(&mut self, u
: UnsafeSource
) -> hir
::UnsafeSource
{
2298 CompilerGenerated
=> hir
::UnsafeSource
::CompilerGenerated
,
2299 UserProvided
=> hir
::UnsafeSource
::UserProvided
,
2303 fn lower_trait_bound_modifier(&mut self, f
: TraitBoundModifier
) -> hir
::TraitBoundModifier
{
2305 TraitBoundModifier
::None
=> hir
::TraitBoundModifier
::None
,
2306 TraitBoundModifier
::MaybeConst
=> hir
::TraitBoundModifier
::MaybeConst
,
2308 // `MaybeConstMaybe` will cause an error during AST validation, but we need to pick a
2309 // placeholder for compilation to proceed.
2310 TraitBoundModifier
::MaybeConstMaybe
| TraitBoundModifier
::Maybe
=> {
2311 hir
::TraitBoundModifier
::Maybe
2316 // Helper methods for building HIR.
2318 fn stmt(&mut self, span
: Span
, kind
: hir
::StmtKind
<'hir
>) -> hir
::Stmt
<'hir
> {
2319 hir
::Stmt { span, kind, hir_id: self.next_id() }
2322 fn stmt_expr(&mut self, span
: Span
, expr
: hir
::Expr
<'hir
>) -> hir
::Stmt
<'hir
> {
2323 self.stmt(span
, hir
::StmtKind
::Expr(self.arena
.alloc(expr
)))
2330 init
: Option
<&'hir hir
::Expr
<'hir
>>,
2331 pat
: &'hir hir
::Pat
<'hir
>,
2332 source
: hir
::LocalSource
,
2333 ) -> hir
::Stmt
<'hir
> {
2334 let local
= hir
::Local { attrs, hir_id: self.next_id(), init, pat, source, span, ty: None }
;
2335 self.stmt(span
, hir
::StmtKind
::Local(self.arena
.alloc(local
)))
2338 fn block_expr(&mut self, expr
: &'hir hir
::Expr
<'hir
>) -> &'hir hir
::Block
<'hir
> {
2339 self.block_all(expr
.span
, &[], Some(expr
))
2345 stmts
: &'hir
[hir
::Stmt
<'hir
>],
2346 expr
: Option
<&'hir hir
::Expr
<'hir
>>,
2347 ) -> &'hir hir
::Block
<'hir
> {
2348 let blk
= hir
::Block
{
2351 hir_id
: self.next_id(),
2352 rules
: hir
::BlockCheckMode
::DefaultBlock
,
2354 targeted_by_break
: false,
2356 self.arena
.alloc(blk
)
2359 /// Constructs a `true` or `false` literal pattern.
2360 fn pat_bool(&mut self, span
: Span
, val
: bool
) -> &'hir hir
::Pat
<'hir
> {
2361 let expr
= self.expr_bool(span
, val
);
2362 self.pat(span
, hir
::PatKind
::Lit(expr
))
2365 fn pat_ok(&mut self, span
: Span
, pat
: &'hir hir
::Pat
<'hir
>) -> &'hir hir
::Pat
<'hir
> {
2366 self.pat_std_enum(span
, &[sym
::result
, sym
::Result
, sym
::Ok
], arena_vec
![self; pat
])
2369 fn pat_err(&mut self, span
: Span
, pat
: &'hir hir
::Pat
<'hir
>) -> &'hir hir
::Pat
<'hir
> {
2370 self.pat_std_enum(span
, &[sym
::result
, sym
::Result
, sym
::Err
], arena_vec
![self; pat
])
2373 fn pat_some(&mut self, span
: Span
, pat
: &'hir hir
::Pat
<'hir
>) -> &'hir hir
::Pat
<'hir
> {
2374 self.pat_std_enum(span
, &[sym
::option
, sym
::Option
, sym
::Some
], arena_vec
![self; pat
])
2377 fn pat_none(&mut self, span
: Span
) -> &'hir hir
::Pat
<'hir
> {
2378 self.pat_std_enum(span
, &[sym
::option
, sym
::Option
, sym
::None
], &[])
2384 components
: &[Symbol
],
2385 subpats
: &'hir
[&'hir hir
::Pat
<'hir
>],
2386 ) -> &'hir hir
::Pat
<'hir
> {
2387 let path
= self.std_path(span
, components
, None
, true);
2388 let qpath
= hir
::QPath
::Resolved(None
, path
);
2389 let pt
= if subpats
.is_empty() {
2390 hir
::PatKind
::Path(qpath
)
2392 hir
::PatKind
::TupleStruct(qpath
, subpats
, None
)
2397 fn pat_ident(&mut self, span
: Span
, ident
: Ident
) -> (&'hir hir
::Pat
<'hir
>, hir
::HirId
) {
2398 self.pat_ident_binding_mode(span
, ident
, hir
::BindingAnnotation
::Unannotated
)
2401 fn pat_ident_binding_mode(
2405 bm
: hir
::BindingAnnotation
,
2406 ) -> (&'hir hir
::Pat
<'hir
>, hir
::HirId
) {
2407 let hir_id
= self.next_id();
2410 self.arena
.alloc(hir
::Pat
{
2412 kind
: hir
::PatKind
::Binding(bm
, hir_id
, ident
.with_span_pos(span
), None
),
2419 fn pat_wild(&mut self, span
: Span
) -> &'hir hir
::Pat
<'hir
> {
2420 self.pat(span
, hir
::PatKind
::Wild
)
2423 fn pat(&mut self, span
: Span
, kind
: hir
::PatKind
<'hir
>) -> &'hir hir
::Pat
<'hir
> {
2424 self.arena
.alloc(hir
::Pat { hir_id: self.next_id(), kind, span }
)
2427 /// Given a suffix `["b", "c", "d"]`, returns path `::std::b::c::d` when
2428 /// `fld.cx.use_std`, and `::core::b::c::d` otherwise.
2429 /// The path is also resolved according to `is_value`.
2433 components
: &[Symbol
],
2434 params
: Option
<&'hir hir
::GenericArgs
<'hir
>>,
2436 ) -> &'hir hir
::Path
<'hir
> {
2437 let ns
= if is_value { Namespace::ValueNS }
else { Namespace::TypeNS }
;
2438 let (path
, res
) = self.resolver
.resolve_str_path(span
, self.crate_root
, components
, ns
);
2440 let mut segments
: Vec
<_
> = path
2444 let res
= self.expect_full_res(segment
.id
);
2446 ident
: segment
.ident
,
2447 hir_id
: Some(self.lower_node_id(segment
.id
)),
2448 res
: Some(self.lower_res(res
)),
2454 segments
.last_mut().unwrap().args
= params
;
2456 self.arena
.alloc(hir
::Path
{
2458 res
: res
.map_id(|_
| panic
!("unexpected `NodeId`")),
2459 segments
: self.arena
.alloc_from_iter(segments
),
2465 mut hir_id
: hir
::HirId
,
2467 qpath
: hir
::QPath
<'hir
>,
2468 ) -> hir
::Ty
<'hir
> {
2469 let kind
= match qpath
{
2470 hir
::QPath
::Resolved(None
, path
) => {
2471 // Turn trait object paths into `TyKind::TraitObject` instead.
2473 Res
::Def(DefKind
::Trait
| DefKind
::TraitAlias
, _
) => {
2474 let principal
= hir
::PolyTraitRef
{
2475 bound_generic_params
: &[],
2476 trait_ref
: hir
::TraitRef { path, hir_ref_id: hir_id }
,
2480 // The original ID is taken by the `PolyTraitRef`,
2481 // so the `Ty` itself needs a different one.
2482 hir_id
= self.next_id();
2483 hir
::TyKind
::TraitObject(
2484 arena_vec
![self; principal
],
2485 self.elided_dyn_bound(span
),
2488 _
=> hir
::TyKind
::Path(hir
::QPath
::Resolved(None
, path
)),
2491 _
=> hir
::TyKind
::Path(qpath
),
2494 hir
::Ty { hir_id, kind, span }
2497 /// Invoked to create the lifetime argument for a type `&T`
2498 /// with no explicit lifetime.
2499 fn elided_ref_lifetime(&mut self, span
: Span
) -> hir
::Lifetime
{
2500 match self.anonymous_lifetime_mode
{
2501 // Intercept when we are in an impl header or async fn and introduce an in-band
2503 // Hence `impl Foo for &u32` becomes `impl<'f> Foo for &'f u32` for some fresh
2505 AnonymousLifetimeMode
::CreateParameter
=> {
2506 let fresh_name
= self.collect_fresh_in_band_lifetime(span
);
2508 hir_id
: self.next_id(),
2510 name
: hir
::LifetimeName
::Param(fresh_name
),
2514 AnonymousLifetimeMode
::ReportError
=> self.new_error_lifetime(None
, span
),
2516 AnonymousLifetimeMode
::PassThrough
=> self.new_implicit_lifetime(span
),
2520 /// Report an error on illegal use of `'_` or a `&T` with no explicit lifetime;
2521 /// return a "error lifetime".
2522 fn new_error_lifetime(&mut self, id
: Option
<NodeId
>, span
: Span
) -> hir
::Lifetime
{
2523 let (id
, msg
, label
) = match id
{
2524 Some(id
) => (id
, "`'_` cannot be used here", "`'_` is a reserved lifetime name"),
2527 self.resolver
.next_node_id(),
2528 "`&` without an explicit lifetime name cannot be used here",
2529 "explicit lifetime name needed here",
2533 let mut err
= struct_span_err
!(self.sess
, span
, E0637
, "{}", msg
,);
2534 err
.span_label(span
, label
);
2537 self.new_named_lifetime(id
, span
, hir
::LifetimeName
::Error
)
2540 /// Invoked to create the lifetime argument(s) for a path like
2541 /// `std::cell::Ref<T>`; note that implicit lifetimes in these
2542 /// sorts of cases are deprecated. This may therefore report a warning or an
2543 /// error, depending on the mode.
2544 fn elided_path_lifetimes
<'s
>(
2548 ) -> impl Iterator
<Item
= hir
::Lifetime
> + Captures
<'a
> + Captures
<'s
> + Captures
<'hir
> {
2549 (0..count
).map(move |_
| self.elided_path_lifetime(span
))
2552 fn elided_path_lifetime(&mut self, span
: Span
) -> hir
::Lifetime
{
2553 match self.anonymous_lifetime_mode
{
2554 AnonymousLifetimeMode
::CreateParameter
=> {
2555 // We should have emitted E0726 when processing this path above
2557 .delay_span_bug(span
, "expected 'implicit elided lifetime not allowed' error");
2558 let id
= self.resolver
.next_node_id();
2559 self.new_named_lifetime(id
, span
, hir
::LifetimeName
::Error
)
2561 // `PassThrough` is the normal case.
2562 // `new_error_lifetime`, which would usually be used in the case of `ReportError`,
2563 // is unsuitable here, as these can occur from missing lifetime parameters in a
2564 // `PathSegment`, for which there is no associated `'_` or `&T` with no explicit
2565 // lifetime. Instead, we simply create an implicit lifetime, which will be checked
2566 // later, at which point a suitable error will be emitted.
2567 AnonymousLifetimeMode
::PassThrough
| AnonymousLifetimeMode
::ReportError
=> {
2568 self.new_implicit_lifetime(span
)
2573 /// Invoked to create the lifetime argument(s) for an elided trait object
2574 /// bound, like the bound in `Box<dyn Debug>`. This method is not invoked
2575 /// when the bound is written, even if it is written with `'_` like in
2576 /// `Box<dyn Debug + '_>`. In those cases, `lower_lifetime` is invoked.
2577 fn elided_dyn_bound(&mut self, span
: Span
) -> hir
::Lifetime
{
2578 match self.anonymous_lifetime_mode
{
2579 // NB. We intentionally ignore the create-parameter mode here.
2580 // and instead "pass through" to resolve-lifetimes, which will apply
2581 // the object-lifetime-defaulting rules. Elided object lifetime defaults
2582 // do not act like other elided lifetimes. In other words, given this:
2584 // impl Foo for Box<dyn Debug>
2586 // we do not introduce a fresh `'_` to serve as the bound, but instead
2587 // ultimately translate to the equivalent of:
2589 // impl Foo for Box<dyn Debug + 'static>
2591 // `resolve_lifetime` has the code to make that happen.
2592 AnonymousLifetimeMode
::CreateParameter
=> {}
2594 AnonymousLifetimeMode
::ReportError
=> {
2595 // ReportError applies to explicit use of `'_`.
2598 // This is the normal case.
2599 AnonymousLifetimeMode
::PassThrough
=> {}
2602 let r
= hir
::Lifetime
{
2603 hir_id
: self.next_id(),
2605 name
: hir
::LifetimeName
::ImplicitObjectLifetimeDefault
,
2607 debug
!("elided_dyn_bound: r={:?}", r
);
2611 fn new_implicit_lifetime(&mut self, span
: Span
) -> hir
::Lifetime
{
2612 hir
::Lifetime { hir_id: self.next_id(), span, name: hir::LifetimeName::Implicit }
2615 fn maybe_lint_bare_trait(&mut self, span
: Span
, id
: NodeId
, is_global
: bool
) {
2616 // FIXME(davidtwco): This is a hack to detect macros which produce spans of the
2617 // call site which do not have a macro backtrace. See #61963.
2618 let is_macro_callsite
= self
2621 .span_to_snippet(span
)
2622 .map(|snippet
| snippet
.starts_with("#["))
2624 if !is_macro_callsite
{
2625 self.resolver
.lint_buffer().buffer_lint_with_diagnostic(
2629 "trait objects without an explicit `dyn` are deprecated",
2630 BuiltinLintDiagnostics
::BareTraitObject(span
, is_global
),
2636 fn body_ids(bodies
: &BTreeMap
<hir
::BodyId
, hir
::Body
<'_
>>) -> Vec
<hir
::BodyId
> {
2637 // Sorting by span ensures that we get things in order within a
2638 // file, and also puts the files in a sensible order.
2639 let mut body_ids
: Vec
<_
> = bodies
.keys().cloned().collect();
2640 body_ids
.sort_by_key(|b
| bodies
[b
].value
.span
);
2644 /// Helper struct for delayed construction of GenericArgs.
2645 struct GenericArgsCtor
<'hir
> {
2646 args
: SmallVec
<[hir
::GenericArg
<'hir
>; 4]>,
2647 bindings
: &'hir
[hir
::TypeBinding
<'hir
>],
2648 parenthesized
: bool
,
2651 impl<'hir
> GenericArgsCtor
<'hir
> {
2652 fn is_empty(&self) -> bool
{
2653 self.args
.is_empty() && self.bindings
.is_empty() && !self.parenthesized
2656 fn into_generic_args(self, arena
: &'hir Arena
<'hir
>) -> hir
::GenericArgs
<'hir
> {
2658 args
: arena
.alloc_from_iter(self.args
),
2659 bindings
: self.bindings
,
2660 parenthesized
: self.parenthesized
,