aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/data.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/data.rs')
-rw-r--r--crates/hir_def/src/data.rs62
1 files changed, 41 insertions, 21 deletions
diff --git a/crates/hir_def/src/data.rs b/crates/hir_def/src/data.rs
index 1a27f7bf2..0be868ba2 100644
--- a/crates/hir_def/src/data.rs
+++ b/crates/hir_def/src/data.rs
@@ -9,7 +9,7 @@ use crate::{
9 attr::Attrs, 9 attr::Attrs,
10 body::Expander, 10 body::Expander,
11 db::DefDatabase, 11 db::DefDatabase,
12 item_tree::{AssocItem, FunctionQualifier, ItemTreeId, ModItem}, 12 item_tree::{AssocItem, FunctionQualifier, ItemTreeId, ModItem, Param},
13 type_ref::{TypeBound, TypeRef}, 13 type_ref::{TypeBound, TypeRef},
14 visibility::RawVisibility, 14 visibility::RawVisibility,
15 AssocContainerId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId, 15 AssocContainerId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId,
@@ -36,19 +36,38 @@ impl FunctionData {
36 pub(crate) fn fn_data_query(db: &dyn DefDatabase, func: FunctionId) -> Arc<FunctionData> { 36 pub(crate) fn fn_data_query(db: &dyn DefDatabase, func: FunctionId) -> Arc<FunctionData> {
37 let loc = func.lookup(db); 37 let loc = func.lookup(db);
38 let krate = loc.container.module(db).krate; 38 let krate = loc.container.module(db).krate;
39 let item_tree = db.item_tree(loc.id.file_id); 39 let crate_graph = db.crate_graph();
40 let cfg_options = &crate_graph[krate].cfg_options;
41 let item_tree = loc.id.item_tree(db);
40 let func = &item_tree[loc.id.value]; 42 let func = &item_tree[loc.id.value];
41 43
44 let enabled_params = func
45 .params
46 .clone()
47 .filter(|&param| item_tree.attrs(db, krate, param.into()).is_cfg_enabled(cfg_options));
48
49 // If last cfg-enabled param is a `...` param, it's a varargs function.
50 let is_varargs = enabled_params
51 .clone()
52 .next_back()
53 .map_or(false, |param| matches!(item_tree[param], Param::Varargs));
54
42 Arc::new(FunctionData { 55 Arc::new(FunctionData {
43 name: func.name.clone(), 56 name: func.name.clone(),
44 params: func.params.iter().map(|id| item_tree[*id].clone()).collect(), 57 params: enabled_params
58 .clone()
59 .filter_map(|id| match &item_tree[id] {
60 Param::Normal(ty) => Some(item_tree[*ty].clone()),
61 Param::Varargs => None,
62 })
63 .collect(),
45 ret_type: item_tree[func.ret_type].clone(), 64 ret_type: item_tree[func.ret_type].clone(),
46 attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()), 65 attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()),
47 has_self_param: func.has_self_param, 66 has_self_param: func.has_self_param,
48 has_body: func.has_body, 67 has_body: func.has_body,
49 qualifier: func.qualifier.clone(), 68 qualifier: func.qualifier.clone(),
50 is_in_extern_block: func.is_in_extern_block, 69 is_in_extern_block: func.is_in_extern_block,
51 is_varargs: func.is_varargs, 70 is_varargs,
52 visibility: item_tree[func.visibility].clone(), 71 visibility: item_tree[func.visibility].clone(),
53 }) 72 })
54 } 73 }
@@ -70,7 +89,7 @@ impl TypeAliasData {
70 typ: TypeAliasId, 89 typ: TypeAliasId,
71 ) -> Arc<TypeAliasData> { 90 ) -> Arc<TypeAliasData> {
72 let loc = typ.lookup(db); 91 let loc = typ.lookup(db);
73 let item_tree = db.item_tree(loc.id.file_id); 92 let item_tree = loc.id.item_tree(db);
74 let typ = &item_tree[loc.id.value]; 93 let typ = &item_tree[loc.id.value];
75 94
76 Arc::new(TypeAliasData { 95 Arc::new(TypeAliasData {
@@ -96,23 +115,23 @@ pub struct TraitData {
96impl TraitData { 115impl TraitData {
97 pub(crate) fn trait_data_query(db: &dyn DefDatabase, tr: TraitId) -> Arc<TraitData> { 116 pub(crate) fn trait_data_query(db: &dyn DefDatabase, tr: TraitId) -> Arc<TraitData> {
98 let tr_loc = tr.lookup(db); 117 let tr_loc = tr.lookup(db);
99 let item_tree = db.item_tree(tr_loc.id.file_id); 118 let item_tree = tr_loc.id.item_tree(db);
100 let tr_def = &item_tree[tr_loc.id.value]; 119 let tr_def = &item_tree[tr_loc.id.value];
101 let name = tr_def.name.clone(); 120 let name = tr_def.name.clone();
102 let is_auto = tr_def.is_auto; 121 let is_auto = tr_def.is_auto;
103 let is_unsafe = tr_def.is_unsafe; 122 let is_unsafe = tr_def.is_unsafe;
104 let module_id = tr_loc.container; 123 let module_id = tr_loc.container;
105 let container = AssocContainerId::TraitId(tr); 124 let container = AssocContainerId::TraitId(tr);
106 let mut expander = Expander::new(db, tr_loc.id.file_id, module_id);
107 let visibility = item_tree[tr_def.visibility].clone(); 125 let visibility = item_tree[tr_def.visibility].clone();
108 let bounds = tr_def.bounds.clone(); 126 let bounds = tr_def.bounds.clone();
127 let mut expander = Expander::new(db, tr_loc.id.file_id(), module_id);
109 128
110 let items = collect_items( 129 let items = collect_items(
111 db, 130 db,
112 module_id, 131 module_id,
113 &mut expander, 132 &mut expander,
114 tr_def.items.iter().copied(), 133 tr_def.items.iter().copied(),
115 tr_loc.id.file_id, 134 tr_loc.id.file_id(),
116 container, 135 container,
117 100, 136 100,
118 ); 137 );
@@ -148,21 +167,21 @@ impl ImplData {
148 let _p = profile::span("impl_data_query"); 167 let _p = profile::span("impl_data_query");
149 let impl_loc = id.lookup(db); 168 let impl_loc = id.lookup(db);
150 169
151 let item_tree = db.item_tree(impl_loc.id.file_id); 170 let item_tree = impl_loc.id.item_tree(db);
152 let impl_def = &item_tree[impl_loc.id.value]; 171 let impl_def = &item_tree[impl_loc.id.value];
153 let target_trait = impl_def.target_trait.map(|id| item_tree[id].clone()); 172 let target_trait = impl_def.target_trait.map(|id| item_tree[id].clone());
154 let target_type = item_tree[impl_def.target_type].clone(); 173 let target_type = item_tree[impl_def.target_type].clone();
155 let is_negative = impl_def.is_negative; 174 let is_negative = impl_def.is_negative;
156 let module_id = impl_loc.container; 175 let module_id = impl_loc.container;
157 let container = AssocContainerId::ImplId(id); 176 let container = AssocContainerId::ImplId(id);
158 let mut expander = Expander::new(db, impl_loc.id.file_id, module_id); 177 let mut expander = Expander::new(db, impl_loc.id.file_id(), module_id);
159 178
160 let items = collect_items( 179 let items = collect_items(
161 db, 180 db,
162 module_id, 181 module_id,
163 &mut expander, 182 &mut expander,
164 impl_def.items.iter().copied(), 183 impl_def.items.iter().copied(),
165 impl_loc.id.file_id, 184 impl_loc.id.file_id(),
166 container, 185 container,
167 100, 186 100,
168 ); 187 );
@@ -183,7 +202,7 @@ pub struct ConstData {
183impl ConstData { 202impl ConstData {
184 pub(crate) fn const_data_query(db: &dyn DefDatabase, konst: ConstId) -> Arc<ConstData> { 203 pub(crate) fn const_data_query(db: &dyn DefDatabase, konst: ConstId) -> Arc<ConstData> {
185 let loc = konst.lookup(db); 204 let loc = konst.lookup(db);
186 let item_tree = db.item_tree(loc.id.file_id); 205 let item_tree = loc.id.item_tree(db);
187 let konst = &item_tree[loc.id.value]; 206 let konst = &item_tree[loc.id.value];
188 207
189 Arc::new(ConstData { 208 Arc::new(ConstData {
@@ -206,7 +225,7 @@ pub struct StaticData {
206impl StaticData { 225impl StaticData {
207 pub(crate) fn static_data_query(db: &dyn DefDatabase, konst: StaticId) -> Arc<StaticData> { 226 pub(crate) fn static_data_query(db: &dyn DefDatabase, konst: StaticId) -> Arc<StaticData> {
208 let node = konst.lookup(db); 227 let node = konst.lookup(db);
209 let item_tree = db.item_tree(node.id.file_id); 228 let item_tree = node.id.item_tree(db);
210 let statik = &item_tree[node.id.value]; 229 let statik = &item_tree[node.id.value];
211 230
212 Arc::new(StaticData { 231 Arc::new(StaticData {
@@ -232,22 +251,23 @@ fn collect_items(
232 return Vec::new(); 251 return Vec::new();
233 } 252 }
234 253
235 let item_tree = db.item_tree(file_id); 254 let item_tree = db.file_item_tree(file_id);
236 let cfg_options = db.crate_graph()[module.krate].cfg_options.clone(); 255 let crate_graph = db.crate_graph();
256 let cfg_options = &crate_graph[module.krate].cfg_options;
237 257
238 let mut items = Vec::new(); 258 let mut items = Vec::new();
239 for item in assoc_items { 259 for item in assoc_items {
260 let attrs = item_tree.attrs(db, module.krate, ModItem::from(item).into());
261 if !attrs.is_cfg_enabled(cfg_options) {
262 continue;
263 }
264
240 match item { 265 match item {
241 AssocItem::Function(id) => { 266 AssocItem::Function(id) => {
242 let item = &item_tree[id]; 267 let item = &item_tree[id];
243 let attrs = item_tree.attrs(db, module.krate, ModItem::from(id).into());
244 if !attrs.is_cfg_enabled(&cfg_options) {
245 continue;
246 }
247 let def = FunctionLoc { container, id: ItemTreeId::new(file_id, id) }.intern(db); 268 let def = FunctionLoc { container, id: ItemTreeId::new(file_id, id) }.intern(db);
248 items.push((item.name.clone(), def.into())); 269 items.push((item.name.clone(), def.into()));
249 } 270 }
250 // FIXME: cfg?
251 AssocItem::Const(id) => { 271 AssocItem::Const(id) => {
252 let item = &item_tree[id]; 272 let item = &item_tree[id];
253 let name = match item.name.clone() { 273 let name = match item.name.clone() {
@@ -272,7 +292,7 @@ fn collect_items(
272 if let Ok(res) = res { 292 if let Ok(res) = res {
273 if let Some((mark, mac)) = res.value { 293 if let Some((mark, mac)) = res.value {
274 let src: InFile<ast::MacroItems> = expander.to_source(mac); 294 let src: InFile<ast::MacroItems> = expander.to_source(mac);
275 let item_tree = db.item_tree(src.file_id); 295 let item_tree = db.file_item_tree(src.file_id);
276 let iter = 296 let iter =
277 item_tree.top_level_items().iter().filter_map(ModItem::as_assoc_item); 297 item_tree.top_level_items().iter().filter_map(ModItem::as_assoc_item);
278 items.extend(collect_items( 298 items.extend(collect_items(