diff options
-rw-r--r-- | crates/ra_hir/src/attr.rs | 19 | ||||
-rw-r--r-- | crates/ra_hir/src/impl_block.rs | 30 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/collector.rs | 5 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/raw.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 45 |
5 files changed, 90 insertions, 13 deletions
diff --git a/crates/ra_hir/src/attr.rs b/crates/ra_hir/src/attr.rs index 19be6de32..84c36b8da 100644 --- a/crates/ra_hir/src/attr.rs +++ b/crates/ra_hir/src/attr.rs | |||
@@ -1,11 +1,14 @@ | |||
1 | use std::sync::Arc; | ||
2 | |||
1 | use mbe::ast_to_token_tree; | 3 | use mbe::ast_to_token_tree; |
4 | use ra_cfg::CfgOptions; | ||
2 | use ra_syntax::{ | 5 | use ra_syntax::{ |
3 | ast::{self, AstNode}, | 6 | ast::{self, AstNode, AttrsOwner}, |
4 | SmolStr, | 7 | SmolStr, |
5 | }; | 8 | }; |
6 | use tt::Subtree; | 9 | use tt::Subtree; |
7 | 10 | ||
8 | use crate::{db::AstDatabase, path::Path, Source}; | 11 | use crate::{db::AstDatabase, path::Path, HirFileId, Source}; |
9 | 12 | ||
10 | #[derive(Debug, Clone, PartialEq, Eq)] | 13 | #[derive(Debug, Clone, PartialEq, Eq)] |
11 | pub(crate) struct Attr { | 14 | pub(crate) struct Attr { |
@@ -40,6 +43,14 @@ impl Attr { | |||
40 | Some(Attr { path, input }) | 43 | Some(Attr { path, input }) |
41 | } | 44 | } |
42 | 45 | ||
46 | pub(crate) fn from_attrs_owner( | ||
47 | file_id: HirFileId, | ||
48 | owner: &impl AttrsOwner, | ||
49 | db: &impl AstDatabase, | ||
50 | ) -> Arc<[Attr]> { | ||
51 | owner.attrs().flat_map(|ast| Attr::from_src(Source { file_id, ast }, db)).collect() | ||
52 | } | ||
53 | |||
43 | pub(crate) fn is_simple_atom(&self, name: &str) -> bool { | 54 | pub(crate) fn is_simple_atom(&self, name: &str) -> bool { |
44 | // FIXME: Avoid cloning | 55 | // FIXME: Avoid cloning |
45 | self.path.as_ident().map_or(false, |s| s.to_string() == name) | 56 | self.path.as_ident().map_or(false, |s| s.to_string() == name) |
@@ -55,4 +66,8 @@ impl Attr { | |||
55 | None | 66 | None |
56 | } | 67 | } |
57 | } | 68 | } |
69 | |||
70 | pub(crate) fn is_cfg_enabled(&self, cfg_options: &CfgOptions) -> Option<bool> { | ||
71 | cfg_options.is_cfg_enabled(self.as_cfg()?) | ||
72 | } | ||
58 | } | 73 | } |
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index 8cf74ddc7..7877c3171 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs | |||
@@ -4,12 +4,14 @@ use rustc_hash::FxHashMap; | |||
4 | use std::sync::Arc; | 4 | use std::sync::Arc; |
5 | 5 | ||
6 | use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; | 6 | use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; |
7 | use ra_cfg::CfgOptions; | ||
7 | use ra_syntax::{ | 8 | use ra_syntax::{ |
8 | ast::{self, AstNode}, | 9 | ast::{self, AstNode}, |
9 | AstPtr, | 10 | AstPtr, |
10 | }; | 11 | }; |
11 | 12 | ||
12 | use crate::{ | 13 | use crate::{ |
14 | attr::Attr, | ||
13 | code_model::{Module, ModuleSource}, | 15 | code_model::{Module, ModuleSource}, |
14 | db::{AstDatabase, DefDatabase, HirDatabase}, | 16 | db::{AstDatabase, DefDatabase, HirDatabase}, |
15 | generics::HasGenericParams, | 17 | generics::HasGenericParams, |
@@ -176,6 +178,7 @@ pub struct ModuleImplBlocks { | |||
176 | impl ModuleImplBlocks { | 178 | impl ModuleImplBlocks { |
177 | fn collect( | 179 | fn collect( |
178 | db: &(impl DefDatabase + AstDatabase), | 180 | db: &(impl DefDatabase + AstDatabase), |
181 | cfg_options: &CfgOptions, | ||
179 | module: Module, | 182 | module: Module, |
180 | source_map: &mut ImplSourceMap, | 183 | source_map: &mut ImplSourceMap, |
181 | ) -> Self { | 184 | ) -> Self { |
@@ -188,11 +191,11 @@ impl ModuleImplBlocks { | |||
188 | let src = m.module.definition_source(db); | 191 | let src = m.module.definition_source(db); |
189 | match &src.ast { | 192 | match &src.ast { |
190 | ModuleSource::SourceFile(node) => { | 193 | ModuleSource::SourceFile(node) => { |
191 | m.collect_from_item_owner(db, source_map, node, src.file_id) | 194 | m.collect_from_item_owner(db, cfg_options, source_map, node, src.file_id) |
192 | } | 195 | } |
193 | ModuleSource::Module(node) => { | 196 | ModuleSource::Module(node) => { |
194 | let item_list = node.item_list().expect("inline module should have item list"); | 197 | let item_list = node.item_list().expect("inline module should have item list"); |
195 | m.collect_from_item_owner(db, source_map, &item_list, src.file_id) | 198 | m.collect_from_item_owner(db, cfg_options, source_map, &item_list, src.file_id) |
196 | } | 199 | } |
197 | }; | 200 | }; |
198 | m | 201 | m |
@@ -201,6 +204,7 @@ impl ModuleImplBlocks { | |||
201 | fn collect_from_item_owner( | 204 | fn collect_from_item_owner( |
202 | &mut self, | 205 | &mut self, |
203 | db: &(impl DefDatabase + AstDatabase), | 206 | db: &(impl DefDatabase + AstDatabase), |
207 | cfg_options: &CfgOptions, | ||
204 | source_map: &mut ImplSourceMap, | 208 | source_map: &mut ImplSourceMap, |
205 | owner: &dyn ast::ModuleItemOwner, | 209 | owner: &dyn ast::ModuleItemOwner, |
206 | file_id: HirFileId, | 210 | file_id: HirFileId, |
@@ -208,6 +212,11 @@ impl ModuleImplBlocks { | |||
208 | for item in owner.items_with_macros() { | 212 | for item in owner.items_with_macros() { |
209 | match item { | 213 | match item { |
210 | ast::ItemOrMacro::Item(ast::ModuleItem::ImplBlock(impl_block_ast)) => { | 214 | ast::ItemOrMacro::Item(ast::ModuleItem::ImplBlock(impl_block_ast)) => { |
215 | let attrs = Attr::from_attrs_owner(file_id, &impl_block_ast, db); | ||
216 | if attrs.iter().any(|attr| attr.is_cfg_enabled(cfg_options) == Some(false)) { | ||
217 | continue; | ||
218 | } | ||
219 | |||
211 | let impl_block = ImplData::from_ast(db, file_id, self.module, &impl_block_ast); | 220 | let impl_block = ImplData::from_ast(db, file_id, self.module, &impl_block_ast); |
212 | let id = self.impls.alloc(impl_block); | 221 | let id = self.impls.alloc(impl_block); |
213 | for &impl_item in &self.impls[id].items { | 222 | for &impl_item in &self.impls[id].items { |
@@ -218,6 +227,11 @@ impl ModuleImplBlocks { | |||
218 | } | 227 | } |
219 | ast::ItemOrMacro::Item(_) => (), | 228 | ast::ItemOrMacro::Item(_) => (), |
220 | ast::ItemOrMacro::Macro(macro_call) => { | 229 | ast::ItemOrMacro::Macro(macro_call) => { |
230 | let attrs = Attr::from_attrs_owner(file_id, ¯o_call, db); | ||
231 | if attrs.iter().any(|attr| attr.is_cfg_enabled(cfg_options) == Some(false)) { | ||
232 | continue; | ||
233 | } | ||
234 | |||
221 | //FIXME: we should really cut down on the boilerplate required to process a macro | 235 | //FIXME: we should really cut down on the boilerplate required to process a macro |
222 | let ast_id = db.ast_id_map(file_id).ast_id(¯o_call).with_file_id(file_id); | 236 | let ast_id = db.ast_id_map(file_id).ast_id(¯o_call).with_file_id(file_id); |
223 | if let Some(path) = macro_call | 237 | if let Some(path) = macro_call |
@@ -231,7 +245,13 @@ impl ModuleImplBlocks { | |||
231 | if let Some(item_list) = | 245 | if let Some(item_list) = |
232 | db.parse_or_expand(file_id).and_then(ast::MacroItems::cast) | 246 | db.parse_or_expand(file_id).and_then(ast::MacroItems::cast) |
233 | { | 247 | { |
234 | self.collect_from_item_owner(db, source_map, &item_list, file_id) | 248 | self.collect_from_item_owner( |
249 | db, | ||
250 | cfg_options, | ||
251 | source_map, | ||
252 | &item_list, | ||
253 | file_id, | ||
254 | ) | ||
235 | } | 255 | } |
236 | } | 256 | } |
237 | } | 257 | } |
@@ -246,8 +266,10 @@ pub(crate) fn impls_in_module_with_source_map_query( | |||
246 | module: Module, | 266 | module: Module, |
247 | ) -> (Arc<ModuleImplBlocks>, Arc<ImplSourceMap>) { | 267 | ) -> (Arc<ModuleImplBlocks>, Arc<ImplSourceMap>) { |
248 | let mut source_map = ImplSourceMap::default(); | 268 | let mut source_map = ImplSourceMap::default(); |
269 | let crate_graph = db.crate_graph(); | ||
270 | let cfg_options = crate_graph.cfg_options(module.krate.crate_id()); | ||
249 | 271 | ||
250 | let result = ModuleImplBlocks::collect(db, module, &mut source_map); | 272 | let result = ModuleImplBlocks::collect(db, cfg_options, module, &mut source_map); |
251 | (Arc::new(result), Arc::new(source_map)) | 273 | (Arc::new(result), Arc::new(source_map)) |
252 | } | 274 | } |
253 | 275 | ||
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index f0e790e4c..1d79cbd8c 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs | |||
@@ -716,10 +716,7 @@ where | |||
716 | } | 716 | } |
717 | 717 | ||
718 | fn is_cfg_enabled(&self, attrs: &[Attr]) -> bool { | 718 | fn is_cfg_enabled(&self, attrs: &[Attr]) -> bool { |
719 | attrs | 719 | attrs.iter().all(|attr| attr.is_cfg_enabled(&self.def_collector.cfg_options) != Some(false)) |
720 | .iter() | ||
721 | .flat_map(|attr| attr.as_cfg()) | ||
722 | .all(|cfg| self.def_collector.cfg_options.is_cfg_enabled(cfg).unwrap_or(true)) | ||
723 | } | 720 | } |
724 | } | 721 | } |
725 | 722 | ||
diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs index ff079bcf1..f02d4eb7a 100644 --- a/crates/ra_hir/src/nameres/raw.rs +++ b/crates/ra_hir/src/nameres/raw.rs | |||
@@ -411,9 +411,7 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> { | |||
411 | } | 411 | } |
412 | 412 | ||
413 | fn parse_attrs(&self, item: &impl ast::AttrsOwner) -> Arc<[Attr]> { | 413 | fn parse_attrs(&self, item: &impl ast::AttrsOwner) -> Arc<[Attr]> { |
414 | item.attrs() | 414 | Attr::from_attrs_owner(self.file_id, item, self.db) |
415 | .flat_map(|ast| Attr::from_src(Source { ast, file_id: self.file_id }, self.db)) | ||
416 | .collect() | ||
417 | } | 415 | } |
418 | } | 416 | } |
419 | 417 | ||
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 4df39c191..171aead18 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -3,6 +3,7 @@ use std::sync::Arc; | |||
3 | 3 | ||
4 | use insta::assert_snapshot; | 4 | use insta::assert_snapshot; |
5 | 5 | ||
6 | use ra_cfg::CfgOptions; | ||
6 | use ra_db::{salsa::Database, FilePosition, SourceDatabase}; | 7 | use ra_db::{salsa::Database, FilePosition, SourceDatabase}; |
7 | use ra_syntax::{ | 8 | use ra_syntax::{ |
8 | algo, | 9 | algo, |
@@ -24,6 +25,50 @@ mod never_type; | |||
24 | mod coercion; | 25 | mod coercion; |
25 | 26 | ||
26 | #[test] | 27 | #[test] |
28 | fn cfg_impl_block() { | ||
29 | let (mut db, pos) = MockDatabase::with_position( | ||
30 | r#" | ||
31 | //- /main.rs | ||
32 | use foo::S as T; | ||
33 | struct S; | ||
34 | |||
35 | #[cfg(test)] | ||
36 | impl S { | ||
37 | fn foo1(&self) -> i32 { 0 } | ||
38 | } | ||
39 | |||
40 | #[cfg(not(test))] | ||
41 | impl S { | ||
42 | fn foo2(&self) -> i32 { 0 } | ||
43 | } | ||
44 | |||
45 | fn test() { | ||
46 | let t = (S.foo1(), S.foo2(), T.foo3(), T.foo4()); | ||
47 | t<|>; | ||
48 | } | ||
49 | |||
50 | //- /foo.rs | ||
51 | struct S; | ||
52 | |||
53 | #[cfg(not(test))] | ||
54 | impl S { | ||
55 | fn foo3(&self) -> i32 { 0 } | ||
56 | } | ||
57 | |||
58 | #[cfg(test)] | ||
59 | impl S { | ||
60 | fn foo4(&self) -> i32 { 0 } | ||
61 | } | ||
62 | "#, | ||
63 | ); | ||
64 | db.set_crate_graph_from_fixture(crate_graph! { | ||
65 | "main": ("/main.rs", ["foo"], CfgOptions::default().atom("test".into())), | ||
66 | "foo": ("/foo.rs", []), | ||
67 | }); | ||
68 | assert_eq!("(i32, {unknown}, i32, {unknown})", type_at_pos(&db, pos)); | ||
69 | } | ||
70 | |||
71 | #[test] | ||
27 | fn infer_await() { | 72 | fn infer_await() { |
28 | let (mut db, pos) = MockDatabase::with_position( | 73 | let (mut db, pos) = MockDatabase::with_position( |
29 | r#" | 74 | r#" |