Allocate ast ids for parameters

This commit is contained in:
Lukas Wirth 2023-09-28 13:16:11 +02:00
parent 3b1b58c225
commit 2b9dde14ab
5 changed files with 34 additions and 20 deletions

View File

@ -15,9 +15,7 @@
attr::Attrs,
db::DefDatabase,
expander::{Expander, Mark},
item_tree::{
self, AssocItem, FnFlags, ItemTree, ItemTreeId, MacroCall, ModItem, Param, TreeId,
},
item_tree::{self, AssocItem, FnFlags, ItemTree, ItemTreeId, MacroCall, ModItem, TreeId},
macro_call_as_call_id, macro_id_to_def_id,
nameres::{
attr_resolution::ResolvedAttr,
@ -69,7 +67,7 @@ pub(crate) fn fn_data_query(db: &dyn DefDatabase, func: FunctionId) -> Arc<Funct
let is_varargs = enabled_params
.clone()
.next_back()
.map_or(false, |param| matches!(item_tree[param], Param::Varargs));
.map_or(false, |param| item_tree[param].type_ref.is_none());
let mut flags = func.flags;
if is_varargs {
@ -105,10 +103,7 @@ pub(crate) fn fn_data_query(db: &dyn DefDatabase, func: FunctionId) -> Arc<Funct
name: func.name.clone(),
params: enabled_params
.clone()
.filter_map(|id| match &item_tree[id] {
Param::Normal(ty) => Some(ty.clone()),
Param::Varargs => None,
})
.filter_map(|id| item_tree[id].type_ref.clone())
.collect(),
ret_type: func.ret_type.clone(),
attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()),

View File

@ -613,10 +613,17 @@ pub struct Function {
pub(crate) flags: FnFlags,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum Param {
Normal(Interned<TypeRef>),
Varargs,
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Param {
/// This is [`None`] for varargs
pub type_ref: Option<Interned<TypeRef>>,
pub ast_id: ParamAstId,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ParamAstId {
Param(FileAstId<ast::Param>),
SelfParam(FileAstId<ast::SelfParam>),
}
bitflags::bitflags! {

View File

@ -295,8 +295,12 @@ fn lower_function(&mut self, func: &ast::Fn) -> Option<FileItemTreeId<Function>>
}
}
};
let ty = Interned::new(self_type);
let idx = self.data().params.alloc(Param::Normal(ty));
let type_ref = Interned::new(self_type);
let ast_id = self.source_ast_id_map.ast_id(&self_param);
let idx = self.data().params.alloc(Param {
type_ref: Some(type_ref),
ast_id: ParamAstId::SelfParam(ast_id),
});
self.add_attrs(
idx.into(),
RawAttrs::new(self.db.upcast(), &self_param, self.hygiene()),
@ -305,11 +309,19 @@ fn lower_function(&mut self, func: &ast::Fn) -> Option<FileItemTreeId<Function>>
}
for param in param_list.params() {
let idx = match param.dotdotdot_token() {
Some(_) => self.data().params.alloc(Param::Varargs),
Some(_) => {
let ast_id = self.source_ast_id_map.ast_id(&param);
self.data()
.params
.alloc(Param { type_ref: None, ast_id: ParamAstId::Param(ast_id) })
}
None => {
let type_ref = TypeRef::from_ast_opt(&self.body_ctx, param.ty());
let ty = Interned::new(type_ref);
self.data().params.alloc(Param::Normal(ty))
let ast_id = self.source_ast_id_map.ast_id(&param);
self.data()
.params
.alloc(Param { type_ref: Some(ty), ast_id: ParamAstId::Param(ast_id) })
}
};
self.add_attrs(idx.into(), RawAttrs::new(self.db.upcast(), &param, self.hygiene()));

View File

@ -261,15 +261,15 @@ fn print_mod_item(&mut self, item: ModItem) {
self.indented(|this| {
for param in params.clone() {
this.print_attrs_of(param, "\n");
match &this.tree[param] {
Param::Normal(ty) => {
match &this.tree[param].type_ref {
Some(ty) => {
if flags.contains(FnFlags::HAS_SELF_PARAM) {
w!(this, "self: ");
}
this.print_type_ref(ty);
wln!(this, ",");
}
Param::Varargs => {
None => {
wln!(this, "...");
}
};

View File

@ -99,7 +99,7 @@ impl AstIdNode for
TraitAlias,
TypeAlias,
Use,
AssocItem, BlockExpr, Variant, RecordField, TupleField, ConstArg
AssocItem, BlockExpr, Variant, RecordField, TupleField, ConstArg, Param, SelfParam
}
/// Maps items' `SyntaxNode`s to `ErasedFileAstId`s and back.