aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir_def/src/adt.rs1
-rw-r--r--crates/ra_hir_def/src/data.rs31
-rw-r--r--crates/ra_hir_ty/src/expr.rs3
-rw-r--r--crates/ra_hir_ty/src/tests.rs30
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 {
54impl StructData { 54impl 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 @@
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use hir_expand::{ 5use hir_expand::{
6 hygiene::Hygiene,
6 name::{name, AsName, Name}, 7 name::{name, AsName, Name},
7 AstId, InFile, 8 AstId, InFile,
8}; 9};
10use ra_cfg::CfgOptions;
9use ra_prof::profile; 11use ra_prof::profile;
10use ra_syntax::ast::{ 12use ra_syntax::ast::{
11 self, AstNode, ImplItem, ModuleItemOwner, NameOwner, TypeAscriptionOwner, VisibilityOwner, 13 self, AstNode, ImplItem, ModuleItemOwner, NameOwner, TypeAscriptionOwner, VisibilityOwner,
12}; 14};
13 15
14use crate::{ 16use 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
321fn 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
314fn collect_impl_items( 325fn 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
5use hir_def::{path::path, resolver::HasResolver, AdtId, FunctionId}; 5use hir_def::{path::path, resolver::HasResolver, AdtId, FunctionId};
6use hir_expand::diagnostics::DiagnosticSink; 6use hir_expand::diagnostics::DiagnosticSink;
7use ra_syntax::ast; 7use ra_syntax::{ast, AstPtr};
8use ra_syntax::AstPtr;
9use rustc_hash::FxHashSet; 8use rustc_hash::FxHashSet;
10 9
11use crate::{ 10use 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]
324fn 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}