aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-10-20 17:35:05 +0100
committerGitHub <[email protected]>2020-10-20 17:35:05 +0100
commit20d369a826e8f333cba1988325480a49a730f00e (patch)
tree266845de2212273c0967ed6455bdc0c7b485f225 /crates/hir_def
parent5dd99aa016bd9f7b8bcbc0eb47998723b675bb26 (diff)
parent74ac83a5acc9f53db69577fc32a4a6e3985d2ef9 (diff)
Merge #6299
6299: Diagnose items that are #[cfg]d out r=jonas-schievink a=jonas-schievink This emits a hint-level diagnostic with `Unnecessary` tag to "gray out" any items whose `#[cfg]` attributes remove the item before name resolution. Co-authored-by: Jonas Schievink <[email protected]>
Diffstat (limited to 'crates/hir_def')
-rw-r--r--crates/hir_def/src/diagnostics.rs25
-rw-r--r--crates/hir_def/src/item_tree.rs18
-rw-r--r--crates/hir_def/src/nameres.rs15
-rw-r--r--crates/hir_def/src/nameres/collector.rs13
4 files changed, 70 insertions, 1 deletions
diff --git a/crates/hir_def/src/diagnostics.rs b/crates/hir_def/src/diagnostics.rs
index fcfbbbad3..c9c08b01f 100644
--- a/crates/hir_def/src/diagnostics.rs
+++ b/crates/hir_def/src/diagnostics.rs
@@ -86,3 +86,28 @@ impl Diagnostic for UnresolvedImport {
86 true 86 true
87 } 87 }
88} 88}
89
90// Diagnostic: unconfigured-code
91//
92// This diagnostic is shown for code with inactive `#[cfg]` attributes.
93#[derive(Debug)]
94pub struct InactiveCode {
95 pub file: HirFileId,
96 pub node: SyntaxNodePtr,
97}
98
99impl Diagnostic for InactiveCode {
100 fn code(&self) -> DiagnosticCode {
101 DiagnosticCode("inactive-code")
102 }
103 fn message(&self) -> String {
104 // FIXME: say *why* it is configured out
105 "code is inactive due to #[cfg] directives".to_string()
106 }
107 fn display_source(&self) -> InFile<SyntaxNodePtr> {
108 InFile::new(self.file, self.node.clone())
109 }
110 fn as_any(&self) -> &(dyn Any + Send + 'static) {
111 self
112 }
113}
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs
index 8a1121bbd..7eb388bae 100644
--- a/crates/hir_def/src/item_tree.rs
+++ b/crates/hir_def/src/item_tree.rs
@@ -672,6 +672,24 @@ impl ModItem {
672 pub fn downcast<N: ItemTreeNode>(self) -> Option<FileItemTreeId<N>> { 672 pub fn downcast<N: ItemTreeNode>(self) -> Option<FileItemTreeId<N>> {
673 N::id_from_mod_item(self) 673 N::id_from_mod_item(self)
674 } 674 }
675
676 pub fn ast_id(&self, tree: &ItemTree) -> FileAstId<ast::Item> {
677 match self {
678 ModItem::Import(it) => tree[it.index].ast_id().upcast(),
679 ModItem::ExternCrate(it) => tree[it.index].ast_id().upcast(),
680 ModItem::Function(it) => tree[it.index].ast_id().upcast(),
681 ModItem::Struct(it) => tree[it.index].ast_id().upcast(),
682 ModItem::Union(it) => tree[it.index].ast_id().upcast(),
683 ModItem::Enum(it) => tree[it.index].ast_id().upcast(),
684 ModItem::Const(it) => tree[it.index].ast_id().upcast(),
685 ModItem::Static(it) => tree[it.index].ast_id().upcast(),
686 ModItem::Trait(it) => tree[it.index].ast_id().upcast(),
687 ModItem::Impl(it) => tree[it.index].ast_id().upcast(),
688 ModItem::TypeAlias(it) => tree[it.index].ast_id().upcast(),
689 ModItem::Mod(it) => tree[it.index].ast_id().upcast(),
690 ModItem::MacroCall(it) => tree[it.index].ast_id().upcast(),
691 }
692 }
675} 693}
676 694
677#[derive(Debug, Copy, Clone, Eq, PartialEq)] 695#[derive(Debug, Copy, Clone, Eq, PartialEq)]
diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs
index 3d04f81c6..01a28aeeb 100644
--- a/crates/hir_def/src/nameres.rs
+++ b/crates/hir_def/src/nameres.rs
@@ -286,7 +286,7 @@ mod diagnostics {
286 use hir_expand::diagnostics::DiagnosticSink; 286 use hir_expand::diagnostics::DiagnosticSink;
287 use hir_expand::hygiene::Hygiene; 287 use hir_expand::hygiene::Hygiene;
288 use hir_expand::InFile; 288 use hir_expand::InFile;
289 use syntax::{ast, AstPtr}; 289 use syntax::{ast, AstPtr, SyntaxNodePtr};
290 290
291 use crate::path::ModPath; 291 use crate::path::ModPath;
292 use crate::{db::DefDatabase, diagnostics::*, nameres::LocalModuleId, AstId}; 292 use crate::{db::DefDatabase, diagnostics::*, nameres::LocalModuleId, AstId};
@@ -298,6 +298,8 @@ mod diagnostics {
298 UnresolvedExternCrate { ast: AstId<ast::ExternCrate> }, 298 UnresolvedExternCrate { ast: AstId<ast::ExternCrate> },
299 299
300 UnresolvedImport { ast: AstId<ast::Use>, index: usize }, 300 UnresolvedImport { ast: AstId<ast::Use>, index: usize },
301
302 UnconfiguredCode { ast: InFile<SyntaxNodePtr> },
301 } 303 }
302 304
303 #[derive(Debug, PartialEq, Eq)] 305 #[derive(Debug, PartialEq, Eq)]
@@ -336,6 +338,13 @@ mod diagnostics {
336 Self { in_module: container, kind: DiagnosticKind::UnresolvedImport { ast, index } } 338 Self { in_module: container, kind: DiagnosticKind::UnresolvedImport { ast, index } }
337 } 339 }
338 340
341 pub(super) fn unconfigured_code(
342 container: LocalModuleId,
343 ast: InFile<SyntaxNodePtr>,
344 ) -> Self {
345 Self { in_module: container, kind: DiagnosticKind::UnconfiguredCode { ast } }
346 }
347
339 pub(super) fn add_to( 348 pub(super) fn add_to(
340 &self, 349 &self,
341 db: &dyn DefDatabase, 350 db: &dyn DefDatabase,
@@ -385,6 +394,10 @@ mod diagnostics {
385 sink.push(UnresolvedImport { file: ast.file_id, node: AstPtr::new(&tree) }); 394 sink.push(UnresolvedImport { file: ast.file_id, node: AstPtr::new(&tree) });
386 } 395 }
387 } 396 }
397
398 DiagnosticKind::UnconfiguredCode { ast } => {
399 sink.push(InactiveCode { file: ast.file_id, node: ast.value.clone() });
400 }
388 } 401 }
389 } 402 }
390 } 403 }
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index c8cd04264..bff8edb62 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -913,6 +913,7 @@ impl ModCollector<'_, '_> {
913 for &item in items { 913 for &item in items {
914 let attrs = self.item_tree.attrs(item.into()); 914 let attrs = self.item_tree.attrs(item.into());
915 if !self.is_cfg_enabled(attrs) { 915 if !self.is_cfg_enabled(attrs) {
916 self.emit_unconfigured_diagnostic(item);
916 continue; 917 continue;
917 } 918 }
918 let module = 919 let module =
@@ -1323,6 +1324,18 @@ impl ModCollector<'_, '_> {
1323 fn is_cfg_enabled(&self, attrs: &Attrs) -> bool { 1324 fn is_cfg_enabled(&self, attrs: &Attrs) -> bool {
1324 attrs.is_cfg_enabled(self.def_collector.cfg_options) 1325 attrs.is_cfg_enabled(self.def_collector.cfg_options)
1325 } 1326 }
1327
1328 fn emit_unconfigured_diagnostic(&mut self, item: ModItem) {
1329 let ast_id = item.ast_id(self.item_tree);
1330 let id_map = self.def_collector.db.ast_id_map(self.file_id);
1331 let syntax_ptr = id_map.get(ast_id).syntax_node_ptr();
1332
1333 let ast_node = InFile::new(self.file_id, syntax_ptr);
1334 self.def_collector
1335 .def_map
1336 .diagnostics
1337 .push(DefDiagnostic::unconfigured_code(self.module_id, ast_node));
1338 }
1326} 1339}
1327 1340
1328fn is_macro_rules(path: &ModPath) -> bool { 1341fn is_macro_rules(path: &ModPath) -> bool {