diff options
-rw-r--r-- | crates/ra_hir_def/src/adt.rs | 1 | ||||
-rw-r--r-- | crates/ra_hir_def/src/data.rs | 31 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/expr.rs | 3 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests.rs | 30 |
4 files changed, 58 insertions, 7 deletions
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs index de07fc952..7fc4cd76e 100644 --- a/crates/ra_hir_def/src/adt.rs +++ b/crates/ra_hir_def/src/adt.rs | |||
@@ -54,6 +54,7 @@ pub struct StructFieldData { | |||
54 | impl StructData { | 54 | impl StructData { |
55 | pub(crate) fn struct_data_query(db: &dyn DefDatabase, id: StructId) -> Arc<StructData> { | 55 | pub(crate) fn struct_data_query(db: &dyn DefDatabase, id: StructId) -> Arc<StructData> { |
56 | let src = id.lookup(db).source(db); | 56 | let src = id.lookup(db).source(db); |
57 | |||
57 | let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); | 58 | let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); |
58 | let variant_data = VariantData::new(db, src.map(|s| s.kind())); | 59 | let variant_data = VariantData::new(db, src.map(|s| s.kind())); |
59 | let variant_data = Arc::new(variant_data); | 60 | let variant_data = Arc::new(variant_data); |
diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index 04bd4a305..606ec48b0 100644 --- a/crates/ra_hir_def/src/data.rs +++ b/crates/ra_hir_def/src/data.rs | |||
@@ -3,15 +3,18 @@ | |||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use hir_expand::{ | 5 | use hir_expand::{ |
6 | hygiene::Hygiene, | ||
6 | name::{name, AsName, Name}, | 7 | name::{name, AsName, Name}, |
7 | AstId, InFile, | 8 | AstId, InFile, |
8 | }; | 9 | }; |
10 | use ra_cfg::CfgOptions; | ||
9 | use ra_prof::profile; | 11 | use ra_prof::profile; |
10 | use ra_syntax::ast::{ | 12 | use ra_syntax::ast::{ |
11 | self, AstNode, ImplItem, ModuleItemOwner, NameOwner, TypeAscriptionOwner, VisibilityOwner, | 13 | self, AstNode, ImplItem, ModuleItemOwner, NameOwner, TypeAscriptionOwner, VisibilityOwner, |
12 | }; | 14 | }; |
13 | 15 | ||
14 | use crate::{ | 16 | use crate::{ |
17 | attr::Attrs, | ||
15 | db::DefDatabase, | 18 | db::DefDatabase, |
16 | path::{path, GenericArgs, Path}, | 19 | path::{path, GenericArgs, Path}, |
17 | src::HasSource, | 20 | src::HasSource, |
@@ -26,6 +29,7 @@ pub struct FunctionData { | |||
26 | pub name: Name, | 29 | pub name: Name, |
27 | pub params: Vec<TypeRef>, | 30 | pub params: Vec<TypeRef>, |
28 | pub ret_type: TypeRef, | 31 | pub ret_type: TypeRef, |
32 | pub attrs: Attrs, | ||
29 | /// True if the first param is `self`. This is relevant to decide whether this | 33 | /// True if the first param is `self`. This is relevant to decide whether this |
30 | /// can be called as a method. | 34 | /// can be called as a method. |
31 | pub has_self_param: bool, | 35 | pub has_self_param: bool, |
@@ -63,6 +67,8 @@ impl FunctionData { | |||
63 | params.push(type_ref); | 67 | params.push(type_ref); |
64 | } | 68 | } |
65 | } | 69 | } |
70 | let attrs = Attrs::new(&src.value, &Hygiene::new(db.upcast(), src.file_id)); | ||
71 | |||
66 | let ret_type = if let Some(type_ref) = src.value.ret_type().and_then(|rt| rt.type_ref()) { | 72 | let ret_type = if let Some(type_ref) = src.value.ret_type().and_then(|rt| rt.type_ref()) { |
67 | TypeRef::from_ast(type_ref) | 73 | TypeRef::from_ast(type_ref) |
68 | } else { | 74 | } else { |
@@ -81,7 +87,7 @@ impl FunctionData { | |||
81 | let visibility = | 87 | let visibility = |
82 | RawVisibility::from_ast_with_default(db, vis_default, src.map(|s| s.visibility())); | 88 | RawVisibility::from_ast_with_default(db, vis_default, src.map(|s| s.visibility())); |
83 | 89 | ||
84 | let sig = FunctionData { name, params, ret_type, has_self_param, visibility }; | 90 | let sig = FunctionData { name, params, ret_type, has_self_param, visibility, attrs }; |
85 | Arc::new(sig) | 91 | Arc::new(sig) |
86 | } | 92 | } |
87 | } | 93 | } |
@@ -211,6 +217,7 @@ impl ImplData { | |||
211 | let module_id = impl_loc.container.module(db); | 217 | let module_id = impl_loc.container.module(db); |
212 | 218 | ||
213 | let mut items = Vec::new(); | 219 | let mut items = Vec::new(); |
220 | |||
214 | if let Some(item_list) = src.value.item_list() { | 221 | if let Some(item_list) = src.value.item_list() { |
215 | items.extend(collect_impl_items(db, item_list.impl_items(), src.file_id, id)); | 222 | items.extend(collect_impl_items(db, item_list.impl_items(), src.file_id, id)); |
216 | items.extend(collect_impl_items_in_macros( | 223 | items.extend(collect_impl_items_in_macros( |
@@ -311,6 +318,10 @@ fn collect_impl_items_in_macro( | |||
311 | } | 318 | } |
312 | } | 319 | } |
313 | 320 | ||
321 | fn is_cfg_enabled(cfg_options: &CfgOptions, attrs: &Attrs) -> bool { | ||
322 | attrs.by_key("cfg").tt_values().all(|tt| cfg_options.is_cfg_enabled(tt) != Some(false)) | ||
323 | } | ||
324 | |||
314 | fn collect_impl_items( | 325 | fn collect_impl_items( |
315 | db: &dyn DefDatabase, | 326 | db: &dyn DefDatabase, |
316 | impl_items: impl Iterator<Item = ImplItem>, | 327 | impl_items: impl Iterator<Item = ImplItem>, |
@@ -318,16 +329,26 @@ fn collect_impl_items( | |||
318 | id: ImplId, | 329 | id: ImplId, |
319 | ) -> Vec<AssocItemId> { | 330 | ) -> Vec<AssocItemId> { |
320 | let items = db.ast_id_map(file_id); | 331 | let items = db.ast_id_map(file_id); |
332 | let crate_graph = db.crate_graph(); | ||
333 | let module_id = id.lookup(db).container.module(db); | ||
321 | 334 | ||
322 | impl_items | 335 | impl_items |
323 | .map(|item_node| match item_node { | 336 | .filter_map(|item_node| match item_node { |
324 | ast::ImplItem::FnDef(it) => { | 337 | ast::ImplItem::FnDef(it) => { |
325 | let def = FunctionLoc { | 338 | let def = FunctionLoc { |
326 | container: AssocContainerId::ImplId(id), | 339 | container: AssocContainerId::ImplId(id), |
327 | ast_id: AstId::new(file_id, items.ast_id(&it)), | 340 | ast_id: AstId::new(file_id, items.ast_id(&it)), |
328 | } | 341 | } |
329 | .intern(db); | 342 | .intern(db); |
330 | def.into() | 343 | |
344 | if !is_cfg_enabled( | ||
345 | &crate_graph[module_id.krate].cfg_options, | ||
346 | &db.function_data(def).attrs, | ||
347 | ) { | ||
348 | None | ||
349 | } else { | ||
350 | Some(def.into()) | ||
351 | } | ||
331 | } | 352 | } |
332 | ast::ImplItem::ConstDef(it) => { | 353 | ast::ImplItem::ConstDef(it) => { |
333 | let def = ConstLoc { | 354 | let def = ConstLoc { |
@@ -335,7 +356,7 @@ fn collect_impl_items( | |||
335 | ast_id: AstId::new(file_id, items.ast_id(&it)), | 356 | ast_id: AstId::new(file_id, items.ast_id(&it)), |
336 | } | 357 | } |
337 | .intern(db); | 358 | .intern(db); |
338 | def.into() | 359 | Some(def.into()) |
339 | } | 360 | } |
340 | ast::ImplItem::TypeAliasDef(it) => { | 361 | ast::ImplItem::TypeAliasDef(it) => { |
341 | let def = TypeAliasLoc { | 362 | let def = TypeAliasLoc { |
@@ -343,7 +364,7 @@ fn collect_impl_items( | |||
343 | ast_id: AstId::new(file_id, items.ast_id(&it)), | 364 | ast_id: AstId::new(file_id, items.ast_id(&it)), |
344 | } | 365 | } |
345 | .intern(db); | 366 | .intern(db); |
346 | def.into() | 367 | Some(def.into()) |
347 | } | 368 | } |
348 | }) | 369 | }) |
349 | .collect() | 370 | .collect() |
diff --git a/crates/ra_hir_ty/src/expr.rs b/crates/ra_hir_ty/src/expr.rs index b4592fbf5..e45e9ea14 100644 --- a/crates/ra_hir_ty/src/expr.rs +++ b/crates/ra_hir_ty/src/expr.rs | |||
@@ -4,8 +4,7 @@ use std::sync::Arc; | |||
4 | 4 | ||
5 | use hir_def::{path::path, resolver::HasResolver, AdtId, FunctionId}; | 5 | use hir_def::{path::path, resolver::HasResolver, AdtId, FunctionId}; |
6 | use hir_expand::diagnostics::DiagnosticSink; | 6 | use hir_expand::diagnostics::DiagnosticSink; |
7 | use ra_syntax::ast; | 7 | use ra_syntax::{ast, AstPtr}; |
8 | use ra_syntax::AstPtr; | ||
9 | use rustc_hash::FxHashSet; | 8 | use rustc_hash::FxHashSet; |
10 | 9 | ||
11 | use crate::{ | 10 | use crate::{ |
diff --git a/crates/ra_hir_ty/src/tests.rs b/crates/ra_hir_ty/src/tests.rs index e4a103d1b..608408d88 100644 --- a/crates/ra_hir_ty/src/tests.rs +++ b/crates/ra_hir_ty/src/tests.rs | |||
@@ -319,3 +319,33 @@ fn no_such_field_diagnostics() { | |||
319 | "### | 319 | "### |
320 | ); | 320 | ); |
321 | } | 321 | } |
322 | |||
323 | #[test] | ||
324 | fn no_such_field_with_feature_flag_diagnostics() { | ||
325 | let diagnostics = TestDB::with_files( | ||
326 | r#" | ||
327 | //- /lib.rs crate:foo cfg:feature=foo | ||
328 | struct MyStruct { | ||
329 | my_val: usize, | ||
330 | #[cfg(feature = "foo")] | ||
331 | bar: bool, | ||
332 | } | ||
333 | |||
334 | impl MyStruct { | ||
335 | #[cfg(feature = "foo")] | ||
336 | pub(crate) fn new(my_val: usize, bar: bool) -> Self { | ||
337 | Self { my_val, bar } | ||
338 | } | ||
339 | |||
340 | #[cfg(not(feature = "foo"))] | ||
341 | pub(crate) fn new(my_val: usize, _bar: bool) -> Self { | ||
342 | Self { my_val } | ||
343 | } | ||
344 | } | ||
345 | "#, | ||
346 | ) | ||
347 | .diagnostics() | ||
348 | .0; | ||
349 | |||
350 | assert_snapshot!(diagnostics, @r###""###); | ||
351 | } | ||