diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-05-25 21:33:21 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2021-05-25 21:33:21 +0100 |
commit | 5587d0a3e3599063a8993e9a44a7628abbabae8b (patch) | |
tree | 77d3d645249361e8a4730be803338caccddeefa0 /crates/hir/src/diagnostics.rs | |
parent | e23083f39813f9559c041b295d23534cd2125913 (diff) | |
parent | 5c9f31d4c28478b4373e6cf5ec155745c840ee3f (diff) |
Merge #8973
8973: internal: move diagnostics to hir r=matklad a=matklad
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/hir/src/diagnostics.rs')
-rw-r--r-- | crates/hir/src/diagnostics.rs | 232 |
1 files changed, 223 insertions, 9 deletions
diff --git a/crates/hir/src/diagnostics.rs b/crates/hir/src/diagnostics.rs index 414c3f35e..22ec7c6ac 100644 --- a/crates/hir/src/diagnostics.rs +++ b/crates/hir/src/diagnostics.rs | |||
@@ -3,13 +3,227 @@ | |||
3 | //! | 3 | //! |
4 | //! This probably isn't the best way to do this -- ideally, diagnistics should | 4 | //! This probably isn't the best way to do this -- ideally, diagnistics should |
5 | //! be expressed in terms of hir types themselves. | 5 | //! be expressed in terms of hir types themselves. |
6 | pub use hir_def::diagnostics::{ | 6 | use std::any::Any; |
7 | InactiveCode, UnresolvedMacroCall, UnresolvedModule, UnresolvedProcMacro, | 7 | |
8 | }; | 8 | use cfg::{CfgExpr, CfgOptions, DnfExpr}; |
9 | pub use hir_expand::diagnostics::{ | 9 | use hir_def::path::ModPath; |
10 | Diagnostic, DiagnosticCode, DiagnosticSink, DiagnosticSinkBuilder, | 10 | use hir_expand::{HirFileId, InFile}; |
11 | }; | 11 | use stdx::format_to; |
12 | pub use hir_ty::diagnostics::{ | 12 | use syntax::{ast, AstPtr, SyntaxNodePtr, TextRange}; |
13 | IncorrectCase, MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkOrSomeInTailExpr, | 13 | |
14 | NoSuchField, RemoveThisSemicolon, ReplaceFilterMapNextWithFindMap, | 14 | pub use hir_ty::{ |
15 | diagnostics::{ | ||
16 | IncorrectCase, MismatchedArgCount, MissingFields, MissingMatchArms, | ||
17 | MissingOkOrSomeInTailExpr, NoSuchField, RemoveThisSemicolon, | ||
18 | ReplaceFilterMapNextWithFindMap, | ||
19 | }, | ||
20 | diagnostics_sink::{Diagnostic, DiagnosticCode, DiagnosticSink, DiagnosticSinkBuilder}, | ||
15 | }; | 21 | }; |
22 | |||
23 | // Diagnostic: unresolved-module | ||
24 | // | ||
25 | // This diagnostic is triggered if rust-analyzer is unable to discover referred module. | ||
26 | #[derive(Debug)] | ||
27 | pub struct UnresolvedModule { | ||
28 | pub file: HirFileId, | ||
29 | pub decl: AstPtr<ast::Module>, | ||
30 | pub candidate: String, | ||
31 | } | ||
32 | |||
33 | impl Diagnostic for UnresolvedModule { | ||
34 | fn code(&self) -> DiagnosticCode { | ||
35 | DiagnosticCode("unresolved-module") | ||
36 | } | ||
37 | fn message(&self) -> String { | ||
38 | "unresolved module".to_string() | ||
39 | } | ||
40 | fn display_source(&self) -> InFile<SyntaxNodePtr> { | ||
41 | InFile::new(self.file, self.decl.clone().into()) | ||
42 | } | ||
43 | fn as_any(&self) -> &(dyn Any + Send + 'static) { | ||
44 | self | ||
45 | } | ||
46 | } | ||
47 | |||
48 | // Diagnostic: unresolved-extern-crate | ||
49 | // | ||
50 | // This diagnostic is triggered if rust-analyzer is unable to discover referred extern crate. | ||
51 | #[derive(Debug)] | ||
52 | pub struct UnresolvedExternCrate { | ||
53 | pub file: HirFileId, | ||
54 | pub item: AstPtr<ast::ExternCrate>, | ||
55 | } | ||
56 | |||
57 | impl Diagnostic for UnresolvedExternCrate { | ||
58 | fn code(&self) -> DiagnosticCode { | ||
59 | DiagnosticCode("unresolved-extern-crate") | ||
60 | } | ||
61 | fn message(&self) -> String { | ||
62 | "unresolved extern crate".to_string() | ||
63 | } | ||
64 | fn display_source(&self) -> InFile<SyntaxNodePtr> { | ||
65 | InFile::new(self.file, self.item.clone().into()) | ||
66 | } | ||
67 | fn as_any(&self) -> &(dyn Any + Send + 'static) { | ||
68 | self | ||
69 | } | ||
70 | } | ||
71 | |||
72 | #[derive(Debug)] | ||
73 | pub struct UnresolvedImport { | ||
74 | pub file: HirFileId, | ||
75 | pub node: AstPtr<ast::UseTree>, | ||
76 | } | ||
77 | |||
78 | impl Diagnostic for UnresolvedImport { | ||
79 | fn code(&self) -> DiagnosticCode { | ||
80 | DiagnosticCode("unresolved-import") | ||
81 | } | ||
82 | fn message(&self) -> String { | ||
83 | "unresolved import".to_string() | ||
84 | } | ||
85 | fn display_source(&self) -> InFile<SyntaxNodePtr> { | ||
86 | InFile::new(self.file, self.node.clone().into()) | ||
87 | } | ||
88 | fn as_any(&self) -> &(dyn Any + Send + 'static) { | ||
89 | self | ||
90 | } | ||
91 | fn is_experimental(&self) -> bool { | ||
92 | // This currently results in false positives in the following cases: | ||
93 | // - `cfg_if!`-generated code in libstd (we don't load the sysroot correctly) | ||
94 | // - `core::arch` (we don't handle `#[path = "../<path>"]` correctly) | ||
95 | // - proc macros and/or proc macro generated code | ||
96 | true | ||
97 | } | ||
98 | } | ||
99 | |||
100 | // Diagnostic: unresolved-macro-call | ||
101 | // | ||
102 | // This diagnostic is triggered if rust-analyzer is unable to resolve the path to a | ||
103 | // macro in a macro invocation. | ||
104 | #[derive(Debug, Clone, Eq, PartialEq)] | ||
105 | pub struct UnresolvedMacroCall { | ||
106 | pub file: HirFileId, | ||
107 | pub node: AstPtr<ast::MacroCall>, | ||
108 | pub path: ModPath, | ||
109 | } | ||
110 | |||
111 | impl Diagnostic for UnresolvedMacroCall { | ||
112 | fn code(&self) -> DiagnosticCode { | ||
113 | DiagnosticCode("unresolved-macro-call") | ||
114 | } | ||
115 | fn message(&self) -> String { | ||
116 | format!("unresolved macro `{}!`", self.path) | ||
117 | } | ||
118 | fn display_source(&self) -> InFile<SyntaxNodePtr> { | ||
119 | InFile::new(self.file, self.node.clone().into()) | ||
120 | } | ||
121 | fn as_any(&self) -> &(dyn Any + Send + 'static) { | ||
122 | self | ||
123 | } | ||
124 | fn is_experimental(&self) -> bool { | ||
125 | true | ||
126 | } | ||
127 | } | ||
128 | |||
129 | // Diagnostic: inactive-code | ||
130 | // | ||
131 | // This diagnostic is shown for code with inactive `#[cfg]` attributes. | ||
132 | #[derive(Debug, Clone, Eq, PartialEq)] | ||
133 | pub struct InactiveCode { | ||
134 | pub file: HirFileId, | ||
135 | pub node: SyntaxNodePtr, | ||
136 | pub cfg: CfgExpr, | ||
137 | pub opts: CfgOptions, | ||
138 | } | ||
139 | |||
140 | impl Diagnostic for InactiveCode { | ||
141 | fn code(&self) -> DiagnosticCode { | ||
142 | DiagnosticCode("inactive-code") | ||
143 | } | ||
144 | fn message(&self) -> String { | ||
145 | let inactive = DnfExpr::new(self.cfg.clone()).why_inactive(&self.opts); | ||
146 | let mut buf = "code is inactive due to #[cfg] directives".to_string(); | ||
147 | |||
148 | if let Some(inactive) = inactive { | ||
149 | format_to!(buf, ": {}", inactive); | ||
150 | } | ||
151 | |||
152 | buf | ||
153 | } | ||
154 | fn display_source(&self) -> InFile<SyntaxNodePtr> { | ||
155 | InFile::new(self.file, self.node.clone()) | ||
156 | } | ||
157 | fn as_any(&self) -> &(dyn Any + Send + 'static) { | ||
158 | self | ||
159 | } | ||
160 | } | ||
161 | |||
162 | // Diagnostic: unresolved-proc-macro | ||
163 | // | ||
164 | // This diagnostic is shown when a procedural macro can not be found. This usually means that | ||
165 | // procedural macro support is simply disabled (and hence is only a weak hint instead of an error), | ||
166 | // but can also indicate project setup problems. | ||
167 | // | ||
168 | // If you are seeing a lot of "proc macro not expanded" warnings, you can add this option to the | ||
169 | // `rust-analyzer.diagnostics.disabled` list to prevent them from showing. Alternatively you can | ||
170 | // enable support for procedural macros (see `rust-analyzer.procMacro.enable`). | ||
171 | #[derive(Debug, Clone, Eq, PartialEq)] | ||
172 | pub struct UnresolvedProcMacro { | ||
173 | pub file: HirFileId, | ||
174 | pub node: SyntaxNodePtr, | ||
175 | /// If the diagnostic can be pinpointed more accurately than via `node`, this is the `TextRange` | ||
176 | /// to use instead. | ||
177 | pub precise_location: Option<TextRange>, | ||
178 | pub macro_name: Option<String>, | ||
179 | } | ||
180 | |||
181 | impl Diagnostic for UnresolvedProcMacro { | ||
182 | fn code(&self) -> DiagnosticCode { | ||
183 | DiagnosticCode("unresolved-proc-macro") | ||
184 | } | ||
185 | |||
186 | fn message(&self) -> String { | ||
187 | match &self.macro_name { | ||
188 | Some(name) => format!("proc macro `{}` not expanded", name), | ||
189 | None => "proc macro not expanded".to_string(), | ||
190 | } | ||
191 | } | ||
192 | |||
193 | fn display_source(&self) -> InFile<SyntaxNodePtr> { | ||
194 | InFile::new(self.file, self.node.clone()) | ||
195 | } | ||
196 | |||
197 | fn as_any(&self) -> &(dyn Any + Send + 'static) { | ||
198 | self | ||
199 | } | ||
200 | } | ||
201 | |||
202 | // Diagnostic: macro-error | ||
203 | // | ||
204 | // This diagnostic is shown for macro expansion errors. | ||
205 | #[derive(Debug, Clone, Eq, PartialEq)] | ||
206 | pub struct MacroError { | ||
207 | pub file: HirFileId, | ||
208 | pub node: SyntaxNodePtr, | ||
209 | pub message: String, | ||
210 | } | ||
211 | |||
212 | impl Diagnostic for MacroError { | ||
213 | fn code(&self) -> DiagnosticCode { | ||
214 | DiagnosticCode("macro-error") | ||
215 | } | ||
216 | fn message(&self) -> String { | ||
217 | self.message.clone() | ||
218 | } | ||
219 | fn display_source(&self) -> InFile<SyntaxNodePtr> { | ||
220 | InFile::new(self.file, self.node.clone()) | ||
221 | } | ||
222 | fn as_any(&self) -> &(dyn Any + Send + 'static) { | ||
223 | self | ||
224 | } | ||
225 | fn is_experimental(&self) -> bool { | ||
226 | // Newly added and not very well-tested, might contain false positives. | ||
227 | true | ||
228 | } | ||
229 | } | ||