diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/hir/src/diagnostics.rs | 2 | ||||
-rw-r--r-- | crates/hir_def/src/diagnostics.rs | 25 | ||||
-rw-r--r-- | crates/hir_def/src/item_tree.rs | 18 | ||||
-rw-r--r-- | crates/hir_def/src/nameres.rs | 15 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 13 | ||||
-rw-r--r-- | crates/ide/src/diagnostics.rs | 16 |
6 files changed, 86 insertions, 3 deletions
diff --git a/crates/hir/src/diagnostics.rs b/crates/hir/src/diagnostics.rs index da2b40849..d476ca3b9 100644 --- a/crates/hir/src/diagnostics.rs +++ b/crates/hir/src/diagnostics.rs | |||
@@ -1,5 +1,5 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | pub use hir_def::diagnostics::UnresolvedModule; | 2 | pub use hir_def::diagnostics::{UnconfiguredCode, UnresolvedModule}; |
3 | pub use hir_expand::diagnostics::{Diagnostic, DiagnosticSink, DiagnosticSinkBuilder}; | 3 | pub use hir_expand::diagnostics::{Diagnostic, DiagnosticSink, DiagnosticSinkBuilder}; |
4 | pub use hir_ty::diagnostics::{ | 4 | pub use hir_ty::diagnostics::{ |
5 | IncorrectCase, MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkInTailExpr, | 5 | IncorrectCase, MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkInTailExpr, |
diff --git a/crates/hir_def/src/diagnostics.rs b/crates/hir_def/src/diagnostics.rs index fcfbbbad3..53cf1aca1 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)] | ||
94 | pub struct UnconfiguredCode { | ||
95 | pub file: HirFileId, | ||
96 | pub node: SyntaxNodePtr, | ||
97 | } | ||
98 | |||
99 | impl Diagnostic for UnconfiguredCode { | ||
100 | fn code(&self) -> DiagnosticCode { | ||
101 | DiagnosticCode("unconfigured-code") | ||
102 | } | ||
103 | fn message(&self) -> String { | ||
104 | // FIXME: say *why* it is configured out | ||
105 | "configured out".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..8bb3a659f 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(UnconfiguredCode { 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 | ||
1328 | fn is_macro_rules(path: &ModPath) -> bool { | 1341 | fn is_macro_rules(path: &ModPath) -> bool { |
diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs index c92c1c066..394365bc8 100644 --- a/crates/ide/src/diagnostics.rs +++ b/crates/ide/src/diagnostics.rs | |||
@@ -10,7 +10,10 @@ mod field_shorthand; | |||
10 | use std::cell::RefCell; | 10 | use std::cell::RefCell; |
11 | 11 | ||
12 | use base_db::SourceDatabase; | 12 | use base_db::SourceDatabase; |
13 | use hir::{diagnostics::DiagnosticSinkBuilder, Semantics}; | 13 | use hir::{ |
14 | diagnostics::{Diagnostic as _, DiagnosticSinkBuilder}, | ||
15 | Semantics, | ||
16 | }; | ||
14 | use ide_db::RootDatabase; | 17 | use ide_db::RootDatabase; |
15 | use itertools::Itertools; | 18 | use itertools::Itertools; |
16 | use rustc_hash::FxHashSet; | 19 | use rustc_hash::FxHashSet; |
@@ -46,6 +49,10 @@ impl Diagnostic { | |||
46 | fn with_fix(self, fix: Option<Fix>) -> Self { | 49 | fn with_fix(self, fix: Option<Fix>) -> Self { |
47 | Self { fix, ..self } | 50 | Self { fix, ..self } |
48 | } | 51 | } |
52 | |||
53 | fn with_unused(self, unused: bool) -> Self { | ||
54 | Self { unused, ..self } | ||
55 | } | ||
49 | } | 56 | } |
50 | 57 | ||
51 | #[derive(Debug)] | 58 | #[derive(Debug)] |
@@ -115,6 +122,13 @@ pub(crate) fn diagnostics( | |||
115 | .on::<hir::diagnostics::IncorrectCase, _>(|d| { | 122 | .on::<hir::diagnostics::IncorrectCase, _>(|d| { |
116 | res.borrow_mut().push(warning_with_fix(d, &sema)); | 123 | res.borrow_mut().push(warning_with_fix(d, &sema)); |
117 | }) | 124 | }) |
125 | .on::<hir::diagnostics::UnconfiguredCode, _>(|d| { | ||
126 | // Override severity and mark as unused. | ||
127 | res.borrow_mut().push( | ||
128 | Diagnostic::hint(sema.diagnostics_display_range(d).range, d.message()) | ||
129 | .with_unused(true), | ||
130 | ); | ||
131 | }) | ||
118 | // Only collect experimental diagnostics when they're enabled. | 132 | // Only collect experimental diagnostics when they're enabled. |
119 | .filter(|diag| !(diag.is_experimental() && config.disable_experimental)) | 133 | .filter(|diag| !(diag.is_experimental() && config.disable_experimental)) |
120 | .filter(|diag| !config.disabled.contains(diag.code().as_str())); | 134 | .filter(|diag| !config.disabled.contains(diag.code().as_str())); |