ItemTree: lower attributes on fn parameters
This commit is contained in:
parent
022a0f061e
commit
622c780a8c
@ -9,7 +9,7 @@
|
||||
attr::Attrs,
|
||||
body::Expander,
|
||||
db::DefDatabase,
|
||||
item_tree::{AssocItem, FunctionQualifier, ItemTreeId, ModItem},
|
||||
item_tree::{AssocItem, FunctionQualifier, ItemTreeId, ModItem, Param},
|
||||
type_ref::{TypeBound, TypeRef},
|
||||
visibility::RawVisibility,
|
||||
AssocContainerId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId,
|
||||
@ -38,17 +38,29 @@ pub(crate) fn fn_data_query(db: &dyn DefDatabase, func: FunctionId) -> Arc<Funct
|
||||
let krate = loc.container.module(db).krate;
|
||||
let item_tree = db.item_tree(loc.id.file_id);
|
||||
let func = &item_tree[loc.id.value];
|
||||
let is_varargs = func
|
||||
.params
|
||||
.clone()
|
||||
.last()
|
||||
.map_or(false, |param| matches!(item_tree[param], Param::Varargs));
|
||||
|
||||
Arc::new(FunctionData {
|
||||
name: func.name.clone(),
|
||||
params: func.params.iter().map(|id| item_tree[*id].clone()).collect(),
|
||||
params: func
|
||||
.params
|
||||
.clone()
|
||||
.filter_map(|id| match &item_tree[id] {
|
||||
Param::Normal(ty) => Some(item_tree[*ty].clone()),
|
||||
Param::Varargs => None,
|
||||
})
|
||||
.collect(),
|
||||
ret_type: item_tree[func.ret_type].clone(),
|
||||
attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()),
|
||||
has_self_param: func.has_self_param,
|
||||
has_body: func.has_body,
|
||||
qualifier: func.qualifier.clone(),
|
||||
is_in_extern_block: func.is_in_extern_block,
|
||||
is_varargs: func.is_varargs,
|
||||
is_varargs,
|
||||
visibility: item_tree[func.visibility].clone(),
|
||||
})
|
||||
}
|
||||
|
@ -134,6 +134,7 @@ fn shrink_to_fit(&mut self) {
|
||||
imports,
|
||||
extern_crates,
|
||||
functions,
|
||||
params,
|
||||
structs,
|
||||
fields,
|
||||
unions,
|
||||
@ -157,6 +158,7 @@ fn shrink_to_fit(&mut self) {
|
||||
imports.shrink_to_fit();
|
||||
extern_crates.shrink_to_fit();
|
||||
functions.shrink_to_fit();
|
||||
params.shrink_to_fit();
|
||||
structs.shrink_to_fit();
|
||||
fields.shrink_to_fit();
|
||||
unions.shrink_to_fit();
|
||||
@ -303,6 +305,7 @@ struct ItemTreeData {
|
||||
imports: Arena<Import>,
|
||||
extern_crates: Arena<ExternCrate>,
|
||||
functions: Arena<Function>,
|
||||
params: Arena<Param>,
|
||||
structs: Arena<Struct>,
|
||||
fields: Arena<Field>,
|
||||
unions: Arena<Union>,
|
||||
@ -334,6 +337,7 @@ pub enum AttrOwner {
|
||||
|
||||
Variant(Idx<Variant>),
|
||||
Field(Idx<Field>),
|
||||
Param(Idx<Param>),
|
||||
}
|
||||
|
||||
macro_rules! from_attrs {
|
||||
@ -348,7 +352,7 @@ fn from(t: $t) -> AttrOwner {
|
||||
};
|
||||
}
|
||||
|
||||
from_attrs!(ModItem(ModItem), Variant(Idx<Variant>), Field(Idx<Field>));
|
||||
from_attrs!(ModItem(ModItem), Variant(Idx<Variant>), Field(Idx<Field>), Param(Idx<Param>));
|
||||
|
||||
/// Trait implemented by all item nodes in the item tree.
|
||||
pub trait ItemTreeNode: Clone {
|
||||
@ -484,7 +488,7 @@ fn index(&self, index: Idx<$t>) -> &Self::Output {
|
||||
};
|
||||
}
|
||||
|
||||
impl_index!(fields: Field, variants: Variant);
|
||||
impl_index!(fields: Field, variants: Variant, params: Param);
|
||||
|
||||
impl Index<RawVisibilityId> for ItemTree {
|
||||
type Output = RawVisibility;
|
||||
@ -560,12 +564,17 @@ pub struct Function {
|
||||
/// Whether the function is located in an `extern` block (*not* whether it is an
|
||||
/// `extern "abi" fn`).
|
||||
pub is_in_extern_block: bool,
|
||||
pub params: Box<[Idx<TypeRef>]>,
|
||||
pub is_varargs: bool,
|
||||
pub params: IdRange<Param>,
|
||||
pub ret_type: Idx<TypeRef>,
|
||||
pub ast_id: FileAstId<ast::Fn>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub enum Param {
|
||||
Normal(Idx<TypeRef>),
|
||||
Varargs,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct FunctionQualifier {
|
||||
pub is_default: bool,
|
||||
@ -796,6 +805,7 @@ pub struct Variant {
|
||||
pub fields: Fields,
|
||||
}
|
||||
|
||||
/// A range of densely allocated ItemTree IDs.
|
||||
pub struct IdRange<T> {
|
||||
range: Range<u32>,
|
||||
_p: PhantomData<T>,
|
||||
|
@ -333,8 +333,8 @@ fn lower_function(&mut self, func: &ast::Fn) -> Option<FileItemTreeId<Function>>
|
||||
let visibility = self.lower_visibility(func);
|
||||
let name = func.name()?.as_name();
|
||||
|
||||
let mut params = Vec::new();
|
||||
let mut has_self_param = false;
|
||||
let start_param = self.next_param_idx();
|
||||
if let Some(param_list) = func.param_list() {
|
||||
if let Some(self_param) = param_list.self_param() {
|
||||
let self_type = match self_param.ty() {
|
||||
@ -356,22 +356,25 @@ fn lower_function(&mut self, func: &ast::Fn) -> Option<FileItemTreeId<Function>>
|
||||
}
|
||||
}
|
||||
};
|
||||
params.push(self_type);
|
||||
let ty = self.data().type_refs.intern(self_type);
|
||||
let idx = self.data().params.alloc(Param::Normal(ty));
|
||||
self.add_attrs(idx.into(), RawAttrs::new(&self_param, &self.hygiene));
|
||||
has_self_param = true;
|
||||
}
|
||||
for param in param_list.params() {
|
||||
let type_ref = TypeRef::from_ast_opt(&self.body_ctx, param.ty());
|
||||
params.push(type_ref);
|
||||
}
|
||||
}
|
||||
let params = params.into_iter().map(|param| self.data().type_refs.intern(param)).collect();
|
||||
|
||||
let mut is_varargs = false;
|
||||
if let Some(params) = func.param_list() {
|
||||
if let Some(last) = params.params().last() {
|
||||
is_varargs = last.dotdotdot_token().is_some();
|
||||
let idx = match param.dotdotdot_token() {
|
||||
Some(_) => self.data().params.alloc(Param::Varargs),
|
||||
None => {
|
||||
let type_ref = TypeRef::from_ast_opt(&self.body_ctx, param.ty());
|
||||
let ty = self.data().type_refs.intern(type_ref);
|
||||
self.data().params.alloc(Param::Normal(ty))
|
||||
}
|
||||
};
|
||||
self.add_attrs(idx.into(), RawAttrs::new(¶m, &self.hygiene));
|
||||
}
|
||||
}
|
||||
let end_param = self.next_param_idx();
|
||||
let params = IdRange::new(start_param..end_param);
|
||||
|
||||
let ret_type = match func.ret_type().and_then(|rt| rt.ty()) {
|
||||
Some(type_ref) => TypeRef::from_ast(&self.body_ctx, type_ref),
|
||||
@ -419,7 +422,6 @@ fn lower_function(&mut self, func: &ast::Fn) -> Option<FileItemTreeId<Function>>
|
||||
qualifier,
|
||||
is_in_extern_block: false,
|
||||
params,
|
||||
is_varargs,
|
||||
ret_type,
|
||||
ast_id,
|
||||
};
|
||||
@ -682,9 +684,11 @@ fn lower_generic_params(
|
||||
GenericsOwner::Function(func) => {
|
||||
generics.fill(&self.body_ctx, sm, node);
|
||||
// lower `impl Trait` in arguments
|
||||
for param in &*func.params {
|
||||
let param = self.data().type_refs.lookup(*param);
|
||||
generics.fill_implicit_impl_trait_args(param);
|
||||
for id in func.params.clone() {
|
||||
if let Param::Normal(ty) = self.data().params[id] {
|
||||
let ty = self.data().type_refs.lookup(ty);
|
||||
generics.fill_implicit_impl_trait_args(ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
GenericsOwner::Struct
|
||||
@ -769,6 +773,11 @@ fn next_variant_idx(&self) -> Idx<Variant> {
|
||||
self.tree.data.as_ref().map_or(0, |data| data.variants.len() as u32),
|
||||
))
|
||||
}
|
||||
fn next_param_idx(&self) -> Idx<Param> {
|
||||
Idx::from_raw(RawIdx::from(
|
||||
self.tree.data.as_ref().map_or(0, |data| data.params.len() as u32),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn desugar_future_path(orig: TypeRef) -> Path {
|
||||
|
Loading…
Reference in New Issue
Block a user