Files
rust/compiler/rustc_ast_lowering/src/item.rs

1567 lines
64 KiB
Rust
Raw Normal View History

use super::{AnonymousLifetimeMode, LoweringContext, ParamMode};
use super::{AstOwner, ImplTraitContext, ImplTraitPosition, ResolverAstLowering};
use crate::{Arena, FnDeclKind};
use rustc_ast::ptr::P;
2021-07-15 01:18:39 +02:00
use rustc_ast::visit::AssocCtxt;
2020-04-27 23:26:11 +05:30
use rustc_ast::*;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::sorted_map::SortedMap;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
2021-07-15 01:18:39 +02:00
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
use rustc_index::vec::{Idx, IndexVec};
use rustc_session::utils::NtToTokenstream;
use rustc_session::Session;
use rustc_span::source_map::{respan, DesugaringKind};
2020-04-19 13:00:18 +02:00
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::Span;
use rustc_target::spec::abi;
use smallvec::{smallvec, SmallVec};
2020-08-02 13:24:08 +05:30
use tracing::debug;
2021-03-08 15:32:41 -08:00
use std::iter;
pub(super) struct ItemLowerer<'a, 'hir> {
pub(super) sess: &'a Session,
pub(super) resolver: &'a mut dyn ResolverAstLowering,
pub(super) nt_to_tokenstream: NtToTokenstream,
pub(super) arena: &'hir Arena<'hir>,
pub(super) ast_index: &'a IndexVec<LocalDefId, AstOwner<'a>>,
pub(super) owners: &'a mut IndexVec<LocalDefId, hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>>>,
2019-08-10 20:13:12 +02:00
}
/// When we have a ty alias we *may* have two where clauses. To give the best diagnostics, we set the span
/// to the where clause that is preferred, if it exists. Otherwise, it sets the span to the other where
/// clause if it exists.
fn add_ty_alias_where_clause(
generics: &mut ast::Generics,
mut where_clauses: (TyAliasWhereClause, TyAliasWhereClause),
prefer_first: bool,
) {
if !prefer_first {
where_clauses = (where_clauses.1, where_clauses.0);
}
if where_clauses.0.0 || !where_clauses.1.0 {
generics.where_clause.has_where_token = where_clauses.0.0;
generics.where_clause.span = where_clauses.0.1;
} else {
generics.where_clause.has_where_token = where_clauses.1.0;
generics.where_clause.span = where_clauses.1.1;
}
}
impl<'a, 'hir> ItemLowerer<'a, 'hir> {
fn make_lctx(&mut self) -> LoweringContext<'_, 'hir> {
LoweringContext {
// Pseudo-globals.
sess: &self.sess,
resolver: self.resolver,
nt_to_tokenstream: self.nt_to_tokenstream,
arena: self.arena,
owners: self.owners,
// HirId handling.
bodies: Vec::new(),
attrs: SortedMap::default(),
current_hir_id_owner: CRATE_DEF_ID,
item_local_id_counter: hir::ItemLocalId::new(0),
node_id_to_local_id: Default::default(),
local_id_to_def_id: SortedMap::new(),
trait_map: Default::default(),
// Lowering state.
catch_scope: None,
loop_scope: None,
is_in_loop_condition: false,
is_in_trait_impl: false,
is_in_dyn_type: false,
anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough,
generator_kind: None,
task_context: None,
current_item: None,
lifetimes_to_define: Vec::new(),
is_collecting_anonymous_lifetimes: None,
in_scope_lifetimes: Vec::new(),
allow_try_trait: Some([sym::try_trait_v2][..].into()),
allow_gen_future: Some([sym::gen_future][..].into()),
allow_into_future: Some([sym::into_future][..].into()),
}
2019-08-10 20:13:12 +02:00
}
2021-07-15 01:18:39 +02:00
pub(super) fn lower_node(
&mut self,
def_id: LocalDefId,
) -> hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>> {
self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
if let hir::MaybeOwner::Phantom = self.owners[def_id] {
2021-07-15 01:18:39 +02:00
let node = self.ast_index[def_id];
match node {
AstOwner::NonOwner => {}
AstOwner::Crate(c) => self.lower_crate(c),
AstOwner::Item(item) => self.lower_item(item),
AstOwner::AssocItem(item, ctxt) => self.lower_assoc_item(item, ctxt),
AstOwner::ForeignItem(item) => self.lower_foreign_item(item),
}
}
self.owners[def_id]
}
2021-07-15 01:18:39 +02:00
fn lower_crate(&mut self, c: &'a Crate) {
debug_assert_eq!(self.resolver.local_def_id(CRATE_NODE_ID), CRATE_DEF_ID);
2019-08-10 20:13:12 +02:00
let mut lctx = self.make_lctx();
lctx.with_hir_id_owner(CRATE_NODE_ID, |lctx| {
2021-07-15 01:18:39 +02:00
let module = lctx.lower_mod(&c.items, c.spans.inner_span);
lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs);
hir::OwnerNode::Crate(lctx.arena.alloc(module))
})
2019-08-10 20:13:12 +02:00
}
2021-07-15 01:18:39 +02:00
fn lower_item(&mut self, item: &'a Item) {
let mut lctx = self.make_lctx();
lctx.with_hir_id_owner(item.id, |lctx| hir::OwnerNode::Item(lctx.lower_item(item)))
Don't visit foreign function bodies when lowering ast to hir Previously the existence of bodies inside a foreign function block would cause a panic in the hir `NodeCollector` during its collection of crate bodies to compute a crate hash: https://github.com/rust-lang/rust/blob/e59b08e62ea691916d2f063cac5aab4634128022/src/librustc_middle/hir/map/collector.rs#L154-L158 The collector walks the hir tree and creates a map of hir nodes, then attaching bodies in the crate to their owner in the map. For a code like ```rust extern "C" { fn f() { fn g() {} } } ``` The crate bodies include the body of the function `g`. But foreign functions cannot have bodies, and while the parser AST permits a foreign function to have a body, the hir doesn't. This means that the body of `f` is not present in the hir, and so neither is `g`. So when the `NodeCollector` finishes the walking the hir, it has no record of `g`, cannot find an owner for the body of `g` it sees in the crate bodies, and blows up. Why do the crate bodies include the body of `g`? The AST walker has a need a for walking function bodies, and FFIs share the same AST node as functions in other contexts. There are at least two options to fix this: - Don't unwrap the map entry for an hir node in the `NodeCollector` - Modifier the ast->hir lowering visitor to ignore foreign function blocks I don't think the first is preferrable, since we want to know when we can't find a body for an hir node that we thought had one (dropping this information may lead to an invalid hash). So this commit implements the second option. Closes #74120
2020-07-09 19:03:15 -07:00
}
2021-07-15 01:18:39 +02:00
fn lower_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
let def_id = self.resolver.local_def_id(item.id);
2021-07-15 01:18:39 +02:00
let parent_id = {
let parent = self.resolver.definitions().def_key(def_id).parent;
2021-07-15 01:18:39 +02:00
let local_def_index = parent.unwrap();
LocalDefId { local_def_index }
};
2021-07-15 01:18:39 +02:00
let parent_hir = self.lower_node(parent_id).unwrap().node().expect_item();
let mut lctx = self.make_lctx();
// Evaluate with the lifetimes in `params` in-scope.
// This is used to track which lifetimes have already been defined,
// and which need to be replicated when lowering an async fn.
match parent_hir.kind {
hir::ItemKind::Impl(hir::Impl { ref of_trait, ref generics, .. }) => {
lctx.is_in_trait_impl = of_trait.is_some();
lctx.in_scope_lifetimes = generics
.params
.iter()
.filter(|param| matches!(param.kind, hir::GenericParamKind::Lifetime { .. }))
.map(|param| param.name)
.collect();
}
hir::ItemKind::Trait(_, _, ref generics, ..) => {
lctx.in_scope_lifetimes = generics
.params
.iter()
.filter(|param| matches!(param.kind, hir::GenericParamKind::Lifetime { .. }))
.map(|param| param.name)
.collect();
2021-07-15 01:18:39 +02:00
}
_ => {}
};
lctx.with_hir_id_owner(item.id, |lctx| match ctxt {
AssocCtxt::Trait => hir::OwnerNode::TraitItem(lctx.lower_trait_item(item)),
AssocCtxt::Impl => hir::OwnerNode::ImplItem(lctx.lower_impl_item(item)),
})
2019-08-10 20:13:12 +02:00
}
2020-11-11 21:57:54 +01:00
2021-07-15 01:18:39 +02:00
fn lower_foreign_item(&mut self, item: &'a ForeignItem) {
let mut lctx = self.make_lctx();
lctx.with_hir_id_owner(item.id, |lctx| {
hir::OwnerNode::ForeignItem(lctx.lower_foreign_item(item))
})
2020-11-11 21:57:54 +01:00
}
2019-08-10 20:13:12 +02:00
}
2019-11-29 11:09:23 +01:00
impl<'hir> LoweringContext<'_, 'hir> {
pub(super) fn lower_mod(&mut self, items: &[P<Item>], inner: Span) -> hir::Mod<'hir> {
2019-08-10 20:13:12 +02:00
hir::Mod {
inner: self.lower_span(inner),
2021-07-14 18:54:56 +02:00
item_ids: self.arena.alloc_from_iter(items.iter().flat_map(|x| self.lower_item_ref(x))),
2019-08-10 20:13:12 +02:00
}
}
2021-07-14 18:54:56 +02:00
pub(super) fn lower_item_ref(&mut self, i: &Item) -> SmallVec<[hir::ItemId; 1]> {
let mut node_ids = smallvec![hir::ItemId { def_id: self.resolver.local_def_id(i.id) }];
if let ItemKind::Use(ref use_tree) = &i.kind {
self.lower_item_id_use_tree(use_tree, i.id, &mut node_ids);
}
2019-12-22 17:42:04 -05:00
node_ids
2019-08-10 20:13:12 +02:00
}
fn lower_item_id_use_tree(
&mut self,
tree: &UseTree,
base_id: NodeId,
2021-07-14 18:54:56 +02:00
vec: &mut SmallVec<[hir::ItemId; 1]>,
2019-08-10 20:13:12 +02:00
) {
match tree.kind {
2019-12-22 17:42:04 -05:00
UseTreeKind::Nested(ref nested_vec) => {
for &(ref nested, id) in nested_vec {
2021-07-14 18:54:56 +02:00
vec.push(hir::ItemId { def_id: self.resolver.local_def_id(id) });
2019-12-22 17:42:04 -05:00
self.lower_item_id_use_tree(nested, id, vec);
}
}
2019-08-10 20:13:12 +02:00
UseTreeKind::Glob => {}
UseTreeKind::Simple(_, id1, id2) => {
2019-12-22 17:42:04 -05:00
for (_, &id) in
2021-03-08 15:32:41 -08:00
iter::zip(self.expect_full_res_from_use(base_id).skip(1), &[id1, id2])
2019-08-10 20:13:12 +02:00
{
2021-07-14 18:54:56 +02:00
vec.push(hir::ItemId { def_id: self.resolver.local_def_id(id) });
2019-08-10 20:13:12 +02:00
}
2019-12-22 17:42:04 -05:00
}
2019-08-10 20:13:12 +02:00
}
}
fn lower_item(&mut self, i: &Item) -> &'hir hir::Item<'hir> {
2019-08-10 20:13:12 +02:00
let mut ident = i.ident;
2021-07-15 22:19:39 +02:00
let mut vis = self.lower_visibility(&i.vis);
let hir_id = self.lower_node_id(i.id);
let attrs = self.lower_attrs(hir_id, &i.attrs);
let kind = self.lower_item_kind(i.span, i.id, hir_id, &mut ident, attrs, &mut vis, &i.kind);
let item = hir::Item {
def_id: hir_id.expect_owner(),
ident: self.lower_ident(ident),
kind,
vis,
span: self.lower_span(i.span),
};
self.arena.alloc(item)
2019-08-10 20:13:12 +02:00
}
fn lower_item_kind(
&mut self,
span: Span,
2019-08-10 20:13:12 +02:00
id: NodeId,
hir_id: hir::HirId,
2019-08-10 20:13:12 +02:00
ident: &mut Ident,
2021-01-24 17:14:17 +01:00
attrs: Option<&'hir [Attribute]>,
2019-11-30 17:46:46 +01:00
vis: &mut hir::Visibility<'hir>,
2019-08-10 20:13:12 +02:00
i: &ItemKind,
2019-11-28 19:28:50 +01:00
) -> hir::ItemKind<'hir> {
2019-08-10 20:13:12 +02:00
match *i {
ItemKind::ExternCrate(orig_name) => hir::ItemKind::ExternCrate(orig_name),
ItemKind::Use(ref use_tree) => {
// Start with an empty prefix.
2020-08-21 18:51:23 -04:00
let prefix = Path { segments: vec![], span: use_tree.span, tokens: None };
2019-08-10 20:13:12 +02:00
self.lower_use_tree(use_tree, &prefix, id, vis, ident, attrs)
}
ItemKind::Static(ref t, m, ref e) => {
let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
hir::ItemKind::Static(ty, m, body_id)
2019-08-10 20:13:12 +02:00
}
ItemKind::Const(_, ref t, ref e) => {
let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
hir::ItemKind::Const(ty, body_id)
2019-08-10 20:13:12 +02:00
}
ItemKind::Fn(box Fn {
sig: FnSig { ref decl, header, span: fn_sig_span },
Use smaller def span for functions Currently, the def span of a funtion encompasses the entire function signature and body. However, this is usually unnecessarily verbose - when we are pointing at an entire function in a diagnostic, we almost always want to point at the signature. The actual contents of the body tends to be irrelevant to the diagnostic we are emitting, and just takes up additional screen space. This commit changes the `def_span` of all function items (freestanding functions, `impl`-block methods, and `trait`-block methods) to be the span of the signature. For example, the function ```rust pub fn foo<T>(val: T) -> T { val } ``` now has a `def_span` corresponding to `pub fn foo<T>(val: T) -> T` (everything before the opening curly brace). Trait methods without a body have a `def_span` which includes the trailing semicolon. For example: ```rust trait Foo { fn bar(); }``` the function definition `Foo::bar` has a `def_span` of `fn bar();` This makes our diagnostic output much shorter, and emphasizes information that is relevant to whatever diagnostic we are reporting. We continue to use the full span (including the body) in a few of places: * MIR building uses the full span when building source scopes. * 'Outlives suggestions' use the full span to sort the diagnostics being emitted. * The `#[rustc_on_unimplemented(enclosing_scope="in this scope")]` attribute points the entire scope body. * The 'unconditional recursion' lint uses the full span to show additional context for the recursive call. All of these cases work only with local items, so we don't need to add anything extra to crate metadata.
2020-08-12 17:02:14 -04:00
ref generics,
ref body,
..
}) => {
let fn_def_id = self.resolver.local_def_id(id);
2019-08-10 20:13:12 +02:00
self.with_new_scopes(|this| {
this.current_item = Some(ident.span);
// Note: we don't need to change the return type from `T` to
// `impl Future<Output = T>` here because lower_body
// only cares about the input argument patterns in the function
// declaration (decl), not the return types.
let asyncness = header.asyncness;
2019-12-22 17:42:04 -05:00
let body_id =
this.lower_maybe_async_body(span, &decl, asyncness, body.as_deref());
2019-08-10 20:13:12 +02:00
2019-11-07 12:57:52 +01:00
let (generics, decl) = this.add_in_band_defs(
2019-08-10 20:13:12 +02:00
generics,
fn_def_id,
AnonymousLifetimeMode::PassThrough,
2019-12-22 17:42:04 -05:00
|this, idty| {
let ret_id = asyncness.opt_return_id();
this.lower_fn_decl(
&decl,
Some((fn_def_id, idty)),
FnDeclKind::Fn,
ret_id,
)
2019-12-22 17:42:04 -05:00
},
2019-08-10 20:13:12 +02:00
);
Use smaller def span for functions Currently, the def span of a funtion encompasses the entire function signature and body. However, this is usually unnecessarily verbose - when we are pointing at an entire function in a diagnostic, we almost always want to point at the signature. The actual contents of the body tends to be irrelevant to the diagnostic we are emitting, and just takes up additional screen space. This commit changes the `def_span` of all function items (freestanding functions, `impl`-block methods, and `trait`-block methods) to be the span of the signature. For example, the function ```rust pub fn foo<T>(val: T) -> T { val } ``` now has a `def_span` corresponding to `pub fn foo<T>(val: T) -> T` (everything before the opening curly brace). Trait methods without a body have a `def_span` which includes the trailing semicolon. For example: ```rust trait Foo { fn bar(); }``` the function definition `Foo::bar` has a `def_span` of `fn bar();` This makes our diagnostic output much shorter, and emphasizes information that is relevant to whatever diagnostic we are reporting. We continue to use the full span (including the body) in a few of places: * MIR building uses the full span when building source scopes. * 'Outlives suggestions' use the full span to sort the diagnostics being emitted. * The `#[rustc_on_unimplemented(enclosing_scope="in this scope")]` attribute points the entire scope body. * The 'unconditional recursion' lint uses the full span to show additional context for the recursive call. All of these cases work only with local items, so we don't need to add anything extra to crate metadata.
2020-08-12 17:02:14 -04:00
let sig = hir::FnSig {
decl,
2021-07-08 21:58:05 +02:00
header: this.lower_fn_header(header),
span: this.lower_span(fn_sig_span),
Use smaller def span for functions Currently, the def span of a funtion encompasses the entire function signature and body. However, this is usually unnecessarily verbose - when we are pointing at an entire function in a diagnostic, we almost always want to point at the signature. The actual contents of the body tends to be irrelevant to the diagnostic we are emitting, and just takes up additional screen space. This commit changes the `def_span` of all function items (freestanding functions, `impl`-block methods, and `trait`-block methods) to be the span of the signature. For example, the function ```rust pub fn foo<T>(val: T) -> T { val } ``` now has a `def_span` corresponding to `pub fn foo<T>(val: T) -> T` (everything before the opening curly brace). Trait methods without a body have a `def_span` which includes the trailing semicolon. For example: ```rust trait Foo { fn bar(); }``` the function definition `Foo::bar` has a `def_span` of `fn bar();` This makes our diagnostic output much shorter, and emphasizes information that is relevant to whatever diagnostic we are reporting. We continue to use the full span (including the body) in a few of places: * MIR building uses the full span when building source scopes. * 'Outlives suggestions' use the full span to sort the diagnostics being emitted. * The `#[rustc_on_unimplemented(enclosing_scope="in this scope")]` attribute points the entire scope body. * The 'unconditional recursion' lint uses the full span to show additional context for the recursive call. All of these cases work only with local items, so we don't need to add anything extra to crate metadata.
2020-08-12 17:02:14 -04:00
};
2019-11-07 12:57:52 +01:00
hir::ItemKind::Fn(sig, generics, body_id)
2019-08-10 20:13:12 +02:00
})
}
ItemKind::Mod(_, ref mod_kind) => match mod_kind {
ModKind::Loaded(items, _, ModSpans { inner_span, inject_use_span: _ }) => {
hir::ItemKind::Mod(self.lower_mod(items, *inner_span))
}
ModKind::Unloaded => panic!("`mod` items should have been loaded by now"),
},
2021-07-08 21:58:05 +02:00
ItemKind::ForeignMod(ref fm) => hir::ItemKind::ForeignMod {
abi: fm.abi.map_or(abi::Abi::FALLBACK, |abi| self.lower_abi(abi)),
items: self
.arena
.alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))),
},
ItemKind::GlobalAsm(ref asm) => {
hir::ItemKind::GlobalAsm(self.lower_inline_asm(span, asm))
}
ItemKind::TyAlias(box TyAlias {
ref generics,
where_clauses,
ty: Some(ref ty),
..
}) => {
// We lower
//
// type Foo = impl Trait
//
// to
//
// type Foo = Foo1
// opaque type Foo1: Trait
let ty = self.lower_ty(
ty,
ImplTraitContext::TypeAliasesOpaqueTy {
capturable_lifetimes: &mut FxHashSet::default(),
},
);
let mut generics = generics.clone();
add_ty_alias_where_clause(&mut generics, where_clauses, true);
let generics = self.lower_generics(
&generics,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
);
2020-05-10 11:57:58 +01:00
hir::ItemKind::TyAlias(ty, generics)
}
ItemKind::TyAlias(box TyAlias {
ref generics, ref where_clauses, ty: None, ..
}) => {
let ty = self.arena.alloc(self.ty(span, hir::TyKind::Err));
let mut generics = generics.clone();
add_ty_alias_where_clause(&mut generics, *where_clauses, true);
let generics = self.lower_generics(
&generics,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
);
hir::ItemKind::TyAlias(ty, generics)
}
2019-12-22 17:42:04 -05:00
ItemKind::Enum(ref enum_definition, ref generics) => hir::ItemKind::Enum(
hir::EnumDef {
variants: self.arena.alloc_from_iter(
enum_definition.variants.iter().map(|x| self.lower_variant(x)),
),
},
self.lower_generics(
generics,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
),
2019-12-22 17:42:04 -05:00
),
2019-08-10 20:13:12 +02:00
ItemKind::Struct(ref struct_def, ref generics) => {
let struct_def = self.lower_variant_data(hir_id, struct_def);
2019-08-10 20:13:12 +02:00
hir::ItemKind::Struct(
struct_def,
self.lower_generics(
generics,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
),
2019-08-10 20:13:12 +02:00
)
}
ItemKind::Union(ref vdata, ref generics) => {
let vdata = self.lower_variant_data(hir_id, vdata);
2019-08-10 20:13:12 +02:00
hir::ItemKind::Union(
vdata,
self.lower_generics(
generics,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
),
2019-08-10 20:13:12 +02:00
)
}
ItemKind::Impl(box Impl {
2019-08-10 20:13:12 +02:00
unsafety,
polarity,
defaultness,
constness,
generics: ref ast_generics,
of_trait: ref trait_ref,
self_ty: ref ty,
items: ref impl_items,
2021-01-29 08:31:08 +01:00
}) => {
2019-08-10 20:13:12 +02:00
// Lower the "impl header" first. This ordering is important
// for in-band lifetimes! Consider `'a` here:
//
// impl Foo<'a> for u32 {
// fn method(&'a self) { .. }
// }
//
// Because we start by lowering the `Foo<'a> for u32`
// part, we will add `'a` to the list of generics on
// the impl. When we then encounter it later in the
// method, it will not be considered an in-band
// lifetime to be added, but rather a reference to a
// parent lifetime.
let lowered_trait_def_id = hir_id.expect_owner();
2019-08-10 20:13:12 +02:00
let (generics, (trait_ref, lowered_ty)) = self.add_in_band_defs(
ast_generics,
lowered_trait_def_id,
2019-08-10 20:13:12 +02:00
AnonymousLifetimeMode::CreateParameter,
|this, _| {
let trait_ref = trait_ref.as_ref().map(|trait_ref| {
this.lower_trait_ref(
trait_ref,
ImplTraitContext::Disallowed(ImplTraitPosition::Trait),
)
2019-08-10 20:13:12 +02:00
});
let lowered_ty = this
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
2019-08-10 20:13:12 +02:00
(trait_ref, lowered_ty)
},
);
2019-12-22 17:42:04 -05:00
let new_impl_items =
self.with_in_scope_lifetime_defs(&ast_generics.params, |this| {
2019-11-28 19:28:50 +01:00
this.arena.alloc_from_iter(
2019-12-22 17:42:04 -05:00
impl_items.iter().map(|item| this.lower_impl_item_ref(item)),
2019-11-28 19:28:50 +01:00
)
2019-12-22 17:42:04 -05:00
});
2019-08-10 20:13:12 +02:00
// `defaultness.has_value()` is never called for an `impl`, always `true` in order
// to not cause an assertion failure inside the `lower_defaultness` function.
let has_val = true;
let (defaultness, defaultness_span) = self.lower_defaultness(defaultness, has_val);
let polarity = match polarity {
ImplPolarity::Positive => ImplPolarity::Positive,
ImplPolarity::Negative(s) => ImplPolarity::Negative(self.lower_span(s)),
};
hir::ItemKind::Impl(hir::Impl {
unsafety: self.lower_unsafety(unsafety),
polarity,
defaultness,
defaultness_span,
constness: self.lower_constness(constness),
2019-08-10 20:13:12 +02:00
generics,
of_trait: trait_ref,
self_ty: lowered_ty,
items: new_impl_items,
})
2019-08-10 20:13:12 +02:00
}
ItemKind::Trait(box Trait {
2021-01-29 08:31:08 +01:00
is_auto,
unsafety,
ref generics,
ref bounds,
ref items,
}) => {
let bounds = self.lower_param_bounds(
bounds,
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
);
2019-12-22 17:42:04 -05:00
let items = self
.arena
.alloc_from_iter(items.iter().map(|item| self.lower_trait_item_ref(item)));
2019-08-10 20:13:12 +02:00
hir::ItemKind::Trait(
2019-11-09 18:28:03 +01:00
is_auto,
self.lower_unsafety(unsafety),
self.lower_generics(
generics,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
),
2019-08-10 20:13:12 +02:00
bounds,
items,
)
}
ItemKind::TraitAlias(ref generics, ref bounds) => hir::ItemKind::TraitAlias(
self.lower_generics(
generics,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
),
self.lower_param_bounds(
bounds,
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
),
2019-08-10 20:13:12 +02:00
),
2021-07-30 23:50:57 -07:00
ItemKind::MacroDef(MacroDef { ref body, macro_rules }) => {
let body = P(self.lower_mac_args(body));
let macro_kind = self.resolver.decl_macro_kind(self.resolver.local_def_id(id));
hir::ItemKind::Macro(ast::MacroDef { body, macro_rules }, macro_kind)
2021-07-30 23:50:57 -07:00
}
ItemKind::MacCall(..) => {
2020-03-21 02:38:48 +01:00
panic!("`TyMac` should have been expanded by now")
2019-12-22 17:42:04 -05:00
}
2019-08-10 20:13:12 +02:00
}
}
fn lower_const_item(
&mut self,
ty: &Ty,
span: Span,
body: Option<&Expr>,
) -> (&'hir hir::Ty<'hir>, hir::BodyId) {
let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
(ty, self.lower_const_body(span, body))
}
2019-08-10 20:13:12 +02:00
fn lower_use_tree(
&mut self,
tree: &UseTree,
prefix: &Path,
id: NodeId,
2019-11-30 17:46:46 +01:00
vis: &mut hir::Visibility<'hir>,
2019-08-10 20:13:12 +02:00
ident: &mut Ident,
2021-01-24 17:14:17 +01:00
attrs: Option<&'hir [Attribute]>,
2019-11-28 19:28:50 +01:00
) -> hir::ItemKind<'hir> {
2019-08-10 20:13:12 +02:00
debug!("lower_use_tree(tree={:?})", tree);
debug!("lower_use_tree: vis = {:?}", vis);
let path = &tree.prefix;
2019-12-22 17:42:04 -05:00
let segments = prefix.segments.iter().chain(path.segments.iter()).cloned().collect();
2019-08-10 20:13:12 +02:00
match tree.kind {
UseTreeKind::Simple(rename, id1, id2) => {
*ident = tree.ident();
// First, apply the prefix to the path.
2020-08-21 18:51:23 -04:00
let mut path = Path { segments, span: path.span, tokens: None };
2019-08-10 20:13:12 +02:00
// Correctly resolve `self` imports.
if path.segments.len() > 1
&& path.segments.last().unwrap().ident.name == kw::SelfLower
{
let _ = path.segments.pop();
if rename.is_none() {
*ident = path.segments.last().unwrap().ident;
}
}
2021-07-14 19:53:57 +02:00
let mut resolutions = self.expect_full_res_from_use(id).fuse();
2019-08-10 20:13:12 +02:00
// We want to return *something* from this function, so hold onto the first item
// for later.
let ret_res = self.lower_res(resolutions.next().unwrap_or(Res::Err));
// Here, we are looping over namespaces, if they exist for the definition
// being imported. We only handle type and value namespaces because we
// won't be dealing with macros in the rest of the compiler.
// Essentially a single `use` which imports two names is desugared into
// two imports.
2021-07-14 19:53:57 +02:00
for new_node_id in [id1, id2] {
let new_id = self.resolver.local_def_id(new_node_id);
2022-02-02 12:45:20 +01:00
let Some(res) = resolutions.next() else {
// Associate an HirId to both ids even if there is no resolution.
self.owners.ensure_contains_elem(new_id, || hir::MaybeOwner::Phantom);
let _old = std::mem::replace(
&mut self.owners[new_id],
hir::MaybeOwner::NonOwner(hir::HirId::make_owner(new_id)),
);
debug_assert!(matches!(_old, hir::MaybeOwner::Phantom));
continue;
};
2019-08-10 20:13:12 +02:00
let ident = *ident;
let mut path = path.clone();
for seg in &mut path.segments {
seg.id = self.resolver.next_node_id();
2019-08-10 20:13:12 +02:00
}
let span = path.span;
self.with_hir_id_owner(new_node_id, |this| {
let res = this.lower_res(res);
2021-07-15 22:19:39 +02:00
let path = this.lower_path_extra(res, &path, ParamMode::Explicit);
2019-12-04 19:45:50 +01:00
let kind = hir::ItemKind::Use(path, hir::UseKind::Single);
2019-08-10 20:13:12 +02:00
let vis = this.rebuild_vis(&vis);
2021-01-24 17:14:17 +01:00
if let Some(attrs) = attrs {
2021-07-16 14:42:26 +02:00
this.attrs.insert(hir::ItemLocalId::new(0), attrs);
2021-01-24 17:14:17 +01:00
}
2019-08-10 20:13:12 +02:00
let item = hir::Item {
2021-07-14 19:53:57 +02:00
def_id: new_id,
ident: this.lower_ident(ident),
2019-12-22 17:42:04 -05:00
kind,
vis,
span: this.lower_span(span),
};
hir::OwnerNode::Item(this.arena.alloc(item))
2019-08-10 20:13:12 +02:00
});
}
2021-07-15 22:19:39 +02:00
let path = self.lower_path_extra(ret_res, &path, ParamMode::Explicit);
2019-08-10 20:13:12 +02:00
hir::ItemKind::Use(path, hir::UseKind::Single)
}
UseTreeKind::Glob => {
2020-08-21 18:51:23 -04:00
let path = self.lower_path(
id,
&Path { segments, span: path.span, tokens: None },
ParamMode::Explicit,
);
2019-08-10 20:13:12 +02:00
hir::ItemKind::Use(path, hir::UseKind::Glob)
}
UseTreeKind::Nested(ref trees) => {
// Nested imports are desugared into simple imports.
// So, if we start with
//
// ```
// pub(x) use foo::{a, b};
// ```
//
// we will create three items:
//
// ```
// pub(x) use foo::a;
// pub(x) use foo::b;
// pub(x) use foo::{}; // <-- this is called the `ListStem`
// ```
//
// The first two are produced by recursively invoking
// `lower_use_tree` (and indeed there may be things
// like `use foo::{a::{b, c}}` and so forth). They
// wind up being directly added to
// `self.items`. However, the structure of this
// function also requires us to return one item, and
// for that we return the `{}` import (called the
// `ListStem`).
2020-08-21 18:51:23 -04:00
let prefix = Path { segments, span: prefix.span.to(path.span), tokens: None };
2019-08-10 20:13:12 +02:00
// Add all the nested `PathListItem`s to the HIR.
for &(ref use_tree, id) in trees {
let new_hir_id = self.resolver.local_def_id(id);
2019-08-10 20:13:12 +02:00
let mut prefix = prefix.clone();
// Give the segments new node-ids since they are being cloned.
for seg in &mut prefix.segments {
seg.id = self.resolver.next_node_id();
2019-08-10 20:13:12 +02:00
}
// Each `use` import is an item and thus are owners of the
// names in the path. Up to this point the nested import is
// the current owner, since we want each desugared import to
// own its own names, we have to adjust the owner before
// lowering the rest of the import.
self.with_hir_id_owner(id, |this| {
let mut vis = this.rebuild_vis(&vis);
let mut ident = *ident;
2019-12-22 17:42:04 -05:00
let kind =
this.lower_use_tree(use_tree, &prefix, id, &mut vis, &mut ident, attrs);
2021-01-24 17:14:17 +01:00
if let Some(attrs) = attrs {
2021-07-16 14:42:26 +02:00
this.attrs.insert(hir::ItemLocalId::new(0), attrs);
2021-01-24 17:14:17 +01:00
}
2019-12-22 17:42:04 -05:00
let item = hir::Item {
2021-07-14 19:53:57 +02:00
def_id: new_hir_id,
ident: this.lower_ident(ident),
2019-12-22 17:42:04 -05:00
kind,
vis,
span: this.lower_span(use_tree.span),
};
hir::OwnerNode::Item(this.arena.alloc(item))
2019-08-10 20:13:12 +02:00
});
}
// Subtle and a bit hacky: we lower the privacy level
// of the list stem to "private" most of the time, but
// not for "restricted" paths. The key thing is that
// we don't want it to stay as `pub` (with no caveats)
// because that affects rustdoc and also the lints
// about `pub` items. But we can't *always* make it
// private -- particularly not for restricted paths --
// because it contains node-ids that would then be
// unused, failing the check that HirIds are "densely
// assigned".
match vis.node {
2019-12-22 17:42:04 -05:00
hir::VisibilityKind::Public
| hir::VisibilityKind::Crate(_)
| hir::VisibilityKind::Inherited => {
*vis = respan(
self.lower_span(prefix.span.shrink_to_lo()),
hir::VisibilityKind::Inherited,
);
2019-08-10 20:13:12 +02:00
}
hir::VisibilityKind::Restricted { .. } => {
// Do nothing here, as described in the comment on the match.
}
}
let res = self.expect_full_res_from_use(id).next().unwrap_or(Res::Err);
let res = self.lower_res(res);
2021-07-15 22:19:39 +02:00
let path = self.lower_path_extra(res, &prefix, ParamMode::Explicit);
2019-08-10 20:13:12 +02:00
hir::ItemKind::Use(path, hir::UseKind::ListStem)
}
}
}
/// Paths like the visibility path in `pub(super) use foo::{bar, baz}` are repeated
/// many times in the HIR tree; for each occurrence, we need to assign distinct
/// `NodeId`s. (See, e.g., #56128.)
2019-12-04 19:45:50 +01:00
fn rebuild_use_path(&mut self, path: &hir::Path<'hir>) -> &'hir hir::Path<'hir> {
2019-08-10 20:13:12 +02:00
debug!("rebuild_use_path(path = {:?})", path);
2019-12-01 11:22:58 +01:00
let segments =
self.arena.alloc_from_iter(path.segments.iter().map(|seg| hir::PathSegment {
2019-12-22 17:42:04 -05:00
ident: seg.ident,
hir_id: seg.hir_id.map(|_| self.next_id()),
res: seg.res,
args: None,
infer_args: seg.infer_args,
2019-12-01 11:22:58 +01:00
}));
2019-12-04 19:45:50 +01:00
self.arena.alloc(hir::Path { span: path.span, res: path.res, segments })
2019-08-10 20:13:12 +02:00
}
2019-11-30 17:46:46 +01:00
fn rebuild_vis(&mut self, vis: &hir::Visibility<'hir>) -> hir::Visibility<'hir> {
2019-08-10 20:13:12 +02:00
let vis_kind = match vis.node {
hir::VisibilityKind::Public => hir::VisibilityKind::Public,
hir::VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar),
hir::VisibilityKind::Inherited => hir::VisibilityKind::Inherited,
hir::VisibilityKind::Restricted { ref path, hir_id: _ } => {
hir::VisibilityKind::Restricted {
2019-12-04 19:45:50 +01:00
path: self.rebuild_use_path(path),
2019-08-10 20:13:12 +02:00
hir_id: self.next_id(),
}
}
};
respan(self.lower_span(vis.span), vis_kind)
2019-08-10 20:13:12 +02:00
}
fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> {
let hir_id = self.lower_node_id(i.id);
let def_id = hir_id.expect_owner();
2020-11-27 00:35:22 +01:00
self.lower_attrs(hir_id, &i.attrs);
let item = hir::ForeignItem {
def_id,
ident: self.lower_ident(i.ident),
kind: match i.kind {
ForeignItemKind::Fn(box Fn { ref sig, ref generics, .. }) => {
let fdec = &sig.decl;
2019-08-10 20:13:12 +02:00
let (generics, (fn_dec, fn_args)) = self.add_in_band_defs(
generics,
def_id,
AnonymousLifetimeMode::PassThrough,
|this, _| {
(
// Disallow `impl Trait` in foreign items.
this.lower_fn_decl(fdec, None, FnDeclKind::ExternFn, None),
this.lower_fn_params_to_names(fdec),
2019-08-10 20:13:12 +02:00
)
},
);
hir::ForeignItemKind::Fn(fn_dec, fn_args, generics)
}
ForeignItemKind::Static(ref t, m, _) => {
let ty =
self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
2019-12-01 11:22:58 +01:00
hir::ForeignItemKind::Static(ty, m)
2019-08-10 20:13:12 +02:00
}
ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type,
2020-02-29 19:32:20 +03:00
ForeignItemKind::MacCall(_) => panic!("macro shouldn't exist here"),
2019-08-10 20:13:12 +02:00
},
2021-07-15 22:19:39 +02:00
vis: self.lower_visibility(&i.vis),
span: self.lower_span(i.span),
};
self.arena.alloc(item)
2019-08-10 20:13:12 +02:00
}
2021-07-15 22:19:39 +02:00
fn lower_foreign_item_ref(&mut self, i: &ForeignItem) -> hir::ForeignItemRef {
2020-11-11 21:57:54 +01:00
hir::ForeignItemRef {
id: hir::ForeignItemId { def_id: self.resolver.local_def_id(i.id) },
ident: self.lower_ident(i.ident),
span: self.lower_span(i.span),
2020-11-11 21:57:54 +01:00
}
}
2019-11-29 09:26:18 +01:00
fn lower_variant(&mut self, v: &Variant) -> hir::Variant<'hir> {
let id = self.lower_node_id(v.id);
2020-11-27 00:07:36 +01:00
self.lower_attrs(id, &v.attrs);
2019-08-13 21:40:21 -03:00
hir::Variant {
id,
data: self.lower_variant_data(id, &v.data),
2019-08-13 21:40:21 -03:00
disr_expr: v.disr_expr.as_ref().map(|e| self.lower_anon_const(e)),
ident: self.lower_ident(v.ident),
span: self.lower_span(v.span),
2019-08-10 20:13:12 +02:00
}
}
fn lower_variant_data(
&mut self,
parent_id: hir::HirId,
vdata: &VariantData,
) -> hir::VariantData<'hir> {
2019-08-10 20:13:12 +02:00
match *vdata {
VariantData::Struct(ref fields, recovered) => hir::VariantData::Struct(
2019-12-22 17:42:04 -05:00
self.arena
.alloc_from_iter(fields.iter().enumerate().map(|f| self.lower_field_def(f))),
2019-08-10 20:13:12 +02:00
recovered,
),
VariantData::Tuple(ref fields, id) => {
let ctor_id = self.lower_node_id(id);
2021-01-24 17:14:17 +01:00
self.alias_attrs(ctor_id, parent_id);
hir::VariantData::Tuple(
self.arena.alloc_from_iter(
fields.iter().enumerate().map(|f| self.lower_field_def(f)),
),
ctor_id,
)
}
VariantData::Unit(id) => {
let ctor_id = self.lower_node_id(id);
2021-01-24 17:14:17 +01:00
self.alias_attrs(ctor_id, parent_id);
hir::VariantData::Unit(ctor_id)
}
2019-08-10 20:13:12 +02:00
}
}
fn lower_field_def(&mut self, (index, f): (usize, &FieldDef)) -> hir::FieldDef<'hir> {
2019-09-26 17:25:31 +01:00
let ty = if let TyKind::Path(ref qself, ref path) = f.ty.kind {
2019-08-10 20:13:12 +02:00
let t = self.lower_path_ty(
&f.ty,
qself,
path,
ParamMode::ExplicitNamed, // no `'_` in declarations (Issue #61124)
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
2019-08-10 20:13:12 +02:00
);
2019-11-29 09:40:33 +01:00
self.arena.alloc(t)
2019-08-10 20:13:12 +02:00
} else {
self.lower_ty(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type))
2019-08-10 20:13:12 +02:00
};
let hir_id = self.lower_node_id(f.id);
2020-11-27 00:27:34 +01:00
self.lower_attrs(hir_id, &f.attrs);
hir::FieldDef {
span: self.lower_span(f.span),
hir_id,
2019-08-10 20:13:12 +02:00
ident: match f.ident {
Some(ident) => self.lower_ident(ident),
2019-08-10 20:13:12 +02:00
// FIXME(jseyfried): positional field hygiene.
None => Ident::new(sym::integer(index), self.lower_span(f.span)),
2019-08-10 20:13:12 +02:00
},
2021-07-15 22:19:39 +02:00
vis: self.lower_visibility(&f.vis),
2019-08-10 20:13:12 +02:00
ty,
}
}
fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
let hir_id = self.lower_node_id(i.id);
let trait_item_def_id = hir_id.expect_owner();
2019-08-10 20:13:12 +02:00
let (generics, kind) = match i.kind {
AssocItemKind::Const(_, ref ty, ref default) => {
let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
2020-02-13 18:03:38 +01:00
let body = default.as_ref().map(|x| self.lower_const_body(i.span, Some(x)));
(hir::Generics::empty(), hir::TraitItemKind::Const(ty, body))
2019-12-22 17:42:04 -05:00
}
AssocItemKind::Fn(box Fn { ref sig, ref generics, body: None, .. }) => {
let names = self.lower_fn_params_to_names(&sig.decl);
let (generics, sig) = self.lower_method_sig(
generics,
sig,
trait_item_def_id,
FnDeclKind::Trait,
None,
);
2020-03-05 09:57:34 -06:00
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)))
2019-08-10 20:13:12 +02:00
}
AssocItemKind::Fn(box Fn { ref sig, ref generics, body: Some(ref body), .. }) => {
let asyncness = sig.header.asyncness;
let body_id =
self.lower_maybe_async_body(i.span, &sig.decl, asyncness, Some(&body));
let (generics, sig) = self.lower_method_sig(
generics,
sig,
trait_item_def_id,
FnDeclKind::Trait,
asyncness.opt_return_id(),
);
2020-03-05 09:57:34 -06:00
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)))
2019-08-10 20:13:12 +02:00
}
AssocItemKind::TyAlias(box TyAlias {
ref generics,
where_clauses,
ref bounds,
ref ty,
..
}) => {
let ty = ty.as_ref().map(|x| {
self.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Type))
});
let mut generics = generics.clone();
add_ty_alias_where_clause(&mut generics, where_clauses, false);
let generics = self.lower_generics(
&generics,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
);
let kind = hir::TraitItemKind::Type(
self.lower_param_bounds(
bounds,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
),
2019-11-28 21:47:10 +01:00
ty,
2019-08-10 20:13:12 +02:00
);
(generics, kind)
2019-12-22 17:42:04 -05:00
}
2020-03-21 02:38:48 +01:00
AssocItemKind::MacCall(..) => panic!("macro item shouldn't exist at this point"),
2019-08-10 20:13:12 +02:00
};
2020-11-27 09:41:53 +01:00
self.lower_attrs(hir_id, &i.attrs);
let item = hir::TraitItem {
def_id: trait_item_def_id,
ident: self.lower_ident(i.ident),
generics,
kind,
span: self.lower_span(i.span),
};
self.arena.alloc(item)
2019-08-10 20:13:12 +02:00
}
fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef {
2020-02-13 18:03:38 +01:00
let (kind, has_default) = match &i.kind {
AssocItemKind::Const(_, _, default) => (hir::AssocItemKind::Const, default.is_some()),
AssocItemKind::TyAlias(box TyAlias { ty, .. }) => {
(hir::AssocItemKind::Type, ty.is_some())
2020-02-15 01:50:26 +01:00
}
AssocItemKind::Fn(box Fn { sig, body, .. }) => {
(hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }, body.is_some())
2019-08-10 20:13:12 +02:00
}
2020-02-29 19:32:20 +03:00
AssocItemKind::MacCall(..) => unimplemented!(),
2019-08-10 20:13:12 +02:00
};
2021-07-14 18:54:56 +02:00
let id = hir::TraitItemId { def_id: self.resolver.local_def_id(i.id) };
let defaultness = hir::Defaultness::Default { has_value: has_default };
hir::TraitItemRef {
id,
ident: self.lower_ident(i.ident),
span: self.lower_span(i.span),
defaultness,
kind,
}
2019-08-10 20:13:12 +02:00
}
/// Construct `ExprKind::Err` for the given `span`.
crate fn expr_err(&mut self, span: Span) -> hir::Expr<'hir> {
2019-12-03 16:38:34 +01:00
self.expr(span, hir::ExprKind::Err, AttrVec::new())
}
fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
let impl_item_def_id = self.resolver.local_def_id(i.id);
2019-08-10 20:13:12 +02:00
let (generics, kind) = match &i.kind {
AssocItemKind::Const(_, ty, expr) => {
let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
2019-12-22 17:42:04 -05:00
(
2020-02-13 18:03:38 +01:00
hir::Generics::empty(),
2019-12-22 17:42:04 -05:00
hir::ImplItemKind::Const(ty, self.lower_const_body(i.span, expr.as_deref())),
)
}
AssocItemKind::Fn(box Fn { sig, generics, body, .. }) => {
2019-08-10 20:13:12 +02:00
self.current_item = Some(i.span);
let asyncness = sig.header.asyncness;
let body_id =
self.lower_maybe_async_body(i.span, &sig.decl, asyncness, body.as_deref());
2019-08-10 20:13:12 +02:00
let (generics, sig) = self.lower_method_sig(
2020-02-13 18:03:38 +01:00
generics,
2019-08-10 20:13:12 +02:00
sig,
impl_item_def_id,
if self.is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent },
asyncness.opt_return_id(),
2019-08-10 20:13:12 +02:00
);
2020-03-05 09:57:34 -06:00
(generics, hir::ImplItemKind::Fn(sig, body_id))
2019-08-10 20:13:12 +02:00
}
AssocItemKind::TyAlias(box TyAlias { generics, where_clauses, ty, .. }) => {
let mut generics = generics.clone();
add_ty_alias_where_clause(&mut generics, *where_clauses, false);
let generics = self.lower_generics(
&generics,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
);
let kind = match ty {
None => {
2019-11-28 22:16:44 +01:00
let ty = self.arena.alloc(self.ty(i.span, hir::TyKind::Err));
hir::ImplItemKind::TyAlias(ty)
}
2020-05-10 11:57:58 +01:00
Some(ty) => {
let ty = self.lower_ty(
ty,
ImplTraitContext::TypeAliasesOpaqueTy {
capturable_lifetimes: &mut FxHashSet::default(),
},
2020-05-10 11:57:58 +01:00
);
hir::ImplItemKind::TyAlias(ty)
}
};
(generics, kind)
2019-12-22 17:42:04 -05:00
}
2020-03-21 02:38:48 +01:00
AssocItemKind::MacCall(..) => panic!("`TyMac` should have been expanded by now"),
2019-08-10 20:13:12 +02:00
};
let hir_id = self.lower_node_id(i.id);
2020-11-27 09:55:10 +01:00
self.lower_attrs(hir_id, &i.attrs);
let item = hir::ImplItem {
def_id: hir_id.expect_owner(),
ident: self.lower_ident(i.ident),
2019-08-10 20:13:12 +02:00
generics,
2021-07-15 22:19:39 +02:00
vis: self.lower_visibility(&i.vis),
kind,
span: self.lower_span(i.span),
};
self.arena.alloc(item)
2019-08-10 20:13:12 +02:00
}
2021-07-15 22:19:39 +02:00
fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef {
// Since `default impl` is not yet implemented, this is always true in impls.
let has_value = true;
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
2019-08-10 20:13:12 +02:00
hir::ImplItemRef {
id: hir::ImplItemId { def_id: self.resolver.local_def_id(i.id) },
ident: self.lower_ident(i.ident),
span: self.lower_span(i.span),
defaultness,
kind: match &i.kind {
AssocItemKind::Const(..) => hir::AssocItemKind::Const,
2020-05-10 11:57:58 +01:00
AssocItemKind::TyAlias(..) => hir::AssocItemKind::Type,
AssocItemKind::Fn(box Fn { sig, .. }) => {
hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }
2019-12-22 17:42:04 -05:00
}
2020-02-29 19:32:20 +03:00
AssocItemKind::MacCall(..) => unimplemented!(),
2019-08-10 20:13:12 +02:00
},
trait_item_def_id: self.resolver.get_partial_res(i.id).map(|r| r.base_res().def_id()),
2019-08-10 20:13:12 +02:00
}
}
/// If an `explicit_owner` is given, this method allocates the `HirId` in
/// the address space of that item instead of the item currently being
/// lowered. This can happen during `lower_impl_item_ref()` where we need to
/// lower a `Visibility` value although we haven't lowered the owning
/// `ImplItem` in question yet.
2021-07-15 22:19:39 +02:00
fn lower_visibility(&mut self, v: &Visibility) -> hir::Visibility<'hir> {
let node = match v.kind {
2019-08-10 20:13:12 +02:00
VisibilityKind::Public => hir::VisibilityKind::Public,
VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar),
VisibilityKind::Restricted { ref path, id } => {
debug!("lower_visibility: restricted path id = {:?}", id);
2021-07-15 22:19:39 +02:00
let lowered_id = self.lower_node_id(id);
2019-08-10 20:13:12 +02:00
hir::VisibilityKind::Restricted {
2021-07-15 22:19:39 +02:00
path: self.lower_path(id, path, ParamMode::Explicit),
2019-08-10 20:13:12 +02:00
hir_id: lowered_id,
}
2019-12-22 17:42:04 -05:00
}
2019-08-10 20:13:12 +02:00
VisibilityKind::Inherited => hir::VisibilityKind::Inherited,
};
respan(self.lower_span(v.span), node)
2019-08-10 20:13:12 +02:00
}
fn lower_defaultness(
&self,
d: Defaultness,
has_value: bool,
) -> (hir::Defaultness, Option<Span>) {
2019-08-10 20:13:12 +02:00
match d {
Defaultness::Default(sp) => {
(hir::Defaultness::Default { has_value }, Some(self.lower_span(sp)))
}
2019-08-10 20:13:12 +02:00
Defaultness::Final => {
assert!(has_value);
(hir::Defaultness::Final, None)
2019-08-10 20:13:12 +02:00
}
}
}
2019-11-29 13:43:03 +01:00
fn record_body(
&mut self,
params: &'hir [hir::Param<'hir>],
value: hir::Expr<'hir>,
) -> hir::BodyId {
2019-12-22 17:42:04 -05:00
let body = hir::Body { generator_kind: self.generator_kind, params, value };
2019-08-10 20:13:12 +02:00
let id = body.id();
2021-07-16 14:42:26 +02:00
debug_assert_eq!(id.hir_id.owner, self.current_hir_id_owner);
2021-10-21 23:08:57 +02:00
self.bodies.push((id.hir_id.local_id, self.arena.alloc(body)));
2019-08-10 20:13:12 +02:00
id
}
pub(super) fn lower_body(
2019-08-10 20:13:12 +02:00
&mut self,
2019-11-29 13:43:03 +01:00
f: impl FnOnce(&mut Self) -> (&'hir [hir::Param<'hir>], hir::Expr<'hir>),
2019-08-10 20:13:12 +02:00
) -> hir::BodyId {
let prev_gen_kind = self.generator_kind.take();
2020-04-01 00:41:40 +02:00
let task_context = self.task_context.take();
let (parameters, result) = f(self);
let body_id = self.record_body(parameters, result);
2020-04-01 00:41:40 +02:00
self.task_context = task_context;
2019-08-10 20:13:12 +02:00
self.generator_kind = prev_gen_kind;
body_id
}
2019-11-29 13:43:03 +01:00
fn lower_param(&mut self, param: &Param) -> hir::Param<'hir> {
let hir_id = self.lower_node_id(param.id);
2020-11-26 23:51:27 +01:00
self.lower_attrs(hir_id, &param.attrs);
hir::Param {
hir_id,
pat: self.lower_pat(&param.pat),
ty_span: self.lower_span(param.ty.span),
span: self.lower_span(param.span),
2019-08-10 20:23:34 +02:00
}
}
2019-08-10 20:13:12 +02:00
pub(super) fn lower_fn_body(
&mut self,
decl: &FnDecl,
2019-11-29 13:43:03 +01:00
body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
2019-08-10 20:13:12 +02:00
) -> hir::BodyId {
2019-12-22 17:42:04 -05:00
self.lower_body(|this| {
(
this.arena.alloc_from_iter(decl.inputs.iter().map(|x| this.lower_param(x))),
body(this),
)
})
2019-08-10 20:13:12 +02:00
}
fn lower_fn_body_block(
&mut self,
span: Span,
decl: &FnDecl,
body: Option<&Block>,
) -> hir::BodyId {
self.lower_fn_body(decl, |this| this.lower_block_expr_opt(span, body))
}
2019-11-29 13:43:03 +01:00
fn lower_block_expr_opt(&mut self, span: Span, block: Option<&Block>) -> hir::Expr<'hir> {
match block {
Some(block) => self.lower_block_expr(block),
None => self.expr_err(span),
}
2019-08-10 20:13:12 +02:00
}
pub(super) fn lower_const_body(&mut self, span: Span, expr: Option<&Expr>) -> hir::BodyId {
2019-12-22 17:42:04 -05:00
self.lower_body(|this| {
(
&[],
match expr {
2019-12-01 21:10:43 +01:00
Some(expr) => this.lower_expr_mut(expr),
2019-12-22 17:42:04 -05:00
None => this.expr_err(span),
},
)
})
2019-08-10 20:13:12 +02:00
}
fn lower_maybe_async_body(
&mut self,
span: Span,
2019-08-10 20:13:12 +02:00
decl: &FnDecl,
asyncness: Async,
body: Option<&Block>,
2019-08-10 20:13:12 +02:00
) -> hir::BodyId {
let closure_id = match asyncness {
Async::Yes { closure_id, .. } => closure_id,
Async::No => return self.lower_fn_body_block(span, decl, body),
2019-08-10 20:13:12 +02:00
};
self.lower_body(|this| {
2019-11-29 19:01:31 +01:00
let mut parameters: Vec<hir::Param<'_>> = Vec::new();
let mut statements: Vec<hir::Stmt<'_>> = Vec::new();
2019-08-10 20:13:12 +02:00
// Async function parameters are lowered into the closure body so that they are
2019-08-10 20:13:12 +02:00
// captured and so that the drop order matches the equivalent non-async functions.
//
// from:
//
// async fn foo(<pattern>: <ty>, <pattern>: <ty>, <pattern>: <ty>) {
// <body>
2019-08-10 20:13:12 +02:00
// }
//
// into:
//
// fn foo(__arg0: <ty>, __arg1: <ty>, __arg2: <ty>) {
// async move {
// let __arg2 = __arg2;
// let <pattern> = __arg2;
// let __arg1 = __arg1;
// let <pattern> = __arg1;
// let __arg0 = __arg0;
// let <pattern> = __arg0;
// drop-temps { <body> } // see comments later in fn for details
2019-08-10 20:13:12 +02:00
// }
// }
//
// If `<pattern>` is a simple ident, then it is lowered to a single
// `let <pattern> = <pattern>;` statement as an optimization.
//
// Note that the body is embedded in `drop-temps`; an
// equivalent desugaring would be `return { <body>
// };`. The key point is that we wish to drop all the
// let-bound variables and temporaries created in the body
// (and its tail expression!) before we drop the
// parameters (c.f. rust-lang/rust#64512).
for (index, parameter) in decl.inputs.iter().enumerate() {
let parameter = this.lower_param(parameter);
let span = parameter.pat.span;
2019-08-10 20:13:12 +02:00
// Check if this is a binding pattern, if so, we can optimize and avoid adding a
// `let <pat> = __argN;` statement. In this case, we do not rename the parameter.
2019-09-26 16:18:31 +01:00
let (ident, is_simple_parameter) = match parameter.pat.kind {
hir::PatKind::Binding(
hir::BindingAnnotation::Unannotated | hir::BindingAnnotation::Mutable,
_,
ident,
_,
) => (ident, true),
2020-11-10 07:49:06 -05:00
// For `ref mut` or wildcard arguments, we can't reuse the binding, but
// we can keep the same name for the parameter.
// This lets rustdoc render it correctly in documentation.
hir::PatKind::Binding(_, _, ident, _) => (ident, false),
2020-11-10 07:49:06 -05:00
hir::PatKind::Wild => {
(Ident::with_dummy_span(rustc_span::symbol::kw::Underscore), false)
}
2019-08-10 20:13:12 +02:00
_ => {
// Replace the ident for bindings that aren't simple.
let name = format!("__arg{}", index);
let ident = Ident::from_str(&name);
(ident, false)
2019-12-22 17:42:04 -05:00
}
2019-08-10 20:13:12 +02:00
};
2019-12-22 17:42:04 -05:00
let desugared_span = this.mark_span_with_reason(DesugaringKind::Async, span, None);
2019-08-10 20:13:12 +02:00
// Construct a parameter representing `__argN: <ty>` to replace the parameter of the
2019-08-10 20:13:12 +02:00
// async function.
//
// If this is the simple case, this parameter will end up being the same as the
// original parameter, but with a different pattern id.
2021-07-16 14:42:26 +02:00
let stmt_attrs = this.attrs.get(&parameter.hir_id.local_id).copied();
let (new_parameter_pat, new_parameter_id) = this.pat_ident(desugared_span, ident);
let new_parameter = hir::Param {
hir_id: parameter.hir_id,
pat: new_parameter_pat,
ty_span: this.lower_span(parameter.ty_span),
span: this.lower_span(parameter.span),
2019-08-10 20:13:12 +02:00
};
if is_simple_parameter {
2019-08-10 20:13:12 +02:00
// If this is the simple case, then we only insert one statement that is
// `let <pat> = <pat>;`. We re-use the original argument's pattern so that
// `HirId`s are densely assigned.
let expr = this.expr_ident(desugared_span, ident, new_parameter_id);
2019-08-10 20:13:12 +02:00
let stmt = this.stmt_let_pat(
stmt_attrs,
desugared_span,
2019-12-29 12:17:56 +01:00
Some(expr),
parameter.pat,
2019-12-22 17:42:04 -05:00
hir::LocalSource::AsyncFn,
2019-08-10 20:13:12 +02:00
);
statements.push(stmt);
} else {
// If this is not the simple case, then we construct two statements:
//
// ```
// let __argN = __argN;
// let <pat> = __argN;
// ```
//
// The first statement moves the parameter into the closure and thus ensures
2019-08-10 20:13:12 +02:00
// that the drop order is correct.
//
// The second statement creates the bindings that the user wrote.
// Construct the `let mut __argN = __argN;` statement. It must be a mut binding
// because the user may have specified a `ref mut` binding in the next
// statement.
let (move_pat, move_id) = this.pat_ident_binding_mode(
2019-12-22 17:42:04 -05:00
desugared_span,
ident,
hir::BindingAnnotation::Mutable,
);
let move_expr = this.expr_ident(desugared_span, ident, new_parameter_id);
2019-08-10 20:13:12 +02:00
let move_stmt = this.stmt_let_pat(
2021-01-24 17:14:17 +01:00
None,
2019-08-10 20:13:12 +02:00
desugared_span,
2019-12-29 12:17:56 +01:00
Some(move_expr),
2019-08-10 20:13:12 +02:00
move_pat,
2019-12-22 17:42:04 -05:00
hir::LocalSource::AsyncFn,
2019-08-10 20:13:12 +02:00
);
// Construct the `let <pat> = __argN;` statement. We re-use the original
// parameter's pattern so that `HirId`s are densely assigned.
2019-08-10 20:13:12 +02:00
let pattern_expr = this.expr_ident(desugared_span, ident, move_id);
let pattern_stmt = this.stmt_let_pat(
stmt_attrs,
desugared_span,
2019-12-29 12:17:56 +01:00
Some(pattern_expr),
parameter.pat,
2019-12-22 17:42:04 -05:00
hir::LocalSource::AsyncFn,
2019-08-10 20:13:12 +02:00
);
statements.push(move_stmt);
statements.push(pattern_stmt);
};
parameters.push(new_parameter);
2019-08-10 20:13:12 +02:00
}
let body_span = body.map_or(span, |b| b.span);
2019-08-10 20:13:12 +02:00
let async_expr = this.make_async_expr(
CaptureBy::Value,
closure_id,
None,
body_span,
hir::AsyncGeneratorKind::Fn,
2019-08-10 20:13:12 +02:00
|this| {
// Create a block from the user's function body:
let user_body = this.lower_block_expr_opt(body_span, body);
// Transform into `drop-temps { <user-body> }`, an expression:
2019-12-22 17:42:04 -05:00
let desugared_span =
this.mark_span_with_reason(DesugaringKind::Async, user_body.span, None);
2019-11-29 19:01:31 +01:00
let user_body = this.expr_drop_temps(
desugared_span,
this.arena.alloc(user_body),
AttrVec::new(),
);
// As noted above, create the final block like
//
// ```
// {
// let $param_pattern = $raw_param;
// ...
// drop-temps { <user-body> }
// }
// ```
2019-11-29 19:01:31 +01:00
let body = this.block_all(
desugared_span,
this.arena.alloc_from_iter(statements),
2019-12-01 21:10:43 +01:00
Some(user_body),
2019-11-29 19:01:31 +01:00
);
2019-12-01 21:10:43 +01:00
this.expr_block(body, AttrVec::new())
2019-12-22 17:42:04 -05:00
},
);
2019-11-29 11:09:23 +01:00
2019-12-01 12:49:54 +01:00
(
this.arena.alloc_from_iter(parameters),
this.expr(body_span, async_expr, AttrVec::new()),
)
2019-08-10 20:13:12 +02:00
})
}
fn lower_method_sig(
&mut self,
generics: &Generics,
2019-11-07 13:11:59 +01:00
sig: &FnSig,
fn_def_id: LocalDefId,
kind: FnDeclKind,
2019-08-10 20:13:12 +02:00
is_async: Option<NodeId>,
2019-11-30 17:46:46 +01:00
) -> (hir::Generics<'hir>, hir::FnSig<'hir>) {
2021-07-08 21:58:05 +02:00
let header = self.lower_fn_header(sig.header);
2019-08-10 20:13:12 +02:00
let (generics, decl) = self.add_in_band_defs(
generics,
fn_def_id,
AnonymousLifetimeMode::PassThrough,
|this, idty| this.lower_fn_decl(&sig.decl, Some((fn_def_id, idty)), kind, is_async),
2019-08-10 20:13:12 +02:00
);
(generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
2019-08-10 20:13:12 +02:00
}
2021-07-08 21:58:05 +02:00
fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader {
2019-08-10 20:13:12 +02:00
hir::FnHeader {
unsafety: self.lower_unsafety(h.unsafety),
asyncness: self.lower_asyncness(h.asyncness),
constness: self.lower_constness(h.constness),
2021-07-08 21:58:05 +02:00
abi: self.lower_extern(h.ext),
2019-08-10 20:13:12 +02:00
}
}
pub(super) fn lower_abi(&mut self, abi: StrLit) -> abi::Abi {
abi::lookup(abi.symbol_unescaped.as_str()).unwrap_or_else(|| {
self.error_on_invalid_abi(abi);
abi::Abi::Rust
})
}
2021-07-08 21:58:05 +02:00
pub(super) fn lower_extern(&mut self, ext: Extern) -> abi::Abi {
match ext {
Extern::None => abi::Abi::Rust,
2021-07-08 21:58:05 +02:00
Extern::Implicit => abi::Abi::FALLBACK,
Extern::Explicit(abi) => self.lower_abi(abi),
}
}
fn error_on_invalid_abi(&self, abi: StrLit) {
2019-12-22 17:42:04 -05:00
struct_span_err!(self.sess, abi.span, E0703, "invalid ABI: found `{}`", abi.symbol)
.span_label(abi.span, "invalid ABI")
.help(&format!("valid ABIs: {}", abi::all_names().join(", ")))
.emit();
}
fn lower_asyncness(&mut self, a: Async) -> hir::IsAsync {
2019-08-10 20:13:12 +02:00
match a {
Async::Yes { .. } => hir::IsAsync::Async,
Async::No => hir::IsAsync::NotAsync,
2019-08-10 20:13:12 +02:00
}
}
fn lower_constness(&mut self, c: Const) -> hir::Constness {
match c {
Const::Yes(_) => hir::Constness::Const,
Const::No => hir::Constness::NotConst,
}
}
pub(super) fn lower_unsafety(&mut self, u: Unsafe) -> hir::Unsafety {
match u {
Unsafe::Yes(_) => hir::Unsafety::Unsafe,
Unsafe::No => hir::Unsafety::Normal,
}
}
2019-12-01 17:10:12 +01:00
pub(super) fn lower_generics_mut(
2019-08-10 20:13:12 +02:00
&mut self,
generics: &Generics,
2019-12-01 11:22:58 +01:00
itctx: ImplTraitContext<'_, 'hir>,
2019-12-01 17:10:12 +01:00
) -> GenericsCtor<'hir> {
2022-03-01 20:02:47 +08:00
// Error if `?Trait` bounds in where clauses don't refer directly to type parameters.
// Note: we used to clone these bounds directly onto the type parameter (and avoid lowering
// these into hir when we lower thee where clauses), but this makes it quite difficult to
// keep track of the Span info. Now, `add_implicitly_sized` in `AstConv` checks both param bounds and
// where clauses for `?Sized`.
2019-08-10 20:13:12 +02:00
for pred in &generics.where_clause.predicates {
2022-02-19 00:48:49 +01:00
let WherePredicate::BoundPredicate(ref bound_pred) = *pred else {
continue;
};
let compute_is_param = || {
// Check if the where clause type is a plain type parameter.
match self
.resolver
.get_partial_res(bound_pred.bounded_ty.id)
.map(|d| (d.base_res(), d.unresolved_segments()))
{
Some((Res::Def(DefKind::TyParam, def_id), 0))
if bound_pred.bound_generic_params.is_empty() =>
{
generics
.params
.iter()
2021-10-07 23:18:39 +02:00
.any(|p| def_id == self.resolver.local_def_id(p.id).to_def_id())
2019-08-10 20:13:12 +02:00
}
// Either the `bounded_ty` is not a plain type parameter, or
// it's not found in the generic type parameters list.
_ => false,
}
};
// We only need to compute this once per `WherePredicate`, but don't
// need to compute this at all unless there is a Maybe bound.
let mut is_param: Option<bool> = None;
for bound in &bound_pred.bounds {
if !matches!(*bound, GenericBound::Trait(_, TraitBoundModifier::Maybe)) {
continue;
}
let is_param = *is_param.get_or_insert_with(compute_is_param);
if !is_param {
self.diagnostic().span_err(
bound.span(),
"`?Trait` bounds are only permitted at the \
point where a type parameter is declared",
);
2019-08-10 20:13:12 +02:00
}
}
}
2019-12-01 17:10:12 +01:00
GenericsCtor {
params: self.lower_generic_params_mut(&generics.params, itctx).collect(),
2019-08-10 20:13:12 +02:00
where_clause: self.lower_where_clause(&generics.where_clause),
span: self.lower_span(generics.span),
2019-08-10 20:13:12 +02:00
}
}
2019-12-01 17:10:12 +01:00
pub(super) fn lower_generics(
&mut self,
generics: &Generics,
itctx: ImplTraitContext<'_, 'hir>,
) -> hir::Generics<'hir> {
let generics_ctor = self.lower_generics_mut(generics, itctx);
generics_ctor.into_generics(self.arena)
}
2019-11-30 17:46:46 +01:00
fn lower_where_clause(&mut self, wc: &WhereClause) -> hir::WhereClause<'hir> {
2019-12-22 17:42:04 -05:00
self.with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| {
hir::WhereClause {
2019-12-01 11:22:58 +01:00
predicates: this.arena.alloc_from_iter(
wc.predicates.iter().map(|predicate| this.lower_where_predicate(predicate)),
),
span: this.lower_span(wc.span),
2019-12-22 17:42:04 -05:00
}
})
2019-08-10 20:13:12 +02:00
}
2019-11-30 17:46:46 +01:00
fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> {
2019-08-10 20:13:12 +02:00
match *pred {
WherePredicate::BoundPredicate(WhereBoundPredicate {
ref bound_generic_params,
ref bounded_ty,
ref bounds,
span,
}) => self.with_in_scope_lifetime_defs(&bound_generic_params, |this| {
hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
bound_generic_params: this.lower_generic_params(
bound_generic_params,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
),
bounded_ty: this.lower_ty(
bounded_ty,
ImplTraitContext::Disallowed(ImplTraitPosition::Type),
),
bounds: this.arena.alloc_from_iter(bounds.iter().map(|bound| {
this.lower_param_bound(
bound,
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
)
})),
span: this.lower_span(span),
2019-12-22 17:42:04 -05:00
})
}),
2019-08-10 20:13:12 +02:00
WherePredicate::RegionPredicate(WhereRegionPredicate {
ref lifetime,
ref bounds,
span,
}) => hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
span: self.lower_span(span),
2019-08-10 20:13:12 +02:00
lifetime: self.lower_lifetime(lifetime),
bounds: self.lower_param_bounds(
bounds,
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
),
2019-08-10 20:13:12 +02:00
}),
2019-12-22 17:42:04 -05:00
WherePredicate::EqPredicate(WhereEqPredicate { id, ref lhs_ty, ref rhs_ty, span }) => {
2019-08-10 20:13:12 +02:00
hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
hir_id: self.lower_node_id(id),
lhs_ty: self
.lower_ty(lhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type)),
rhs_ty: self
.lower_ty(rhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type)),
span: self.lower_span(span),
2019-08-10 20:13:12 +02:00
})
2019-12-22 17:42:04 -05:00
}
2019-08-10 20:13:12 +02:00
}
}
}
2019-12-01 17:10:12 +01:00
/// Helper struct for delayed construction of Generics.
pub(super) struct GenericsCtor<'hir> {
2019-12-30 23:25:47 +01:00
pub(super) params: SmallVec<[hir::GenericParam<'hir>; 4]>,
2019-12-01 17:10:12 +01:00
where_clause: hir::WhereClause<'hir>,
span: Span,
}
impl<'hir> GenericsCtor<'hir> {
2019-12-01 17:10:12 +01:00
pub(super) fn into_generics(self, arena: &'hir Arena<'hir>) -> hir::Generics<'hir> {
hir::Generics {
params: arena.alloc_from_iter(self.params),
where_clause: self.where_clause,
span: self.span,
}
}
}