aboutsummaryrefslogtreecommitdiff
path: root/crates/hir
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir')
-rw-r--r--crates/hir/src/diagnostics.rs125
-rw-r--r--crates/hir/src/lib.rs27
2 files changed, 27 insertions, 125 deletions
diff --git a/crates/hir/src/diagnostics.rs b/crates/hir/src/diagnostics.rs
index 28580eeb4..f839616ce 100644
--- a/crates/hir/src/diagnostics.rs
+++ b/crates/hir/src/diagnostics.rs
@@ -32,14 +32,19 @@ macro_rules! diagnostics {
32} 32}
33 33
34diagnostics![ 34diagnostics![
35 UnresolvedModule, 35 BreakOutsideOfLoop,
36 InactiveCode,
37 MacroError,
38 MismatchedArgCount,
39 MissingFields,
40 MissingUnsafe,
41 NoSuchField,
42 UnimplementedBuiltinMacro,
36 UnresolvedExternCrate, 43 UnresolvedExternCrate,
37 UnresolvedImport, 44 UnresolvedImport,
38 UnresolvedMacroCall, 45 UnresolvedMacroCall,
46 UnresolvedModule,
39 UnresolvedProcMacro, 47 UnresolvedProcMacro,
40 MacroError,
41 MissingFields,
42 InactiveCode,
43]; 48];
44 49
45#[derive(Debug)] 50#[derive(Debug)]
@@ -88,101 +93,22 @@ pub struct MacroError {
88 93
89#[derive(Debug)] 94#[derive(Debug)]
90pub struct UnimplementedBuiltinMacro { 95pub struct UnimplementedBuiltinMacro {
91 pub file: HirFileId, 96 pub node: InFile<SyntaxNodePtr>,
92 pub node: SyntaxNodePtr,
93}
94
95impl Diagnostic for UnimplementedBuiltinMacro {
96 fn code(&self) -> DiagnosticCode {
97 DiagnosticCode("unimplemented-builtin-macro")
98 }
99
100 fn message(&self) -> String {
101 "unimplemented built-in macro".to_string()
102 }
103
104 fn display_source(&self) -> InFile<SyntaxNodePtr> {
105 InFile::new(self.file, self.node.clone())
106 }
107
108 fn as_any(&self) -> &(dyn Any + Send + 'static) {
109 self
110 }
111} 97}
112 98
113// Diagnostic: no-such-field
114//
115// This diagnostic is triggered if created structure does not have field provided in record.
116#[derive(Debug)] 99#[derive(Debug)]
117pub struct NoSuchField { 100pub struct NoSuchField {
118 pub file: HirFileId, 101 pub field: InFile<AstPtr<ast::RecordExprField>>,
119 pub field: AstPtr<ast::RecordExprField>,
120} 102}
121 103
122impl Diagnostic for NoSuchField {
123 fn code(&self) -> DiagnosticCode {
124 DiagnosticCode("no-such-field")
125 }
126
127 fn message(&self) -> String {
128 "no such field".to_string()
129 }
130
131 fn display_source(&self) -> InFile<SyntaxNodePtr> {
132 InFile::new(self.file, self.field.clone().into())
133 }
134
135 fn as_any(&self) -> &(dyn Any + Send + 'static) {
136 self
137 }
138}
139
140// Diagnostic: break-outside-of-loop
141//
142// This diagnostic is triggered if the `break` keyword is used outside of a loop.
143#[derive(Debug)] 104#[derive(Debug)]
144pub struct BreakOutsideOfLoop { 105pub struct BreakOutsideOfLoop {
145 pub file: HirFileId, 106 pub expr: InFile<AstPtr<ast::Expr>>,
146 pub expr: AstPtr<ast::Expr>,
147} 107}
148 108
149impl Diagnostic for BreakOutsideOfLoop {
150 fn code(&self) -> DiagnosticCode {
151 DiagnosticCode("break-outside-of-loop")
152 }
153 fn message(&self) -> String {
154 "break outside of loop".to_string()
155 }
156 fn display_source(&self) -> InFile<SyntaxNodePtr> {
157 InFile { file_id: self.file, value: self.expr.clone().into() }
158 }
159 fn as_any(&self) -> &(dyn Any + Send + 'static) {
160 self
161 }
162}
163
164// Diagnostic: missing-unsafe
165//
166// This diagnostic is triggered if an operation marked as `unsafe` is used outside of an `unsafe` function or block.
167#[derive(Debug)] 109#[derive(Debug)]
168pub struct MissingUnsafe { 110pub struct MissingUnsafe {
169 pub file: HirFileId, 111 pub expr: InFile<AstPtr<ast::Expr>>,
170 pub expr: AstPtr<ast::Expr>,
171}
172
173impl Diagnostic for MissingUnsafe {
174 fn code(&self) -> DiagnosticCode {
175 DiagnosticCode("missing-unsafe")
176 }
177 fn message(&self) -> String {
178 format!("This operation is unsafe and requires an unsafe function or block")
179 }
180 fn display_source(&self) -> InFile<SyntaxNodePtr> {
181 InFile { file_id: self.file, value: self.expr.clone().into() }
182 }
183 fn as_any(&self) -> &(dyn Any + Send + 'static) {
184 self
185 }
186} 112}
187 113
188#[derive(Debug)] 114#[derive(Debug)]
@@ -218,36 +144,13 @@ impl Diagnostic for ReplaceFilterMapNextWithFindMap {
218 } 144 }
219} 145}
220 146
221// Diagnostic: mismatched-arg-count
222//
223// This diagnostic is triggered if a function is invoked with an incorrect amount of arguments.
224#[derive(Debug)] 147#[derive(Debug)]
225pub struct MismatchedArgCount { 148pub struct MismatchedArgCount {
226 pub file: HirFileId, 149 pub call_expr: InFile<AstPtr<ast::Expr>>,
227 pub call_expr: AstPtr<ast::Expr>,
228 pub expected: usize, 150 pub expected: usize,
229 pub found: usize, 151 pub found: usize,
230} 152}
231 153
232impl Diagnostic for MismatchedArgCount {
233 fn code(&self) -> DiagnosticCode {
234 DiagnosticCode("mismatched-arg-count")
235 }
236 fn message(&self) -> String {
237 let s = if self.expected == 1 { "" } else { "s" };
238 format!("Expected {} argument{}, found {}", self.expected, s, self.found)
239 }
240 fn display_source(&self) -> InFile<SyntaxNodePtr> {
241 InFile { file_id: self.file, value: self.call_expr.clone().into() }
242 }
243 fn as_any(&self) -> &(dyn Any + Send + 'static) {
244 self
245 }
246 fn is_experimental(&self) -> bool {
247 true
248 }
249}
250
251#[derive(Debug)] 154#[derive(Debug)]
252pub struct RemoveThisSemicolon { 155pub struct RemoveThisSemicolon {
253 pub file: HirFileId, 156 pub file: HirFileId,
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index d891d0ec1..c1af5f097 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -606,8 +606,12 @@ impl Module {
606 let node = ast.to_node(db.upcast()); 606 let node = ast.to_node(db.upcast());
607 // Must have a name, otherwise we wouldn't emit it. 607 // Must have a name, otherwise we wouldn't emit it.
608 let name = node.name().expect("unimplemented builtin macro with no name"); 608 let name = node.name().expect("unimplemented builtin macro with no name");
609 let ptr = SyntaxNodePtr::from(AstPtr::new(&name)); 609 acc.push(
610 sink.push(UnimplementedBuiltinMacro { file: ast.file_id, node: ptr }); 610 UnimplementedBuiltinMacro {
611 node: ast.with_value(SyntaxNodePtr::from(AstPtr::new(&name))),
612 }
613 .into(),
614 );
611 } 615 }
612 } 616 }
613 } 617 }
@@ -1073,22 +1077,20 @@ impl Function {
1073 match d { 1077 match d {
1074 hir_ty::InferenceDiagnostic::NoSuchField { expr } => { 1078 hir_ty::InferenceDiagnostic::NoSuchField { expr } => {
1075 let field = source_map.field_syntax(*expr); 1079 let field = source_map.field_syntax(*expr);
1076 sink.push(NoSuchField { file: field.file_id, field: field.value }) 1080 acc.push(NoSuchField { field }.into())
1077 } 1081 }
1078 hir_ty::InferenceDiagnostic::BreakOutsideOfLoop { expr } => { 1082 hir_ty::InferenceDiagnostic::BreakOutsideOfLoop { expr } => {
1079 let ptr = source_map 1083 let expr = source_map
1080 .expr_syntax(*expr) 1084 .expr_syntax(*expr)
1081 .expect("break outside of loop in synthetic syntax"); 1085 .expect("break outside of loop in synthetic syntax");
1082 sink.push(BreakOutsideOfLoop { file: ptr.file_id, expr: ptr.value }) 1086 acc.push(BreakOutsideOfLoop { expr }.into())
1083 } 1087 }
1084 } 1088 }
1085 } 1089 }
1086 1090
1087 for expr in hir_ty::diagnostics::missing_unsafe(db, self.id.into()) { 1091 for expr in hir_ty::diagnostics::missing_unsafe(db, self.id.into()) {
1088 match source_map.expr_syntax(expr) { 1092 match source_map.expr_syntax(expr) {
1089 Ok(in_file) => { 1093 Ok(expr) => acc.push(MissingUnsafe { expr }.into()),
1090 sink.push(MissingUnsafe { file: in_file.file_id, expr: in_file.value })
1091 }
1092 Err(SyntheticSyntax) => { 1094 Err(SyntheticSyntax) => {
1093 // FIXME: Here and eslwhere in this file, the `expr` was 1095 // FIXME: Here and eslwhere in this file, the `expr` was
1094 // desugared, report or assert that this doesn't happen. 1096 // desugared, report or assert that this doesn't happen.
@@ -1174,12 +1176,9 @@ impl Function {
1174 } 1176 }
1175 BodyValidationDiagnostic::MismatchedArgCount { call_expr, expected, found } => { 1177 BodyValidationDiagnostic::MismatchedArgCount { call_expr, expected, found } => {
1176 match source_map.expr_syntax(call_expr) { 1178 match source_map.expr_syntax(call_expr) {
1177 Ok(source_ptr) => sink.push(MismatchedArgCount { 1179 Ok(source_ptr) => acc.push(
1178 file: source_ptr.file_id, 1180 MismatchedArgCount { call_expr: source_ptr, expected, found }.into(),
1179 call_expr: source_ptr.value, 1181 ),
1180 expected,
1181 found,
1182 }),
1183 Err(SyntheticSyntax) => (), 1182 Err(SyntheticSyntax) => (),
1184 } 1183 }
1185 } 1184 }