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(crate_visibility_modifier)]
34 #![feature(box_patterns)]
36 #![feature(never_type)]
37 #![recursion_limit = "256"]
39 use rustc_ast::token::{self, Token};
40 use rustc_ast::tokenstream::{CanSynthesizeMissingTokens, TokenStream, TokenTree};
42 use rustc_ast::{self as ast, *};
43 use rustc_ast_pretty::pprust;
44 use rustc_data_structures::captures::Captures;
45 use rustc_data_structures::fingerprint::Fingerprint;
46 use rustc_data_structures::fx::FxHashSet;
47 use rustc_data_structures::sorted_map::SortedMap;
48 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
49 use rustc_data_structures::sync::Lrc;
50 use rustc_errors::{struct_span_err, Applicability};
52 use rustc_hir::def::{DefKind, Namespace, PartialRes, PerNS, Res};
53 use rustc_hir::def_id::{DefId, DefPathHash, LocalDefId, CRATE_DEF_ID};
54 use rustc_hir::definitions::{DefKey, DefPathData, Definitions};
55 use rustc_hir::intravisit;
56 use rustc_hir::{ConstArg, GenericArg, InferKind, ParamName};
57 use rustc_index::vec::{Idx, IndexVec};
58 use rustc_query_system::ich::StableHashingContext;
59 use rustc_session::lint::builtin::BARE_TRAIT_OBJECTS;
60 use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
61 use rustc_session::utils::{FlattenNonterminals, NtToTokenstream};
62 use rustc_session::Session;
63 use rustc_span::edition::Edition;
64 use rustc_span::hygiene::ExpnId;
65 use rustc_span::source_map::{respan, DesugaringKind};
66 use rustc_span::symbol::{kw, sym, Ident, Symbol};
67 use rustc_span::{Span, DUMMY_SP};
69 use smallvec::SmallVec;
70 use tracing::{debug, trace};
72 macro_rules! arena_vec {
73 ($this:expr; $($x:expr),*) => ({
75 $this.arena.alloc_from_iter(std::array::IntoIter::new(a))
87 rustc_hir::arena_types!(rustc_arena::declare_arena, 'tcx);
89 struct LoweringContext<'a, 'hir: 'a> {
90 /// Used to assign IDs to HIR nodes that do not directly correspond to AST nodes.
93 resolver: &'a mut dyn ResolverAstLowering,
95 /// HACK(Centril): there is a cyclic dependency between the parser and lowering
96 /// if we don't have this function pointer. To avoid that dependency so that
97 /// `rustc_middle` is independent of the parser, we use dynamic dispatch here.
98 nt_to_tokenstream: NtToTokenstream,
100 /// Used to allocate HIR nodes.
101 arena: &'hir Arena<'hir>,
103 /// The items being lowered are collected here.
104 owners: IndexVec<LocalDefId, Option<hir::OwnerInfo<'hir>>>,
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]>,
110 generator_kind: Option<hir::GeneratorKind>,
112 /// When inside an `async` context, this is the `HirId` of the
113 /// `task_context` local bound to the resume argument of the generator.
114 task_context: Option<hir::HirId>,
116 /// Used to get the current `fn`'s def span to point to when using `await`
117 /// outside of an `async fn`.
118 current_item: Option<Span>,
120 catch_scope: Option<NodeId>,
121 loop_scope: Option<NodeId>,
122 is_in_loop_condition: bool,
123 is_in_trait_impl: bool,
124 is_in_dyn_type: bool,
126 /// What to do when we encounter an "anonymous lifetime
127 /// reference". The term "anonymous" is meant to encompass both
128 /// `'_` lifetimes as well as fully elided cases where nothing is
129 /// written at all (e.g., `&T` or `std::cell::Ref<T>`).
130 anonymous_lifetime_mode: AnonymousLifetimeMode,
132 /// Used to create lifetime definitions from in-band lifetime usages.
133 /// e.g., `fn foo(x: &'x u8) -> &'x u8` to `fn foo<'x>(x: &'x u8) -> &'x u8`
134 /// When a named lifetime is encountered in a function or impl header and
135 /// has not been defined
136 /// (i.e., it doesn't appear in the in_scope_lifetimes list), it is added
137 /// to this list. The results of this list are then added to the list of
138 /// lifetime definitions in the corresponding impl or function generics.
139 lifetimes_to_define: Vec<(Span, ParamName)>,
141 /// `true` if in-band lifetimes are being collected. This is used to
142 /// indicate whether or not we're in a place where new lifetimes will result
143 /// in in-band lifetime definitions, such a function or an impl header,
144 /// including implicit lifetimes from `impl_header_lifetime_elision`.
145 is_collecting_in_band_lifetimes: bool,
147 /// Currently in-scope lifetimes defined in impl headers, fn headers, or HRTB.
148 /// When `is_collecting_in_band_lifetimes` is true, each lifetime is checked
149 /// against this list to see if it is already in-scope, or if a definition
150 /// needs to be created for it.
152 /// We always store a `normalize_to_macros_2_0()` version of the param-name in this
154 in_scope_lifetimes: Vec<ParamName>,
156 current_hir_id_owner: LocalDefId,
157 item_local_id_counter: hir::ItemLocalId,
158 node_id_to_hir_id: IndexVec<NodeId, Option<hir::HirId>>,
160 /// NodeIds that are lowered inside the current HIR owner.
161 local_node_ids: Vec<NodeId>,
163 allow_try_trait: Option<Lrc<[Symbol]>>,
164 allow_gen_future: Option<Lrc<[Symbol]>>,
167 pub trait ResolverAstLowering {
168 fn def_key(&mut self, id: DefId) -> DefKey;
170 fn def_span(&self, id: LocalDefId) -> Span;
172 fn item_generics_num_lifetimes(&self, def: DefId) -> usize;
174 fn legacy_const_generic_args(&mut self, expr: &Expr) -> Option<Vec<usize>>;
176 /// Obtains resolution for a `NodeId` with a single resolution.
177 fn get_partial_res(&self, id: NodeId) -> Option<PartialRes>;
179 /// Obtains per-namespace resolutions for `use` statement with the given `NodeId`.
180 fn get_import_res(&mut self, id: NodeId) -> PerNS<Option<Res<NodeId>>>;
182 /// Obtains resolution for a label with the given `NodeId`.
183 fn get_label_res(&mut self, id: NodeId) -> Option<NodeId>;
185 /// We must keep the set of definitions up to date as we add nodes that weren't in the AST.
186 /// This should only return `None` during testing.
187 fn definitions(&mut self) -> &mut Definitions;
189 fn create_stable_hashing_context(&self) -> StableHashingContext<'_>;
191 fn lint_buffer(&mut self) -> &mut LintBuffer;
193 fn next_node_id(&mut self) -> NodeId;
195 fn take_trait_map(&mut self, node: NodeId) -> Option<Vec<hir::TraitCandidate>>;
197 fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId>;
199 fn local_def_id(&self, node: NodeId) -> LocalDefId;
201 fn def_path_hash(&self, def_id: DefId) -> DefPathHash;
206 node_id: ast::NodeId,
213 /// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,
214 /// and if so, what meaning it has.
216 enum ImplTraitContext<'b, 'a> {
217 /// Treat `impl Trait` as shorthand for a new universal generic parameter.
218 /// Example: `fn foo(x: impl Debug)`, where `impl Debug` is conceptually
219 /// equivalent to a fresh universal parameter like `fn foo<T: Debug>(x: T)`.
221 /// Newly generated parameters should be inserted into the given `Vec`.
222 Universal(&'b mut Vec<hir::GenericParam<'a>>, LocalDefId),
224 /// Treat `impl Trait` as shorthand for a new opaque type.
225 /// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
226 /// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`.
228 ReturnPositionOpaqueTy {
229 /// `DefId` for the parent function, used to look up necessary
230 /// information later.
232 /// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn,
233 origin: hir::OpaqueTyOrigin,
235 /// Impl trait in type aliases.
236 TypeAliasesOpaqueTy {
237 /// Set of lifetimes that this opaque type can capture, if it uses
238 /// them. This includes lifetimes bound since we entered this context.
242 /// type A<'b> = impl for<'a> Trait<'a, Out = impl Sized + 'a>;
245 /// Here the inner opaque type captures `'a` because it uses it. It doesn't
246 /// need to capture `'b` because it already inherits the lifetime
247 /// parameter from `A`.
248 // FIXME(impl_trait): but `required_region_bounds` will ICE later
250 capturable_lifetimes: &'b mut FxHashSet<hir::LifetimeName>,
252 /// `impl Trait` is not accepted in this position.
253 Disallowed(ImplTraitPosition),
256 /// Position in which `impl Trait` is disallowed.
257 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
258 enum ImplTraitPosition {
259 /// Disallowed in `let` / `const` / `static` bindings.
262 /// All other positions.
266 impl<'a> ImplTraitContext<'_, 'a> {
268 fn disallowed() -> Self {
269 ImplTraitContext::Disallowed(ImplTraitPosition::Other)
272 fn reborrow<'this>(&'this mut self) -> ImplTraitContext<'this, 'a> {
273 use self::ImplTraitContext::*;
275 Universal(params, parent) => Universal(params, *parent),
276 ReturnPositionOpaqueTy { fn_def_id, origin } => {
277 ReturnPositionOpaqueTy { fn_def_id: *fn_def_id, origin: *origin }
279 TypeAliasesOpaqueTy { capturable_lifetimes } => {
280 TypeAliasesOpaqueTy { capturable_lifetimes }
282 Disallowed(pos) => Disallowed(*pos),
287 pub fn lower_crate<'a, 'hir>(
290 resolver: &'a mut dyn ResolverAstLowering,
291 nt_to_tokenstream: NtToTokenstream,
292 arena: &'hir Arena<'hir>,
293 ) -> &'hir hir::Crate<'hir> {
294 let _prof_timer = sess.prof.verbose_generic_activity("hir_lowering");
296 let owners = IndexVec::from_fn_n(|_| None, resolver.definitions().def_index_count());
304 attrs: SortedMap::new(),
307 is_in_loop_condition: false,
308 is_in_trait_impl: false,
309 is_in_dyn_type: false,
310 anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough,
311 current_hir_id_owner: CRATE_DEF_ID,
312 item_local_id_counter: hir::ItemLocalId::new(0),
313 node_id_to_hir_id: IndexVec::new(),
314 local_node_ids: Vec::new(),
315 generator_kind: None,
318 lifetimes_to_define: Vec::new(),
319 is_collecting_in_band_lifetimes: false,
320 in_scope_lifetimes: Vec::new(),
321 allow_try_trait: Some([sym::try_trait_v2][..].into()),
322 allow_gen_future: Some([sym::gen_future][..].into()),
327 #[derive(Copy, Clone, PartialEq)]
329 /// Any path in a type context.
331 /// Path in a type definition, where the anonymous lifetime `'_` is not allowed.
333 /// The `module::Type` in `module::Type::method` in an expression.
337 enum ParenthesizedGenericArgs {
342 /// What to do when we encounter an **anonymous** lifetime
343 /// reference. Anonymous lifetime references come in two flavors. You
344 /// have implicit, or fully elided, references to lifetimes, like the
345 /// one in `&T` or `Ref<T>`, and you have `'_` lifetimes, like `&'_ T`
346 /// or `Ref<'_, T>`. These often behave the same, but not always:
348 /// - certain usages of implicit references are deprecated, like
349 /// `Ref<T>`, and we sometimes just give hard errors in those cases
351 /// - for object bounds there is a difference: `Box<dyn Foo>` is not
352 /// the same as `Box<dyn Foo + '_>`.
354 /// We describe the effects of the various modes in terms of three cases:
356 /// - **Modern** -- includes all uses of `'_`, but also the lifetime arg
357 /// of a `&` (e.g., the missing lifetime in something like `&T`)
358 /// - **Dyn Bound** -- if you have something like `Box<dyn Foo>`,
359 /// there is an elided lifetime bound (`Box<dyn Foo + 'X>`). These
360 /// elided bounds follow special rules. Note that this only covers
361 /// cases where *nothing* is written; the `'_` in `Box<dyn Foo +
362 /// '_>` is a case of "modern" elision.
363 /// - **Deprecated** -- this covers cases like `Ref<T>`, where the lifetime
364 /// parameter to ref is completely elided. `Ref<'_, T>` would be the modern,
365 /// non-deprecated equivalent.
367 /// Currently, the handling of lifetime elision is somewhat spread out
368 /// between HIR lowering and -- as described below -- the
369 /// `resolve_lifetime` module. Often we "fallthrough" to that code by generating
370 /// an "elided" or "underscore" lifetime name. In the future, we probably want to move
371 /// everything into HIR lowering.
372 #[derive(Copy, Clone, Debug)]
373 enum AnonymousLifetimeMode {
374 /// For **Modern** cases, create a new anonymous region parameter
375 /// and reference that.
377 /// For **Dyn Bound** cases, pass responsibility to
378 /// `resolve_lifetime` code.
380 /// For **Deprecated** cases, report an error.
383 /// Give a hard error when either `&` or `'_` is written. Used to
384 /// rule out things like `where T: Foo<'_>`. Does not imply an
385 /// error on default object bounds (e.g., `Box<dyn Foo>`).
388 /// Pass responsibility to `resolve_lifetime` code for all cases.
392 impl<'a, 'hir> LoweringContext<'a, 'hir> {
393 fn lower_crate(mut self, c: &Crate) -> &'hir hir::Crate<'hir> {
394 debug_assert_eq!(self.resolver.local_def_id(CRATE_NODE_ID), CRATE_DEF_ID);
396 visit::walk_crate(&mut item::ItemLowerer { lctx: &mut self }, c);
398 self.with_hir_id_owner(CRATE_NODE_ID, |lctx| {
399 let module = lctx.lower_mod(&c.items, c.span);
400 lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs);
401 hir::OwnerNode::Crate(lctx.arena.alloc(module))
404 let hir_hash = self.compute_hir_hash();
406 let mut def_id_to_hir_id = IndexVec::default();
408 for (node_id, hir_id) in self.node_id_to_hir_id.into_iter_enumerated() {
409 if let Some(def_id) = self.resolver.opt_local_def_id(node_id) {
410 if def_id_to_hir_id.len() <= def_id.index() {
411 def_id_to_hir_id.resize(def_id.index() + 1, None);
413 def_id_to_hir_id[def_id] = hir_id;
417 self.resolver.definitions().init_def_id_to_hir_id_mapping(def_id_to_hir_id);
419 let krate = hir::Crate { owners: self.owners, hir_hash };
420 self.arena.alloc(krate)
423 /// Compute the hash for the HIR of the full crate.
424 /// This hash will then be part of the crate_hash which is stored in the metadata.
425 fn compute_hir_hash(&mut self) -> Fingerprint {
426 let definitions = self.resolver.definitions();
427 let mut hir_body_nodes: Vec<_> = self
430 .filter_map(|(def_id, info)| {
431 let info = info.as_ref()?;
432 let def_path_hash = definitions.def_path_hash(def_id);
433 Some((def_path_hash, info))
436 hir_body_nodes.sort_unstable_by_key(|bn| bn.0);
438 let mut stable_hasher = StableHasher::new();
439 let mut hcx = self.resolver.create_stable_hashing_context();
440 hir_body_nodes.hash_stable(&mut hcx, &mut stable_hasher);
441 stable_hasher.finish()
444 fn with_hir_id_owner(
447 f: impl FnOnce(&mut Self) -> hir::OwnerNode<'hir>,
449 let def_id = self.resolver.local_def_id(owner);
451 let current_attrs = std::mem::take(&mut self.attrs);
452 let current_bodies = std::mem::take(&mut self.bodies);
453 let current_node_ids = std::mem::take(&mut self.local_node_ids);
454 let current_owner = std::mem::replace(&mut self.current_hir_id_owner, def_id);
455 let current_local_counter =
456 std::mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1));
458 // Always allocate the first `HirId` for the owner itself.
459 let _old = self.node_id_to_hir_id.insert(owner, hir::HirId::make_owner(def_id));
460 debug_assert_eq!(_old, None);
461 self.local_node_ids.push(owner);
464 debug_assert_eq!(def_id, item.def_id());
465 let info = self.make_owner_info(item);
467 self.attrs = current_attrs;
468 self.bodies = current_bodies;
469 self.local_node_ids = current_node_ids;
470 self.current_hir_id_owner = current_owner;
471 self.item_local_id_counter = current_local_counter;
473 let _old = self.owners.insert(def_id, info);
474 debug_assert!(_old.is_none());
479 fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> hir::OwnerInfo<'hir> {
480 let attrs = std::mem::take(&mut self.attrs);
481 let mut bodies = std::mem::take(&mut self.bodies);
482 let local_node_ids = std::mem::take(&mut self.local_node_ids);
483 let trait_map = local_node_ids
485 .filter_map(|node_id| {
486 let hir_id = self.node_id_to_hir_id[node_id]?;
487 let traits = self.resolver.take_trait_map(node_id)?;
488 Some((hir_id.local_id, traits.into_boxed_slice()))
492 #[cfg(debug_assertions)]
493 for (id, attrs) in attrs.iter() {
494 // Verify that we do not store empty slices in the map.
495 if attrs.is_empty() {
496 panic!("Stored empty attributes for {:?}", id);
500 bodies.sort_by_key(|(k, _)| *k);
501 let bodies = SortedMap::from_presorted_elements(bodies);
502 let (hash_including_bodies, hash_without_bodies) = self.hash_owner(node, &bodies);
503 let (nodes, parenting) =
504 index::index_hir(self.sess, self.resolver.definitions(), node, &bodies);
505 let nodes = hir::OwnerNodes { hash_including_bodies, hash_without_bodies, nodes, bodies };
507 let mut hcx = self.resolver.create_stable_hashing_context();
508 let mut stable_hasher = StableHasher::new();
509 attrs.hash_stable(&mut hcx, &mut stable_hasher);
510 let hash = stable_hasher.finish();
511 hir::AttributeMap { map: attrs, hash }
514 hir::OwnerInfo { nodes, parenting, attrs, trait_map }
517 /// Hash the HIR node twice, one deep and one shallow hash. This allows to differentiate
518 /// queries which depend on the full HIR tree and those which only depend on the item signature.
521 node: hir::OwnerNode<'hir>,
522 bodies: &SortedMap<hir::ItemLocalId, &'hir hir::Body<'hir>>,
523 ) -> (Fingerprint, Fingerprint) {
524 let mut hcx = self.resolver.create_stable_hashing_context();
525 let mut stable_hasher = StableHasher::new();
526 hcx.with_hir_bodies(true, node.def_id(), bodies, |hcx| {
527 node.hash_stable(hcx, &mut stable_hasher)
529 let hash_including_bodies = stable_hasher.finish();
530 let mut stable_hasher = StableHasher::new();
531 hcx.with_hir_bodies(false, node.def_id(), bodies, |hcx| {
532 node.hash_stable(hcx, &mut stable_hasher)
534 let hash_without_bodies = stable_hasher.finish();
535 (hash_including_bodies, hash_without_bodies)
538 /// This method allocates a new `HirId` for the given `NodeId` and stores it in
539 /// the `LoweringContext`'s `NodeId => HirId` map.
540 /// Take care not to call this method if the resulting `HirId` is then not
541 /// actually used in the HIR, as that would trigger an assertion in the
542 /// `HirIdValidator` later on, which makes sure that all `NodeId`s got mapped
543 /// properly. Calling the method twice with the same `NodeId` is fine though.
544 fn lower_node_id(&mut self, ast_node_id: NodeId) -> hir::HirId {
545 assert_ne!(ast_node_id, DUMMY_NODE_ID);
547 *self.node_id_to_hir_id.get_or_insert_with(ast_node_id, || {
548 // Generate a new `HirId`.
549 let owner = self.current_hir_id_owner;
550 let local_id = self.item_local_id_counter;
551 self.item_local_id_counter.increment_by(1);
552 self.local_node_ids.push(ast_node_id);
553 hir::HirId { owner, local_id }
557 fn next_id(&mut self) -> hir::HirId {
558 let node_id = self.resolver.next_node_id();
559 self.lower_node_id(node_id)
562 fn lower_res(&mut self, res: Res<NodeId>) -> Res {
564 self.node_id_to_hir_id.get(id).copied().flatten().unwrap_or_else(|| {
565 panic!("expected `NodeId` to be lowered already for res {:#?}", res);
570 fn expect_full_res(&mut self, id: NodeId) -> Res<NodeId> {
571 self.resolver.get_partial_res(id).map_or(Res::Err, |pr| {
572 if pr.unresolved_segments() != 0 {
573 panic!("path not fully resolved: {:?}", pr);
579 fn expect_full_res_from_use(&mut self, id: NodeId) -> impl Iterator<Item = Res<NodeId>> {
580 self.resolver.get_import_res(id).present_items()
583 fn diagnostic(&self) -> &rustc_errors::Handler {
584 self.sess.diagnostic()
587 /// Reuses the span but adds information like the kind of the desugaring and features that are
588 /// allowed inside this span.
589 fn mark_span_with_reason(
591 reason: DesugaringKind,
593 allow_internal_unstable: Option<Lrc<[Symbol]>>,
595 span.mark_with_reason(
596 allow_internal_unstable,
599 self.resolver.create_stable_hashing_context(),
603 fn with_anonymous_lifetime_mode<R>(
605 anonymous_lifetime_mode: AnonymousLifetimeMode,
606 op: impl FnOnce(&mut Self) -> R,
609 "with_anonymous_lifetime_mode(anonymous_lifetime_mode={:?})",
610 anonymous_lifetime_mode,
612 let old_anonymous_lifetime_mode = self.anonymous_lifetime_mode;
613 self.anonymous_lifetime_mode = anonymous_lifetime_mode;
614 let result = op(self);
615 self.anonymous_lifetime_mode = old_anonymous_lifetime_mode;
617 "with_anonymous_lifetime_mode: restoring anonymous_lifetime_mode={:?}",
618 old_anonymous_lifetime_mode
623 /// Intercept all spans entering HIR.
624 /// Mark a span as relative to the current owning item.
625 fn lower_span(&self, span: Span) -> Span {
626 if self.sess.opts.debugging_opts.incremental_relative_spans {
627 span.with_parent(Some(self.current_hir_id_owner))
629 // Do not make spans relative when not using incremental compilation.
634 fn lower_ident(&self, ident: Ident) -> Ident {
635 Ident::new(ident.name, self.lower_span(ident.span))
638 /// Creates a new `hir::GenericParam` for every new lifetime and
639 /// type parameter encountered while evaluating `f`. Definitions
640 /// are created with the parent provided. If no `parent_id` is
641 /// provided, no definitions will be returned.
643 /// Presuming that in-band lifetimes are enabled, then
644 /// `self.anonymous_lifetime_mode` will be updated to match the
645 /// parameter while `f` is running (and restored afterwards).
646 fn collect_in_band_defs<T>(
648 parent_def_id: LocalDefId,
649 anonymous_lifetime_mode: AnonymousLifetimeMode,
650 f: impl FnOnce(&mut Self) -> (Vec<hir::GenericParam<'hir>>, T),
651 ) -> (Vec<hir::GenericParam<'hir>>, T) {
652 assert!(!self.is_collecting_in_band_lifetimes);
653 assert!(self.lifetimes_to_define.is_empty());
654 let old_anonymous_lifetime_mode = self.anonymous_lifetime_mode;
656 self.anonymous_lifetime_mode = anonymous_lifetime_mode;
657 self.is_collecting_in_band_lifetimes = true;
659 let (in_band_ty_params, res) = f(self);
661 self.is_collecting_in_band_lifetimes = false;
662 self.anonymous_lifetime_mode = old_anonymous_lifetime_mode;
664 let lifetimes_to_define = self.lifetimes_to_define.split_off(0);
666 let params = lifetimes_to_define
668 .map(|(span, hir_name)| self.lifetime_to_generic_param(span, hir_name, parent_def_id))
669 .chain(in_band_ty_params.into_iter())
675 /// Converts a lifetime into a new generic parameter.
676 fn lifetime_to_generic_param(
680 parent_def_id: LocalDefId,
681 ) -> hir::GenericParam<'hir> {
682 let node_id = self.resolver.next_node_id();
684 // Get the name we'll use to make the def-path. Note
685 // that collisions are ok here and this shouldn't
686 // really show up for end-user.
687 let (str_name, kind) = match hir_name {
688 ParamName::Plain(ident) => (ident.name, hir::LifetimeParamKind::InBand),
689 ParamName::Fresh(_) => (kw::UnderscoreLifetime, hir::LifetimeParamKind::Elided),
690 ParamName::Error => (kw::UnderscoreLifetime, hir::LifetimeParamKind::Error),
693 // Add a definition for the in-band lifetime def.
694 self.resolver.create_def(
697 DefPathData::LifetimeNs(str_name),
699 span.with_parent(None),
703 hir_id: self.lower_node_id(node_id),
706 span: self.lower_span(span),
707 pure_wrt_drop: false,
708 kind: hir::GenericParamKind::Lifetime { kind },
712 /// When there is a reference to some lifetime `'a`, and in-band
713 /// lifetimes are enabled, then we want to push that lifetime into
714 /// the vector of names to define later. In that case, it will get
715 /// added to the appropriate generics.
716 fn maybe_collect_in_band_lifetime(&mut self, ident: Ident) {
717 if !self.is_collecting_in_band_lifetimes {
721 if !self.sess.features_untracked().in_band_lifetimes {
725 if self.in_scope_lifetimes.contains(&ParamName::Plain(ident.normalize_to_macros_2_0())) {
729 let hir_name = ParamName::Plain(ident);
731 if self.lifetimes_to_define.iter().any(|(_, lt_name)| {
732 lt_name.normalize_to_macros_2_0() == hir_name.normalize_to_macros_2_0()
737 self.lifetimes_to_define.push((ident.span, hir_name));
740 /// When we have either an elided or `'_` lifetime in an impl
741 /// header, we convert it to an in-band lifetime.
742 fn collect_fresh_in_band_lifetime(&mut self, span: Span) -> ParamName {
743 assert!(self.is_collecting_in_band_lifetimes);
744 let index = self.lifetimes_to_define.len() + self.in_scope_lifetimes.len();
745 let hir_name = ParamName::Fresh(index);
746 self.lifetimes_to_define.push((span, hir_name));
750 // Evaluates `f` with the lifetimes in `params` in-scope.
751 // This is used to track which lifetimes have already been defined, and
752 // which are new in-band lifetimes that need to have a definition created
754 fn with_in_scope_lifetime_defs<T>(
756 params: &[GenericParam],
757 f: impl FnOnce(&mut Self) -> T,
759 let old_len = self.in_scope_lifetimes.len();
760 let lt_def_names = params.iter().filter_map(|param| match param.kind {
761 GenericParamKind::Lifetime { .. } => {
762 Some(ParamName::Plain(param.ident.normalize_to_macros_2_0()))
766 self.in_scope_lifetimes.extend(lt_def_names);
770 self.in_scope_lifetimes.truncate(old_len);
774 /// Appends in-band lifetime defs and argument-position `impl
775 /// Trait` defs to the existing set of generics.
777 /// Presuming that in-band lifetimes are enabled, then
778 /// `self.anonymous_lifetime_mode` will be updated to match the
779 /// parameter while `f` is running (and restored afterwards).
780 fn add_in_band_defs<T>(
783 parent_def_id: LocalDefId,
784 anonymous_lifetime_mode: AnonymousLifetimeMode,
785 f: impl FnOnce(&mut Self, &mut Vec<hir::GenericParam<'hir>>) -> T,
786 ) -> (hir::Generics<'hir>, T) {
787 let (in_band_defs, (mut lowered_generics, res)) =
788 self.with_in_scope_lifetime_defs(&generics.params, |this| {
789 this.collect_in_band_defs(parent_def_id, anonymous_lifetime_mode, |this| {
790 let mut params = Vec::new();
791 // Note: it is necessary to lower generics *before* calling `f`.
792 // When lowering `async fn`, there's a final step when lowering
793 // the return type that assumes that all in-scope lifetimes have
794 // already been added to either `in_scope_lifetimes` or
795 // `lifetimes_to_define`. If we swapped the order of these two,
796 // in-band-lifetimes introduced by generics or where-clauses
797 // wouldn't have been added yet.
798 let generics = this.lower_generics_mut(
800 ImplTraitContext::Universal(&mut params, this.current_hir_id_owner),
802 let res = f(this, &mut params);
803 (params, (generics, res))
807 lowered_generics.params.extend(in_band_defs);
809 let lowered_generics = lowered_generics.into_generics(self.arena);
810 (lowered_generics, res)
813 fn with_dyn_type_scope<T>(&mut self, in_scope: bool, f: impl FnOnce(&mut Self) -> T) -> T {
814 let was_in_dyn_type = self.is_in_dyn_type;
815 self.is_in_dyn_type = in_scope;
817 let result = f(self);
819 self.is_in_dyn_type = was_in_dyn_type;
824 fn with_new_scopes<T>(&mut self, f: impl FnOnce(&mut Self) -> T) -> T {
825 let was_in_loop_condition = self.is_in_loop_condition;
826 self.is_in_loop_condition = false;
828 let catch_scope = self.catch_scope.take();
829 let loop_scope = self.loop_scope.take();
831 self.catch_scope = catch_scope;
832 self.loop_scope = loop_scope;
834 self.is_in_loop_condition = was_in_loop_condition;
839 fn lower_attrs(&mut self, id: hir::HirId, attrs: &[Attribute]) -> Option<&'hir [Attribute]> {
840 if attrs.is_empty() {
843 debug_assert_eq!(id.owner, self.current_hir_id_owner);
844 let ret = self.arena.alloc_from_iter(attrs.iter().map(|a| self.lower_attr(a)));
845 debug_assert!(!ret.is_empty());
846 self.attrs.insert(id.local_id, ret);
851 fn lower_attr(&self, attr: &Attribute) -> Attribute {
852 // Note that we explicitly do not walk the path. Since we don't really
853 // lower attributes (we use the AST version) there is nowhere to keep
854 // the `HirId`s. We don't actually need HIR version of attributes anyway.
855 // Tokens are also not needed after macro expansion and parsing.
856 let kind = match attr.kind {
857 AttrKind::Normal(ref item, _) => AttrKind::Normal(
859 path: item.path.clone(),
860 args: self.lower_mac_args(&item.args),
865 AttrKind::DocComment(comment_kind, data) => AttrKind::DocComment(comment_kind, data),
868 Attribute { kind, id: attr.id, style: attr.style, span: self.lower_span(attr.span) }
871 fn alias_attrs(&mut self, id: hir::HirId, target_id: hir::HirId) {
872 debug_assert_eq!(id.owner, self.current_hir_id_owner);
873 debug_assert_eq!(target_id.owner, self.current_hir_id_owner);
874 if let Some(&a) = self.attrs.get(&target_id.local_id) {
875 debug_assert!(!a.is_empty());
876 self.attrs.insert(id.local_id, a);
880 fn lower_mac_args(&self, args: &MacArgs) -> MacArgs {
882 MacArgs::Empty => MacArgs::Empty,
883 MacArgs::Delimited(dspan, delim, ref tokens) => {
884 // This is either a non-key-value attribute, or a `macro_rules!` body.
885 // We either not have any nonterminals present (in the case of an attribute),
886 // or have tokens available for all nonterminals in the case of a nested
887 // `macro_rules`: e.g:
890 // macro_rules! outer {
892 // macro_rules! inner {
899 // In both cases, we don't want to synthesize any tokens
903 self.lower_token_stream(tokens.clone(), CanSynthesizeMissingTokens::No),
906 // This is an inert key-value attribute - it will never be visible to macros
907 // after it gets lowered to HIR. Therefore, we can synthesize tokens with fake
908 // spans to handle nonterminals in `#[doc]` (e.g. `#[doc = $e]`).
909 MacArgs::Eq(eq_span, ref token) => {
910 // In valid code the value is always representable as a single literal token.
911 fn unwrap_single_token(sess: &Session, tokens: TokenStream, span: Span) -> Token {
912 if tokens.len() != 1 {
914 .delay_span_bug(span, "multiple tokens in key-value attribute's value");
916 match tokens.into_trees().next() {
917 Some(TokenTree::Token(token)) => token,
918 Some(TokenTree::Delimited(_, delim, tokens)) => {
919 if delim != token::NoDelim {
920 sess.diagnostic().delay_span_bug(
922 "unexpected delimiter in key-value attribute's value",
925 unwrap_single_token(sess, tokens, span)
927 None => Token::dummy(),
931 let tokens = FlattenNonterminals {
932 parse_sess: &self.sess.parse_sess,
933 synthesize_tokens: CanSynthesizeMissingTokens::Yes,
934 nt_to_tokenstream: self.nt_to_tokenstream,
936 .process_token(token.clone());
937 MacArgs::Eq(eq_span, unwrap_single_token(self.sess, tokens, token.span))
942 fn lower_token_stream(
945 synthesize_tokens: CanSynthesizeMissingTokens,
947 FlattenNonterminals {
948 parse_sess: &self.sess.parse_sess,
950 nt_to_tokenstream: self.nt_to_tokenstream,
952 .process_token_stream(tokens)
955 /// Given an associated type constraint like one of these:
958 /// T: Iterator<Item: Debug>
960 /// T: Iterator<Item = Debug>
964 /// returns a `hir::TypeBinding` representing `Item`.
965 fn lower_assoc_ty_constraint(
967 constraint: &AssocTyConstraint,
968 mut itctx: ImplTraitContext<'_, 'hir>,
969 ) -> hir::TypeBinding<'hir> {
970 debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx);
972 // lower generic arguments of identifier in constraint
973 let gen_args = if let Some(ref gen_args) = constraint.gen_args {
974 let gen_args_ctor = match gen_args {
975 GenericArgs::AngleBracketed(ref data) => {
976 self.lower_angle_bracketed_parameter_data(
983 GenericArgs::Parenthesized(ref data) => {
984 let mut err = self.sess.struct_span_err(
986 "parenthesized generic arguments cannot be used in associated type constraints"
988 // FIXME: try to write a suggestion here
990 self.lower_angle_bracketed_parameter_data(
991 &data.as_angle_bracketed_args(),
998 gen_args_ctor.into_generic_args(self)
1000 self.arena.alloc(hir::GenericArgs::none())
1003 let kind = match constraint.kind {
1004 AssocTyConstraintKind::Equality { ref ty } => {
1005 hir::TypeBindingKind::Equality { ty: self.lower_ty(ty, itctx) }
1007 AssocTyConstraintKind::Bound { ref bounds } => {
1008 let mut capturable_lifetimes;
1009 let mut parent_def_id = self.current_hir_id_owner;
1010 // Piggy-back on the `impl Trait` context to figure out the correct behavior.
1011 let (desugar_to_impl_trait, itctx) = match itctx {
1012 // We are in the return position:
1014 // fn foo() -> impl Iterator<Item: Debug>
1018 // fn foo() -> impl Iterator<Item = impl Debug>
1019 ImplTraitContext::ReturnPositionOpaqueTy { .. }
1020 | ImplTraitContext::TypeAliasesOpaqueTy { .. } => (true, itctx),
1022 // We are in the argument position, but within a dyn type:
1024 // fn foo(x: dyn Iterator<Item: Debug>)
1028 // fn foo(x: dyn Iterator<Item = impl Debug>)
1029 ImplTraitContext::Universal(_, parent) if self.is_in_dyn_type => {
1030 parent_def_id = parent;
1034 // In `type Foo = dyn Iterator<Item: Debug>` we desugar to
1035 // `type Foo = dyn Iterator<Item = impl Debug>` but we have to override the
1036 // "impl trait context" to permit `impl Debug` in this position (it desugars
1037 // then to an opaque type).
1039 // FIXME: this is only needed until `impl Trait` is allowed in type aliases.
1040 ImplTraitContext::Disallowed(_) if self.is_in_dyn_type => {
1041 capturable_lifetimes = FxHashSet::default();
1044 ImplTraitContext::TypeAliasesOpaqueTy {
1045 capturable_lifetimes: &mut capturable_lifetimes,
1050 // We are in the parameter position, but not within a dyn type:
1052 // fn foo(x: impl Iterator<Item: Debug>)
1054 // so we leave it as is and this gets expanded in astconv to a bound like
1055 // `<T as Iterator>::Item: Debug` where `T` is the type parameter for the
1057 _ => (false, itctx),
1060 if desugar_to_impl_trait {
1061 // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by
1062 // constructing the HIR for `impl bounds...` and then lowering that.
1064 let impl_trait_node_id = self.resolver.next_node_id();
1065 self.resolver.create_def(
1068 DefPathData::ImplTrait,
1073 self.with_dyn_type_scope(false, |this| {
1074 let node_id = this.resolver.next_node_id();
1075 let ty = this.lower_ty(
1078 kind: TyKind::ImplTrait(impl_trait_node_id, bounds.clone()),
1079 span: this.lower_span(constraint.span),
1085 hir::TypeBindingKind::Equality { ty }
1088 // Desugar `AssocTy: Bounds` into a type binding where the
1089 // later desugars into a trait predicate.
1090 let bounds = self.lower_param_bounds(bounds, itctx);
1092 hir::TypeBindingKind::Constraint { bounds }
1098 hir_id: self.lower_node_id(constraint.id),
1099 ident: self.lower_ident(constraint.ident),
1102 span: self.lower_span(constraint.span),
1106 fn lower_generic_arg(
1108 arg: &ast::GenericArg,
1109 itctx: ImplTraitContext<'_, 'hir>,
1110 ) -> hir::GenericArg<'hir> {
1112 ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(<)),
1113 ast::GenericArg::Type(ty) => {
1115 TyKind::Infer if self.sess.features_untracked().generic_arg_infer => {
1116 return GenericArg::Infer(hir::InferArg {
1117 hir_id: self.lower_node_id(ty.id),
1118 span: self.lower_span(ty.span),
1119 kind: InferKind::Type,
1122 // We parse const arguments as path types as we cannot distinguish them during
1123 // parsing. We try to resolve that ambiguity by attempting resolution in both the
1124 // type and value namespaces. If we resolved the path in the value namespace, we
1125 // transform it into a generic const argument.
1126 TyKind::Path(ref qself, ref path) => {
1127 if let Some(partial_res) = self.resolver.get_partial_res(ty.id) {
1128 let res = partial_res.base_res();
1129 if !res.matches_ns(Namespace::TypeNS) {
1131 "lower_generic_arg: Lowering type argument as const argument: {:?}",
1135 // Construct an AnonConst where the expr is the "ty"'s path.
1137 let parent_def_id = self.current_hir_id_owner;
1138 let node_id = self.resolver.next_node_id();
1140 // Add a definition for the in-band const def.
1141 self.resolver.create_def(
1144 DefPathData::AnonConst,
1149 let span = self.lower_span(ty.span);
1150 let path_expr = Expr {
1152 kind: ExprKind::Path(qself.clone(), path.clone()),
1154 attrs: AttrVec::new(),
1158 let ct = self.with_new_scopes(|this| hir::AnonConst {
1159 hir_id: this.lower_node_id(node_id),
1160 body: this.lower_const_body(path_expr.span, Some(&path_expr)),
1162 return GenericArg::Const(ConstArg { value: ct, span });
1168 GenericArg::Type(self.lower_ty_direct(&ty, itctx))
1170 ast::GenericArg::Const(ct) => GenericArg::Const(ConstArg {
1171 value: self.lower_anon_const(&ct),
1172 span: self.lower_span(ct.value.span),
1177 fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext<'_, 'hir>) -> &'hir hir::Ty<'hir> {
1178 self.arena.alloc(self.lower_ty_direct(t, itctx))
1184 qself: &Option<QSelf>,
1186 param_mode: ParamMode,
1187 itctx: ImplTraitContext<'_, 'hir>,
1188 ) -> hir::Ty<'hir> {
1189 let id = self.lower_node_id(t.id);
1190 let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx);
1191 let ty = self.ty_path(id, t.span, qpath);
1192 if let hir::TyKind::TraitObject(..) = ty.kind {
1193 self.maybe_lint_bare_trait(t.span, t.id, qself.is_none() && path.is_global());
1198 fn ty(&mut self, span: Span, kind: hir::TyKind<'hir>) -> hir::Ty<'hir> {
1199 hir::Ty { hir_id: self.next_id(), kind, span: self.lower_span(span) }
1202 fn ty_tup(&mut self, span: Span, tys: &'hir [hir::Ty<'hir>]) -> hir::Ty<'hir> {
1203 self.ty(span, hir::TyKind::Tup(tys))
1206 fn lower_ty_direct(&mut self, t: &Ty, mut itctx: ImplTraitContext<'_, 'hir>) -> hir::Ty<'hir> {
1207 let kind = match t.kind {
1208 TyKind::Infer => hir::TyKind::Infer,
1209 TyKind::Err => hir::TyKind::Err,
1210 TyKind::Slice(ref ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)),
1211 TyKind::Ptr(ref mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)),
1212 TyKind::Rptr(ref region, ref mt) => {
1213 let span = self.sess.source_map().next_point(t.span.shrink_to_lo());
1214 let lifetime = match *region {
1215 Some(ref lt) => self.lower_lifetime(lt),
1216 None => self.elided_ref_lifetime(span),
1218 hir::TyKind::Rptr(lifetime, self.lower_mt(mt, itctx))
1220 TyKind::BareFn(ref f) => self.with_in_scope_lifetime_defs(&f.generic_params, |this| {
1221 this.with_anonymous_lifetime_mode(AnonymousLifetimeMode::PassThrough, |this| {
1222 hir::TyKind::BareFn(this.arena.alloc(hir::BareFnTy {
1223 generic_params: this.lower_generic_params(
1225 ImplTraitContext::disallowed(),
1227 unsafety: this.lower_unsafety(f.unsafety),
1228 abi: this.lower_extern(f.ext),
1229 decl: this.lower_fn_decl(&f.decl, None, false, None),
1230 param_names: this.lower_fn_params_to_names(&f.decl),
1234 TyKind::Never => hir::TyKind::Never,
1235 TyKind::Tup(ref tys) => {
1236 hir::TyKind::Tup(self.arena.alloc_from_iter(
1237 tys.iter().map(|ty| self.lower_ty_direct(ty, itctx.reborrow())),
1240 TyKind::Paren(ref ty) => {
1241 return self.lower_ty_direct(ty, itctx);
1243 TyKind::Path(ref qself, ref path) => {
1244 return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx);
1246 TyKind::ImplicitSelf => {
1247 let res = self.expect_full_res(t.id);
1248 let res = self.lower_res(res);
1249 hir::TyKind::Path(hir::QPath::Resolved(
1251 self.arena.alloc(hir::Path {
1253 segments: arena_vec![self; hir::PathSegment::from_ident(
1254 Ident::with_dummy_span(kw::SelfUpper)
1256 span: self.lower_span(t.span),
1260 TyKind::Array(ref ty, ref length) => {
1261 hir::TyKind::Array(self.lower_ty(ty, itctx), self.lower_anon_const(length))
1263 TyKind::Typeof(ref expr) => hir::TyKind::Typeof(self.lower_anon_const(expr)),
1264 TyKind::TraitObject(ref bounds, kind) => {
1265 let mut lifetime_bound = None;
1266 let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
1268 this.arena.alloc_from_iter(bounds.iter().filter_map(
1269 |bound| match *bound {
1270 GenericBound::Trait(
1272 TraitBoundModifier::None | TraitBoundModifier::MaybeConst,
1273 ) => Some(this.lower_poly_trait_ref(ty, itctx.reborrow())),
1274 // `~const ?Bound` will cause an error during AST validation
1275 // anyways, so treat it like `?Bound` as compilation proceeds.
1276 GenericBound::Trait(
1278 TraitBoundModifier::Maybe | TraitBoundModifier::MaybeConstMaybe,
1280 GenericBound::Outlives(ref lifetime) => {
1281 if lifetime_bound.is_none() {
1282 lifetime_bound = Some(this.lower_lifetime(lifetime));
1288 let lifetime_bound =
1289 lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));
1290 (bounds, lifetime_bound)
1292 if kind != TraitObjectSyntax::Dyn {
1293 self.maybe_lint_bare_trait(t.span, t.id, false);
1295 hir::TyKind::TraitObject(bounds, lifetime_bound, kind)
1297 TyKind::ImplTrait(def_node_id, ref bounds) => {
1300 ImplTraitContext::ReturnPositionOpaqueTy { fn_def_id, origin } => self
1301 .lower_opaque_impl_trait(
1307 |this| this.lower_param_bounds(bounds, itctx),
1309 ImplTraitContext::TypeAliasesOpaqueTy { ref capturable_lifetimes } => {
1310 // Reset capturable lifetimes, any nested impl trait
1311 // types will inherit lifetimes from this opaque type,
1312 // so don't need to capture them again.
1313 let nested_itctx = ImplTraitContext::TypeAliasesOpaqueTy {
1314 capturable_lifetimes: &mut FxHashSet::default(),
1316 self.lower_opaque_impl_trait(
1319 hir::OpaqueTyOrigin::TyAlias,
1321 Some(capturable_lifetimes),
1322 |this| this.lower_param_bounds(bounds, nested_itctx),
1325 ImplTraitContext::Universal(in_band_ty_params, parent_def_id) => {
1326 // Add a definition for the in-band `Param`.
1327 let def_id = self.resolver.local_def_id(def_node_id);
1329 let hir_bounds = self.lower_param_bounds(
1331 ImplTraitContext::Universal(in_band_ty_params, parent_def_id),
1333 // Set the name to `impl Bound1 + Bound2`.
1334 let ident = Ident::from_str_and_span(&pprust::ty_to_string(t), span);
1335 in_band_ty_params.push(hir::GenericParam {
1336 hir_id: self.lower_node_id(def_node_id),
1337 name: ParamName::Plain(self.lower_ident(ident)),
1338 pure_wrt_drop: false,
1340 span: self.lower_span(span),
1341 kind: hir::GenericParamKind::Type {
1343 synthetic: Some(hir::SyntheticTyParamKind::ImplTrait),
1347 hir::TyKind::Path(hir::QPath::Resolved(
1349 self.arena.alloc(hir::Path {
1350 span: self.lower_span(span),
1351 res: Res::Def(DefKind::TyParam, def_id.to_def_id()),
1352 segments: arena_vec![self; hir::PathSegment::from_ident(self.lower_ident(ident))],
1356 ImplTraitContext::Disallowed(_) => {
1357 let mut err = struct_span_err!(
1361 "`impl Trait` not allowed outside of {}",
1362 "function and method return types",
1369 TyKind::MacCall(_) => panic!("`TyKind::MacCall` should have been expanded by now"),
1370 TyKind::CVarArgs => {
1371 self.sess.delay_span_bug(
1373 "`TyKind::CVarArgs` should have been handled elsewhere",
1379 hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.lower_node_id(t.id) }
1382 fn lower_opaque_impl_trait(
1385 fn_def_id: Option<DefId>,
1386 origin: hir::OpaqueTyOrigin,
1387 opaque_ty_node_id: NodeId,
1388 capturable_lifetimes: Option<&FxHashSet<hir::LifetimeName>>,
1389 lower_bounds: impl FnOnce(&mut Self) -> hir::GenericBounds<'hir>,
1390 ) -> hir::TyKind<'hir> {
1392 "lower_opaque_impl_trait(fn_def_id={:?}, opaque_ty_node_id={:?}, span={:?})",
1393 fn_def_id, opaque_ty_node_id, span,
1396 // Make sure we know that some funky desugaring has been going on here.
1397 // This is a first: there is code in other places like for loop
1398 // desugaring that explicitly states that we don't want to track that.
1399 // Not tracking it makes lints in rustc and clippy very fragile, as
1400 // frequently opened issues show.
1401 let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None);
1403 let opaque_ty_def_id = self.resolver.local_def_id(opaque_ty_node_id);
1405 let mut collected_lifetimes = Vec::new();
1406 self.with_hir_id_owner(opaque_ty_node_id, |lctx| {
1407 let hir_bounds = lower_bounds(lctx);
1409 collected_lifetimes = lifetimes_from_impl_trait_bounds(
1412 capturable_lifetimes,
1416 lctx.arena.alloc_from_iter(collected_lifetimes.iter().map(|&(name, span)| {
1417 let def_node_id = lctx.resolver.next_node_id();
1418 let hir_id = lctx.lower_node_id(def_node_id);
1419 lctx.resolver.create_def(
1422 DefPathData::LifetimeNs(name.ident().name),
1424 span.with_parent(None),
1427 let (name, kind) = match name {
1428 hir::LifetimeName::Underscore => (
1429 hir::ParamName::Plain(Ident::with_dummy_span(kw::UnderscoreLifetime)),
1430 hir::LifetimeParamKind::Elided,
1432 hir::LifetimeName::Param(param_name) => {
1433 (param_name, hir::LifetimeParamKind::Explicit)
1435 _ => panic!("expected `LifetimeName::Param` or `ParamName::Plain`"),
1442 pure_wrt_drop: false,
1444 kind: hir::GenericParamKind::Lifetime { kind },
1448 debug!("lower_opaque_impl_trait: lifetime_defs={:#?}", lifetime_defs);
1450 let opaque_ty_item = hir::OpaqueTy {
1451 generics: hir::Generics {
1452 params: lifetime_defs,
1453 where_clause: hir::WhereClause { predicates: &[], span: lctx.lower_span(span) },
1454 span: lctx.lower_span(span),
1457 impl_trait_fn: fn_def_id,
1461 trace!("lower_opaque_impl_trait: {:#?}", opaque_ty_def_id);
1462 lctx.generate_opaque_type(opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span)
1466 self.arena.alloc_from_iter(collected_lifetimes.into_iter().map(|(name, span)| {
1467 hir::GenericArg::Lifetime(hir::Lifetime { hir_id: self.next_id(), span, name })
1470 debug!("lower_opaque_impl_trait: lifetimes={:#?}", lifetimes);
1472 // `impl Trait` now just becomes `Foo<'a, 'b, ..>`.
1473 hir::TyKind::OpaqueDef(hir::ItemId { def_id: opaque_ty_def_id }, lifetimes)
1476 /// Registers a new opaque type with the proper `NodeId`s and
1477 /// returns the lowered node-ID for the opaque type.
1478 fn generate_opaque_type(
1480 opaque_ty_id: LocalDefId,
1481 opaque_ty_item: hir::OpaqueTy<'hir>,
1483 opaque_ty_span: Span,
1484 ) -> hir::OwnerNode<'hir> {
1485 let opaque_ty_item_kind = hir::ItemKind::OpaqueTy(opaque_ty_item);
1486 // Generate an `type Foo = impl Trait;` declaration.
1487 trace!("registering opaque type with id {:#?}", opaque_ty_id);
1488 let opaque_ty_item = hir::Item {
1489 def_id: opaque_ty_id,
1490 ident: Ident::empty(),
1491 kind: opaque_ty_item_kind,
1492 vis: respan(self.lower_span(span.shrink_to_lo()), hir::VisibilityKind::Inherited),
1493 span: self.lower_span(opaque_ty_span),
1495 hir::OwnerNode::Item(self.arena.alloc(opaque_ty_item))
1498 fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Ident] {
1499 // Skip the `...` (`CVarArgs`) trailing arguments from the AST,
1500 // as they are not explicit in HIR/Ty function signatures.
1501 // (instead, the `c_variadic` flag is set to `true`)
1502 let mut inputs = &decl.inputs[..];
1503 if decl.c_variadic() {
1504 inputs = &inputs[..inputs.len() - 1];
1506 self.arena.alloc_from_iter(inputs.iter().map(|param| match param.pat.kind {
1507 PatKind::Ident(_, ident, _) => self.lower_ident(ident),
1508 _ => Ident::new(kw::Empty, self.lower_span(param.pat.span)),
1512 // Lowers a function declaration.
1514 // `decl`: the unlowered (AST) function declaration.
1515 // `fn_def_id`: if `Some`, impl Trait arguments are lowered into generic parameters on the
1516 // given DefId, otherwise impl Trait is disallowed. Must be `Some` if
1517 // `make_ret_async` is also `Some`.
1518 // `impl_trait_return_allow`: determines whether `impl Trait` can be used in return position.
1519 // This guards against trait declarations and implementations where `impl Trait` is
1521 // `make_ret_async`: if `Some`, converts `-> T` into `-> impl Future<Output = T>` in the
1522 // return type. This is used for `async fn` declarations. The `NodeId` is the ID of the
1523 // return type `impl Trait` item.
1527 mut in_band_ty_params: Option<(DefId, &mut Vec<hir::GenericParam<'hir>>)>,
1528 impl_trait_return_allow: bool,
1529 make_ret_async: Option<NodeId>,
1530 ) -> &'hir hir::FnDecl<'hir> {
1534 in_band_ty_params: {:?}, \
1535 impl_trait_return_allow: {}, \
1536 make_ret_async: {:?})",
1537 decl, in_band_ty_params, impl_trait_return_allow, make_ret_async,
1539 let lt_mode = if make_ret_async.is_some() {
1540 // In `async fn`, argument-position elided lifetimes
1541 // must be transformed into fresh generic parameters so that
1542 // they can be applied to the opaque `impl Trait` return type.
1543 AnonymousLifetimeMode::CreateParameter
1545 self.anonymous_lifetime_mode
1548 let c_variadic = decl.c_variadic();
1550 // Remember how many lifetimes were already around so that we can
1551 // only look at the lifetime parameters introduced by the arguments.
1552 let inputs = self.with_anonymous_lifetime_mode(lt_mode, |this| {
1553 // Skip the `...` (`CVarArgs`) trailing arguments from the AST,
1554 // as they are not explicit in HIR/Ty function signatures.
1555 // (instead, the `c_variadic` flag is set to `true`)
1556 let mut inputs = &decl.inputs[..];
1558 inputs = &inputs[..inputs.len() - 1];
1560 this.arena.alloc_from_iter(inputs.iter().map(|param| {
1561 if let Some((_, ibty)) = &mut in_band_ty_params {
1562 this.lower_ty_direct(
1564 ImplTraitContext::Universal(ibty, this.current_hir_id_owner),
1567 this.lower_ty_direct(¶m.ty, ImplTraitContext::disallowed())
1572 let output = if let Some(ret_id) = make_ret_async {
1573 self.lower_async_fn_ret_ty(
1575 in_band_ty_params.expect("`make_ret_async` but no `fn_def_id`").0,
1580 FnRetTy::Ty(ref ty) => {
1581 let context = match in_band_ty_params {
1582 Some((def_id, _)) if impl_trait_return_allow => {
1583 ImplTraitContext::ReturnPositionOpaqueTy {
1585 origin: hir::OpaqueTyOrigin::FnReturn,
1588 _ => ImplTraitContext::disallowed(),
1590 hir::FnRetTy::Return(self.lower_ty(ty, context))
1592 FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(span)),
1596 self.arena.alloc(hir::FnDecl {
1600 implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| {
1601 use BindingMode::{ByRef, ByValue};
1602 let is_mutable_pat = matches!(
1604 PatKind::Ident(ByValue(Mutability::Mut) | ByRef(Mutability::Mut), ..)
1608 TyKind::ImplicitSelf if is_mutable_pat => hir::ImplicitSelfKind::Mut,
1609 TyKind::ImplicitSelf => hir::ImplicitSelfKind::Imm,
1610 // Given we are only considering `ImplicitSelf` types, we needn't consider
1611 // the case where we have a mutable pattern to a reference as that would
1612 // no longer be an `ImplicitSelf`.
1613 TyKind::Rptr(_, ref mt)
1614 if mt.ty.kind.is_implicit_self() && mt.mutbl == ast::Mutability::Mut =>
1616 hir::ImplicitSelfKind::MutRef
1618 TyKind::Rptr(_, ref mt) if mt.ty.kind.is_implicit_self() => {
1619 hir::ImplicitSelfKind::ImmRef
1621 _ => hir::ImplicitSelfKind::None,
1627 // Transforms `-> T` for `async fn` into `-> OpaqueTy { .. }`
1628 // combined with the following definition of `OpaqueTy`:
1630 // type OpaqueTy<generics_from_parent_fn> = impl Future<Output = T>;
1632 // `inputs`: lowered types of parameters to the function (used to collect lifetimes)
1633 // `output`: unlowered output type (`T` in `-> T`)
1634 // `fn_def_id`: `DefId` of the parent function (used to create child impl trait definition)
1635 // `opaque_ty_node_id`: `NodeId` of the opaque `impl Trait` type that should be created
1636 // `elided_lt_replacement`: replacement for elided lifetimes in the return type
1637 fn lower_async_fn_ret_ty(
1641 opaque_ty_node_id: NodeId,
1642 ) -> hir::FnRetTy<'hir> {
1644 "lower_async_fn_ret_ty(\
1647 opaque_ty_node_id={:?})",
1648 output, fn_def_id, opaque_ty_node_id,
1651 let span = output.span();
1653 let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, span, None);
1655 let opaque_ty_def_id = self.resolver.local_def_id(opaque_ty_node_id);
1657 // When we create the opaque type for this async fn, it is going to have
1658 // to capture all the lifetimes involved in the signature (including in the
1659 // return type). This is done by introducing lifetime parameters for:
1661 // - all the explicitly declared lifetimes from the impl and function itself;
1662 // - all the elided lifetimes in the fn arguments;
1663 // - all the elided lifetimes in the return type.
1665 // So for example in this snippet:
1668 // impl<'a> Foo<'a> {
1669 // async fn bar<'b>(&self, x: &'b Vec<f64>, y: &str) -> &u32 {
1670 // // ^ '0 ^ '1 ^ '2
1671 // // elided lifetimes used below
1676 // we would create an opaque type like:
1679 // type Bar<'a, 'b, '0, '1, '2> = impl Future<Output = &'2 u32>;
1682 // and we would then desugar `bar` to the equivalent of:
1685 // impl<'a> Foo<'a> {
1686 // fn bar<'b, '0, '1>(&'0 self, x: &'b Vec<f64>, y: &'1 str) -> Bar<'a, 'b, '0, '1, '_>
1690 // Note that the final parameter to `Bar` is `'_`, not `'2` --
1691 // this is because the elided lifetimes from the return type
1692 // should be figured out using the ordinary elision rules, and
1693 // this desugaring achieves that.
1695 // The variable `input_lifetimes_count` tracks the number of
1696 // lifetime parameters to the opaque type *not counting* those
1697 // lifetimes elided in the return type. This includes those
1698 // that are explicitly declared (`in_scope_lifetimes`) and
1699 // those elided lifetimes we found in the arguments (current
1700 // content of `lifetimes_to_define`). Next, we will process
1701 // the return type, which will cause `lifetimes_to_define` to
1703 let input_lifetimes_count = self.in_scope_lifetimes.len() + self.lifetimes_to_define.len();
1705 let mut lifetime_params = Vec::new();
1706 self.with_hir_id_owner(opaque_ty_node_id, |this| {
1707 // We have to be careful to get elision right here. The
1708 // idea is that we create a lifetime parameter for each
1709 // lifetime in the return type. So, given a return type
1710 // like `async fn foo(..) -> &[&u32]`, we lower to `impl
1711 // Future<Output = &'1 [ &'2 u32 ]>`.
1713 // Then, we will create `fn foo(..) -> Foo<'_, '_>`, and
1714 // hence the elision takes place at the fn site.
1715 let future_bound = this
1716 .with_anonymous_lifetime_mode(AnonymousLifetimeMode::CreateParameter, |this| {
1717 this.lower_async_fn_output_type_to_future_bound(output, fn_def_id, span)
1720 debug!("lower_async_fn_ret_ty: future_bound={:#?}", future_bound);
1722 // Calculate all the lifetimes that should be captured
1723 // by the opaque type. This should include all in-scope
1724 // lifetime parameters, including those defined in-band.
1726 // Note: this must be done after lowering the output type,
1727 // as the output type may introduce new in-band lifetimes.
1728 lifetime_params = this
1732 .map(|name| (name.ident().span, name))
1733 .chain(this.lifetimes_to_define.iter().cloned())
1736 debug!("lower_async_fn_ret_ty: in_scope_lifetimes={:#?}", this.in_scope_lifetimes);
1737 debug!("lower_async_fn_ret_ty: lifetimes_to_define={:#?}", this.lifetimes_to_define);
1738 debug!("lower_async_fn_ret_ty: lifetime_params={:#?}", lifetime_params);
1740 let generic_params =
1741 this.arena.alloc_from_iter(lifetime_params.iter().map(|(span, hir_name)| {
1742 this.lifetime_to_generic_param(*span, *hir_name, opaque_ty_def_id)
1745 let opaque_ty_item = hir::OpaqueTy {
1746 generics: hir::Generics {
1747 params: generic_params,
1748 where_clause: hir::WhereClause { predicates: &[], span: this.lower_span(span) },
1749 span: this.lower_span(span),
1751 bounds: arena_vec![this; future_bound],
1752 impl_trait_fn: Some(fn_def_id),
1753 origin: hir::OpaqueTyOrigin::AsyncFn,
1756 trace!("exist ty from async fn def id: {:#?}", opaque_ty_def_id);
1757 this.generate_opaque_type(opaque_ty_def_id, opaque_ty_item, span, opaque_ty_span)
1760 // As documented above on the variable
1761 // `input_lifetimes_count`, we need to create the lifetime
1762 // arguments to our opaque type. Continuing with our example,
1763 // we're creating the type arguments for the return type:
1766 // Bar<'a, 'b, '0, '1, '_>
1769 // For the "input" lifetime parameters, we wish to create
1770 // references to the parameters themselves, including the
1771 // "implicit" ones created from parameter types (`'a`, `'b`,
1774 // For the "output" lifetime parameters, we just want to
1776 let mut generic_args = Vec::with_capacity(lifetime_params.len());
1777 generic_args.extend(lifetime_params[..input_lifetimes_count].iter().map(
1778 |&(span, hir_name)| {
1779 // Input lifetime like `'a` or `'1`:
1780 GenericArg::Lifetime(hir::Lifetime {
1781 hir_id: self.next_id(),
1782 span: self.lower_span(span),
1783 name: hir::LifetimeName::Param(hir_name),
1787 generic_args.extend(lifetime_params[input_lifetimes_count..].iter().map(|&(span, _)|
1788 // Output lifetime like `'_`.
1789 GenericArg::Lifetime(hir::Lifetime {
1790 hir_id: self.next_id(),
1791 span: self.lower_span(span),
1792 name: hir::LifetimeName::Implicit,
1794 let generic_args = self.arena.alloc_from_iter(generic_args);
1796 // Create the `Foo<...>` reference itself. Note that the `type
1797 // Foo = impl Trait` is, internally, created as a child of the
1798 // async fn, so the *type parameters* are inherited. It's
1799 // only the lifetime parameters that we must supply.
1801 hir::TyKind::OpaqueDef(hir::ItemId { def_id: opaque_ty_def_id }, generic_args);
1802 let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);
1803 hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
1806 /// Transforms `-> T` into `Future<Output = T>`.
1807 fn lower_async_fn_output_type_to_future_bound(
1812 ) -> hir::GenericBound<'hir> {
1813 // Compute the `T` in `Future<Output = T>` from the return type.
1814 let output_ty = match output {
1815 FnRetTy::Ty(ty) => {
1816 // Not `OpaqueTyOrigin::AsyncFn`: that's only used for the
1817 // `impl Future` opaque type that `async fn` implicitly
1819 let context = ImplTraitContext::ReturnPositionOpaqueTy {
1821 origin: hir::OpaqueTyOrigin::FnReturn,
1823 self.lower_ty(ty, context)
1825 FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),
1829 let future_args = self.arena.alloc(hir::GenericArgs {
1831 bindings: arena_vec![self; self.output_ty_binding(span, output_ty)],
1832 parenthesized: false,
1836 hir::GenericBound::LangItemTrait(
1837 // ::std::future::Future<future_params>
1838 hir::LangItem::Future,
1839 self.lower_span(span),
1845 fn lower_param_bound(
1848 itctx: ImplTraitContext<'_, 'hir>,
1849 ) -> hir::GenericBound<'hir> {
1851 GenericBound::Trait(p, modifier) => hir::GenericBound::Trait(
1852 self.lower_poly_trait_ref(p, itctx),
1853 self.lower_trait_bound_modifier(*modifier),
1855 GenericBound::Outlives(lifetime) => {
1856 hir::GenericBound::Outlives(self.lower_lifetime(lifetime))
1861 fn lower_lifetime(&mut self, l: &Lifetime) -> hir::Lifetime {
1862 let span = self.lower_span(l.ident.span);
1864 ident if ident.name == kw::StaticLifetime => {
1865 self.new_named_lifetime(l.id, span, hir::LifetimeName::Static)
1867 ident if ident.name == kw::UnderscoreLifetime => match self.anonymous_lifetime_mode {
1868 AnonymousLifetimeMode::CreateParameter => {
1869 let fresh_name = self.collect_fresh_in_band_lifetime(span);
1870 self.new_named_lifetime(l.id, span, hir::LifetimeName::Param(fresh_name))
1873 AnonymousLifetimeMode::PassThrough => {
1874 self.new_named_lifetime(l.id, span, hir::LifetimeName::Underscore)
1877 AnonymousLifetimeMode::ReportError => self.new_error_lifetime(Some(l.id), span),
1880 self.maybe_collect_in_band_lifetime(ident);
1881 let param_name = ParamName::Plain(self.lower_ident(ident));
1882 self.new_named_lifetime(l.id, span, hir::LifetimeName::Param(param_name))
1887 fn new_named_lifetime(
1891 name: hir::LifetimeName,
1892 ) -> hir::Lifetime {
1893 hir::Lifetime { hir_id: self.lower_node_id(id), span: self.lower_span(span), name }
1896 fn lower_generic_params_mut<'s>(
1898 params: &'s [GenericParam],
1899 mut itctx: ImplTraitContext<'s, 'hir>,
1900 ) -> impl Iterator<Item = hir::GenericParam<'hir>> + Captures<'a> + Captures<'s> {
1901 params.iter().map(move |param| self.lower_generic_param(param, itctx.reborrow()))
1904 fn lower_generic_params(
1906 params: &[GenericParam],
1907 itctx: ImplTraitContext<'_, 'hir>,
1908 ) -> &'hir [hir::GenericParam<'hir>] {
1909 self.arena.alloc_from_iter(self.lower_generic_params_mut(params, itctx))
1912 fn lower_generic_param(
1914 param: &GenericParam,
1915 mut itctx: ImplTraitContext<'_, 'hir>,
1916 ) -> hir::GenericParam<'hir> {
1917 let bounds: Vec<_> = self
1918 .with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| {
1919 this.lower_param_bounds_mut(¶m.bounds, itctx.reborrow()).collect()
1922 let (name, kind) = match param.kind {
1923 GenericParamKind::Lifetime => {
1924 let was_collecting_in_band = self.is_collecting_in_band_lifetimes;
1925 self.is_collecting_in_band_lifetimes = false;
1928 .with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| {
1929 this.lower_lifetime(&Lifetime { id: param.id, ident: param.ident })
1931 let param_name = match lt.name {
1932 hir::LifetimeName::Param(param_name) => param_name,
1933 hir::LifetimeName::Implicit
1934 | hir::LifetimeName::Underscore
1935 | hir::LifetimeName::Static => hir::ParamName::Plain(lt.name.ident()),
1936 hir::LifetimeName::ImplicitObjectLifetimeDefault => {
1937 self.sess.diagnostic().span_bug(
1939 "object-lifetime-default should not occur here",
1942 hir::LifetimeName::Error => ParamName::Error,
1946 hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit };
1948 self.is_collecting_in_band_lifetimes = was_collecting_in_band;
1952 GenericParamKind::Type { ref default, .. } => {
1953 let kind = hir::GenericParamKind::Type {
1954 default: default.as_ref().map(|x| {
1955 self.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Other))
1960 .filter(|attr| attr.has_name(sym::rustc_synthetic))
1961 .map(|_| hir::SyntheticTyParamKind::FromAttr)
1965 (hir::ParamName::Plain(self.lower_ident(param.ident)), kind)
1967 GenericParamKind::Const { ref ty, kw_span: _, ref default } => {
1969 .with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| {
1970 this.lower_ty(&ty, ImplTraitContext::disallowed())
1972 let default = default.as_ref().map(|def| self.lower_anon_const(def));
1974 hir::ParamName::Plain(self.lower_ident(param.ident)),
1975 hir::GenericParamKind::Const { ty, default },
1979 let name = match name {
1980 hir::ParamName::Plain(ident) => hir::ParamName::Plain(self.lower_ident(ident)),
1984 let hir_id = self.lower_node_id(param.id);
1985 self.lower_attrs(hir_id, ¶m.attrs);
1989 span: self.lower_span(param.ident.span),
1990 pure_wrt_drop: self.sess.contains_name(¶m.attrs, sym::may_dangle),
1991 bounds: self.arena.alloc_from_iter(bounds),
1999 itctx: ImplTraitContext<'_, 'hir>,
2000 ) -> hir::TraitRef<'hir> {
2001 let path = match self.lower_qpath(p.ref_id, &None, &p.path, ParamMode::Explicit, itctx) {
2002 hir::QPath::Resolved(None, path) => path,
2003 qpath => panic!("lower_trait_ref: unexpected QPath `{:?}`", qpath),
2005 hir::TraitRef { path, hir_ref_id: self.lower_node_id(p.ref_id) }
2008 fn lower_poly_trait_ref(
2011 mut itctx: ImplTraitContext<'_, 'hir>,
2012 ) -> hir::PolyTraitRef<'hir> {
2013 let bound_generic_params =
2014 self.lower_generic_params(&p.bound_generic_params, itctx.reborrow());
2016 let trait_ref = self.with_in_scope_lifetime_defs(&p.bound_generic_params, |this| {
2017 // Any impl Trait types defined within this scope can capture
2018 // lifetimes bound on this predicate.
2019 let lt_def_names = p.bound_generic_params.iter().filter_map(|param| match param.kind {
2020 GenericParamKind::Lifetime { .. } => Some(hir::LifetimeName::Param(
2021 ParamName::Plain(param.ident.normalize_to_macros_2_0()),
2025 if let ImplTraitContext::TypeAliasesOpaqueTy { ref mut capturable_lifetimes, .. } =
2028 capturable_lifetimes.extend(lt_def_names.clone());
2031 let res = this.lower_trait_ref(&p.trait_ref, itctx.reborrow());
2033 if let ImplTraitContext::TypeAliasesOpaqueTy { ref mut capturable_lifetimes, .. } =
2036 for param in lt_def_names {
2037 capturable_lifetimes.remove(¶m);
2043 hir::PolyTraitRef { bound_generic_params, trait_ref, span: self.lower_span(p.span) }
2046 fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext<'_, 'hir>) -> hir::MutTy<'hir> {
2047 hir::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl }
2050 fn lower_param_bounds(
2052 bounds: &[GenericBound],
2053 itctx: ImplTraitContext<'_, 'hir>,
2054 ) -> hir::GenericBounds<'hir> {
2055 self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, itctx))
2058 fn lower_param_bounds_mut<'s>(
2060 bounds: &'s [GenericBound],
2061 mut itctx: ImplTraitContext<'s, 'hir>,
2062 ) -> impl Iterator<Item = hir::GenericBound<'hir>> + Captures<'s> + Captures<'a> {
2063 bounds.iter().map(move |bound| self.lower_param_bound(bound, itctx.reborrow()))
2066 /// Lowers a block directly to an expression, presuming that it
2067 /// has no attributes and is not targeted by a `break`.
2068 fn lower_block_expr(&mut self, b: &Block) -> hir::Expr<'hir> {
2069 let block = self.lower_block(b, false);
2070 self.expr_block(block, AttrVec::new())
2073 fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst {
2074 self.with_new_scopes(|this| hir::AnonConst {
2075 hir_id: this.lower_node_id(c.id),
2076 body: this.lower_const_body(c.value.span, Some(&c.value)),
2080 fn lower_unsafe_source(&mut self, u: UnsafeSource) -> hir::UnsafeSource {
2082 CompilerGenerated => hir::UnsafeSource::CompilerGenerated,
2083 UserProvided => hir::UnsafeSource::UserProvided,
2087 fn lower_trait_bound_modifier(&mut self, f: TraitBoundModifier) -> hir::TraitBoundModifier {
2089 TraitBoundModifier::None => hir::TraitBoundModifier::None,
2090 TraitBoundModifier::MaybeConst => hir::TraitBoundModifier::MaybeConst,
2092 // `MaybeConstMaybe` will cause an error during AST validation, but we need to pick a
2093 // placeholder for compilation to proceed.
2094 TraitBoundModifier::MaybeConstMaybe | TraitBoundModifier::Maybe => {
2095 hir::TraitBoundModifier::Maybe
2100 // Helper methods for building HIR.
2102 fn stmt(&mut self, span: Span, kind: hir::StmtKind<'hir>) -> hir::Stmt<'hir> {
2103 hir::Stmt { span: self.lower_span(span), kind, hir_id: self.next_id() }
2106 fn stmt_expr(&mut self, span: Span, expr: hir::Expr<'hir>) -> hir::Stmt<'hir> {
2107 self.stmt(span, hir::StmtKind::Expr(self.arena.alloc(expr)))
2112 attrs: Option<&'hir [Attribute]>,
2114 init: Option<&'hir hir::Expr<'hir>>,
2115 pat: &'hir hir::Pat<'hir>,
2116 source: hir::LocalSource,
2117 ) -> hir::Stmt<'hir> {
2118 let hir_id = self.next_id();
2119 if let Some(a) = attrs {
2120 debug_assert!(!a.is_empty());
2121 self.attrs.insert(hir_id.local_id, a);
2123 let local = hir::Local { hir_id, init, pat, source, span: self.lower_span(span), ty: None };
2124 self.stmt(span, hir::StmtKind::Local(self.arena.alloc(local)))
2127 fn block_expr(&mut self, expr: &'hir hir::Expr<'hir>) -> &'hir hir::Block<'hir> {
2128 self.block_all(expr.span, &[], Some(expr))
2134 stmts: &'hir [hir::Stmt<'hir>],
2135 expr: Option<&'hir hir::Expr<'hir>>,
2136 ) -> &'hir hir::Block<'hir> {
2137 let blk = hir::Block {
2140 hir_id: self.next_id(),
2141 rules: hir::BlockCheckMode::DefaultBlock,
2142 span: self.lower_span(span),
2143 targeted_by_break: false,
2145 self.arena.alloc(blk)
2148 fn pat_cf_continue(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2149 let field = self.single_pat_field(span, pat);
2150 self.pat_lang_item_variant(span, hir::LangItem::ControlFlowContinue, field)
2153 fn pat_cf_break(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2154 let field = self.single_pat_field(span, pat);
2155 self.pat_lang_item_variant(span, hir::LangItem::ControlFlowBreak, field)
2158 fn pat_some(&mut self, span: Span, pat: &'hir hir::Pat<'hir>) -> &'hir hir::Pat<'hir> {
2159 let field = self.single_pat_field(span, pat);
2160 self.pat_lang_item_variant(span, hir::LangItem::OptionSome, field)
2163 fn pat_none(&mut self, span: Span) -> &'hir hir::Pat<'hir> {
2164 self.pat_lang_item_variant(span, hir::LangItem::OptionNone, &[])
2167 fn single_pat_field(
2170 pat: &'hir hir::Pat<'hir>,
2171 ) -> &'hir [hir::PatField<'hir>] {
2172 let field = hir::PatField {
2173 hir_id: self.next_id(),
2174 ident: Ident::new(sym::integer(0), self.lower_span(span)),
2175 is_shorthand: false,
2177 span: self.lower_span(span),
2179 arena_vec![self; field]
2182 fn pat_lang_item_variant(
2185 lang_item: hir::LangItem,
2186 fields: &'hir [hir::PatField<'hir>],
2187 ) -> &'hir hir::Pat<'hir> {
2188 let qpath = hir::QPath::LangItem(lang_item, self.lower_span(span));
2189 self.pat(span, hir::PatKind::Struct(qpath, fields, false))
2192 fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, hir::HirId) {
2193 self.pat_ident_binding_mode(span, ident, hir::BindingAnnotation::Unannotated)
2196 fn pat_ident_mut(&mut self, span: Span, ident: Ident) -> (hir::Pat<'hir>, hir::HirId) {
2197 self.pat_ident_binding_mode_mut(span, ident, hir::BindingAnnotation::Unannotated)
2200 fn pat_ident_binding_mode(
2204 bm: hir::BindingAnnotation,
2205 ) -> (&'hir hir::Pat<'hir>, hir::HirId) {
2206 let (pat, hir_id) = self.pat_ident_binding_mode_mut(span, ident, bm);
2207 (self.arena.alloc(pat), hir_id)
2210 fn pat_ident_binding_mode_mut(
2214 bm: hir::BindingAnnotation,
2215 ) -> (hir::Pat<'hir>, hir::HirId) {
2216 let hir_id = self.next_id();
2221 kind: hir::PatKind::Binding(bm, hir_id, self.lower_ident(ident), None),
2222 span: self.lower_span(span),
2223 default_binding_modes: true,
2229 fn pat(&mut self, span: Span, kind: hir::PatKind<'hir>) -> &'hir hir::Pat<'hir> {
2230 self.arena.alloc(hir::Pat {
2231 hir_id: self.next_id(),
2233 span: self.lower_span(span),
2234 default_binding_modes: true,
2238 fn pat_without_dbm(&mut self, span: Span, kind: hir::PatKind<'hir>) -> hir::Pat<'hir> {
2240 hir_id: self.next_id(),
2242 span: self.lower_span(span),
2243 default_binding_modes: false,
2249 mut hir_id: hir::HirId,
2251 qpath: hir::QPath<'hir>,
2252 ) -> hir::Ty<'hir> {
2253 let kind = match qpath {
2254 hir::QPath::Resolved(None, path) => {
2255 // Turn trait object paths into `TyKind::TraitObject` instead.
2257 Res::Def(DefKind::Trait | DefKind::TraitAlias, _) => {
2258 let principal = hir::PolyTraitRef {
2259 bound_generic_params: &[],
2260 trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
2261 span: self.lower_span(span),
2264 // The original ID is taken by the `PolyTraitRef`,
2265 // so the `Ty` itself needs a different one.
2266 hir_id = self.next_id();
2267 hir::TyKind::TraitObject(
2268 arena_vec![self; principal],
2269 self.elided_dyn_bound(span),
2270 TraitObjectSyntax::None,
2273 _ => hir::TyKind::Path(hir::QPath::Resolved(None, path)),
2276 _ => hir::TyKind::Path(qpath),
2279 hir::Ty { hir_id, kind, span: self.lower_span(span) }
2282 /// Invoked to create the lifetime argument for a type `&T`
2283 /// with no explicit lifetime.
2284 fn elided_ref_lifetime(&mut self, span: Span) -> hir::Lifetime {
2285 match self.anonymous_lifetime_mode {
2286 // Intercept when we are in an impl header or async fn and introduce an in-band
2288 // Hence `impl Foo for &u32` becomes `impl<'f> Foo for &'f u32` for some fresh
2290 AnonymousLifetimeMode::CreateParameter => {
2291 let fresh_name = self.collect_fresh_in_band_lifetime(span);
2293 hir_id: self.next_id(),
2294 span: self.lower_span(span),
2295 name: hir::LifetimeName::Param(fresh_name),
2299 AnonymousLifetimeMode::ReportError => self.new_error_lifetime(None, span),
2301 AnonymousLifetimeMode::PassThrough => self.new_implicit_lifetime(span),
2305 /// Report an error on illegal use of `'_` or a `&T` with no explicit lifetime;
2306 /// return an "error lifetime".
2307 fn new_error_lifetime(&mut self, id: Option<NodeId>, span: Span) -> hir::Lifetime {
2308 let (id, msg, label) = match id {
2309 Some(id) => (id, "`'_` cannot be used here", "`'_` is a reserved lifetime name"),
2312 self.resolver.next_node_id(),
2313 "`&` without an explicit lifetime name cannot be used here",
2314 "explicit lifetime name needed here",
2318 let mut err = struct_span_err!(self.sess, span, E0637, "{}", msg,);
2319 err.span_label(span, label);
2322 self.new_named_lifetime(id, span, hir::LifetimeName::Error)
2325 /// Invoked to create the lifetime argument(s) for a path like
2326 /// `std::cell::Ref<T>`; note that implicit lifetimes in these
2327 /// sorts of cases are deprecated. This may therefore report a warning or an
2328 /// error, depending on the mode.
2329 fn elided_path_lifetimes<'s>(
2333 ) -> impl Iterator<Item = hir::Lifetime> + Captures<'a> + Captures<'s> + Captures<'hir> {
2334 (0..count).map(move |_| self.elided_path_lifetime(span))
2337 fn elided_path_lifetime(&mut self, span: Span) -> hir::Lifetime {
2338 match self.anonymous_lifetime_mode {
2339 AnonymousLifetimeMode::CreateParameter => {
2340 // We should have emitted E0726 when processing this path above
2342 .delay_span_bug(span, "expected 'implicit elided lifetime not allowed' error");
2343 let id = self.resolver.next_node_id();
2344 self.new_named_lifetime(id, span, hir::LifetimeName::Error)
2346 // `PassThrough` is the normal case.
2347 // `new_error_lifetime`, which would usually be used in the case of `ReportError`,
2348 // is unsuitable here, as these can occur from missing lifetime parameters in a
2349 // `PathSegment`, for which there is no associated `'_` or `&T` with no explicit
2350 // lifetime. Instead, we simply create an implicit lifetime, which will be checked
2351 // later, at which point a suitable error will be emitted.
2352 AnonymousLifetimeMode::PassThrough | AnonymousLifetimeMode::ReportError => {
2353 self.new_implicit_lifetime(span)
2358 /// Invoked to create the lifetime argument(s) for an elided trait object
2359 /// bound, like the bound in `Box<dyn Debug>`. This method is not invoked
2360 /// when the bound is written, even if it is written with `'_` like in
2361 /// `Box<dyn Debug + '_>`. In those cases, `lower_lifetime` is invoked.
2362 fn elided_dyn_bound(&mut self, span: Span) -> hir::Lifetime {
2363 match self.anonymous_lifetime_mode {
2364 // NB. We intentionally ignore the create-parameter mode here.
2365 // and instead "pass through" to resolve-lifetimes, which will apply
2366 // the object-lifetime-defaulting rules. Elided object lifetime defaults
2367 // do not act like other elided lifetimes. In other words, given this:
2369 // impl Foo for Box<dyn Debug>
2371 // we do not introduce a fresh `'_` to serve as the bound, but instead
2372 // ultimately translate to the equivalent of:
2374 // impl Foo for Box<dyn Debug + 'static>
2376 // `resolve_lifetime` has the code to make that happen.
2377 AnonymousLifetimeMode::CreateParameter => {}
2379 AnonymousLifetimeMode::ReportError => {
2380 // ReportError applies to explicit use of `'_`.
2383 // This is the normal case.
2384 AnonymousLifetimeMode::PassThrough => {}
2387 let r = hir::Lifetime {
2388 hir_id: self.next_id(),
2389 span: self.lower_span(span),
2390 name: hir::LifetimeName::ImplicitObjectLifetimeDefault,
2392 debug!("elided_dyn_bound: r={:?}", r);
2396 fn new_implicit_lifetime(&mut self, span: Span) -> hir::Lifetime {
2398 hir_id: self.next_id(),
2399 span: self.lower_span(span),
2400 name: hir::LifetimeName::Implicit,
2404 fn maybe_lint_bare_trait(&mut self, span: Span, id: NodeId, is_global: bool) {
2405 // FIXME(davidtwco): This is a hack to detect macros which produce spans of the
2406 // call site which do not have a macro backtrace. See #61963.
2407 let is_macro_callsite = self
2410 .span_to_snippet(span)
2411 .map(|snippet| snippet.starts_with("#["))
2413 if !is_macro_callsite {
2414 if span.edition() < Edition::Edition2021 {
2415 self.resolver.lint_buffer().buffer_lint_with_diagnostic(
2419 "trait objects without an explicit `dyn` are deprecated",
2420 BuiltinLintDiagnostics::BareTraitObject(span, is_global),
2423 let msg = "trait objects must include the `dyn` keyword";
2424 let label = "add `dyn` keyword before this trait";
2425 let mut err = struct_span_err!(self.sess, span, E0782, "{}", msg,);
2426 err.span_suggestion_verbose(
2427 span.shrink_to_lo(),
2429 String::from("dyn "),
2430 Applicability::MachineApplicable,
2438 /// Helper struct for delayed construction of GenericArgs.
2439 struct GenericArgsCtor<'hir> {
2440 args: SmallVec<[hir::GenericArg<'hir>; 4]>,
2441 bindings: &'hir [hir::TypeBinding<'hir>],
2442 parenthesized: bool,
2446 impl<'hir> GenericArgsCtor<'hir> {
2447 fn is_empty(&self) -> bool {
2448 self.args.is_empty() && self.bindings.is_empty() && !self.parenthesized
2451 fn into_generic_args(self, this: &LoweringContext<'_, 'hir>) -> &'hir hir::GenericArgs<'hir> {
2452 let ga = hir::GenericArgs {
2453 args: this.arena.alloc_from_iter(self.args),
2454 bindings: self.bindings,
2455 parenthesized: self.parenthesized,
2456 span_ext: this.lower_span(self.span),
2458 this.arena.alloc(ga)
2462 fn lifetimes_from_impl_trait_bounds(
2463 opaque_ty_id: NodeId,
2464 bounds: hir::GenericBounds<'_>,
2465 lifetimes_to_include: Option<&FxHashSet<hir::LifetimeName>>,
2466 ) -> Vec<(hir::LifetimeName, Span)> {
2468 "lifetimes_from_impl_trait_bounds(opaque_ty_id={:?}, \
2470 opaque_ty_id, bounds,
2473 // This visitor walks over `impl Trait` bounds and creates defs for all lifetimes that
2474 // appear in the bounds, excluding lifetimes that are created within the bounds.
2475 // E.g., `'a`, `'b`, but not `'c` in `impl for<'c> SomeTrait<'a, 'b, 'c>`.
2476 struct ImplTraitLifetimeCollector<'r> {
2477 collect_elided_lifetimes: bool,
2478 currently_bound_lifetimes: Vec<hir::LifetimeName>,
2479 already_defined_lifetimes: FxHashSet<hir::LifetimeName>,
2480 lifetimes: Vec<(hir::LifetimeName, Span)>,
2481 lifetimes_to_include: Option<&'r FxHashSet<hir::LifetimeName>>,
2484 impl<'r, 'v> intravisit::Visitor<'v> for ImplTraitLifetimeCollector<'r> {
2485 type Map = intravisit::ErasedMap<'v>;
2487 fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap<Self::Map> {
2488 intravisit::NestedVisitorMap::None
2491 fn visit_generic_args(&mut self, span: Span, parameters: &'v hir::GenericArgs<'v>) {
2492 // Don't collect elided lifetimes used inside of `Fn()` syntax.
2493 if parameters.parenthesized {
2494 let old_collect_elided_lifetimes = self.collect_elided_lifetimes;
2495 self.collect_elided_lifetimes = false;
2496 intravisit::walk_generic_args(self, span, parameters);
2497 self.collect_elided_lifetimes = old_collect_elided_lifetimes;
2499 intravisit::walk_generic_args(self, span, parameters);
2503 fn visit_ty(&mut self, t: &'v hir::Ty<'v>) {
2504 // Don't collect elided lifetimes used inside of `fn()` syntax.
2505 if let hir::TyKind::BareFn(_) = t.kind {
2506 let old_collect_elided_lifetimes = self.collect_elided_lifetimes;
2507 self.collect_elided_lifetimes = false;
2509 // Record the "stack height" of `for<'a>` lifetime bindings
2510 // to be able to later fully undo their introduction.
2511 let old_len = self.currently_bound_lifetimes.len();
2512 intravisit::walk_ty(self, t);
2513 self.currently_bound_lifetimes.truncate(old_len);
2515 self.collect_elided_lifetimes = old_collect_elided_lifetimes;
2517 intravisit::walk_ty(self, t)
2521 fn visit_poly_trait_ref(
2523 trait_ref: &'v hir::PolyTraitRef<'v>,
2524 modifier: hir::TraitBoundModifier,
2526 // Record the "stack height" of `for<'a>` lifetime bindings
2527 // to be able to later fully undo their introduction.
2528 let old_len = self.currently_bound_lifetimes.len();
2529 intravisit::walk_poly_trait_ref(self, trait_ref, modifier);
2530 self.currently_bound_lifetimes.truncate(old_len);
2533 fn visit_generic_param(&mut self, param: &'v hir::GenericParam<'v>) {
2534 // Record the introduction of 'a in `for<'a> ...`.
2535 if let hir::GenericParamKind::Lifetime { .. } = param.kind {
2536 // Introduce lifetimes one at a time so that we can handle
2537 // cases like `fn foo<'d>() -> impl for<'a, 'b: 'a, 'c: 'b + 'd>`.
2538 let lt_name = hir::LifetimeName::Param(param.name);
2539 self.currently_bound_lifetimes.push(lt_name);
2542 intravisit::walk_generic_param(self, param);
2545 fn visit_lifetime(&mut self, lifetime: &'v hir::Lifetime) {
2546 let name = match lifetime.name {
2547 hir::LifetimeName::Implicit | hir::LifetimeName::Underscore => {
2548 if self.collect_elided_lifetimes {
2549 // Use `'_` for both implicit and underscore lifetimes in
2550 // `type Foo<'_> = impl SomeTrait<'_>;`.
2551 hir::LifetimeName::Underscore
2556 hir::LifetimeName::Param(_) => lifetime.name,
2558 // Refers to some other lifetime that is "in
2559 // scope" within the type.
2560 hir::LifetimeName::ImplicitObjectLifetimeDefault => return,
2562 hir::LifetimeName::Error | hir::LifetimeName::Static => return,
2565 if !self.currently_bound_lifetimes.contains(&name)
2566 && !self.already_defined_lifetimes.contains(&name)
2567 && self.lifetimes_to_include.map_or(true, |lifetimes| lifetimes.contains(&name))
2569 self.already_defined_lifetimes.insert(name);
2571 self.lifetimes.push((name, lifetime.span));
2576 let mut lifetime_collector = ImplTraitLifetimeCollector {
2577 collect_elided_lifetimes: true,
2578 currently_bound_lifetimes: Vec::new(),
2579 already_defined_lifetimes: FxHashSet::default(),
2580 lifetimes: Vec::new(),
2581 lifetimes_to_include,
2584 for bound in bounds {
2585 intravisit::walk_param_bound(&mut lifetime_collector, &bound);
2588 lifetime_collector.lifetimes