aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src
diff options
context:
space:
mode:
authorPaul Daniel Faria <[email protected]>2020-05-23 22:49:53 +0100
committerPaul Daniel Faria <[email protected]>2020-06-27 15:08:14 +0100
commit0b95bed83fc8db897f54b350168567f14527e8de (patch)
tree94fc33b8e7f160ae2b45e38b32a70856006c93a2 /crates/ra_hir_ty/src
parent9d1e2c4d9dc6c7f5fbaee5d9907d135f618d7ac6 (diff)
Add unsafe diagnostics and unsafe highlighting
Diffstat (limited to 'crates/ra_hir_ty/src')
-rw-r--r--crates/ra_hir_ty/src/diagnostics.rs58
-rw-r--r--crates/ra_hir_ty/src/expr.rs24
2 files changed, 81 insertions, 1 deletions
diff --git a/crates/ra_hir_ty/src/diagnostics.rs b/crates/ra_hir_ty/src/diagnostics.rs
index ebd9cb08f..3469cc680 100644
--- a/crates/ra_hir_ty/src/diagnostics.rs
+++ b/crates/ra_hir_ty/src/diagnostics.rs
@@ -169,3 +169,61 @@ impl AstDiagnostic for BreakOutsideOfLoop {
169 ast::Expr::cast(node).unwrap() 169 ast::Expr::cast(node).unwrap()
170 } 170 }
171} 171}
172
173#[derive(Debug)]
174pub struct MissingUnsafe {
175 pub file: HirFileId,
176 pub fn_def: AstPtr<ast::FnDef>,
177 pub fn_name: Name,
178}
179
180impl Diagnostic for MissingUnsafe {
181 fn message(&self) -> String {
182 format!("Missing unsafe marker on fn `{}`", self.fn_name)
183 }
184 fn source(&self) -> InFile<SyntaxNodePtr> {
185 InFile { file_id: self.file, value: self.fn_def.clone().into() }
186 }
187 fn as_any(&self) -> &(dyn Any + Send + 'static) {
188 self
189 }
190}
191
192impl AstDiagnostic for MissingUnsafe {
193 type AST = ast::FnDef;
194
195 fn ast(&self, db: &impl AstDatabase) -> Self::AST {
196 let root = db.parse_or_expand(self.source().file_id).unwrap();
197 let node = self.source().value.to_node(&root);
198 ast::FnDef::cast(node).unwrap()
199 }
200}
201
202#[derive(Debug)]
203pub struct UnnecessaryUnsafe {
204 pub file: HirFileId,
205 pub fn_def: AstPtr<ast::FnDef>,
206 pub fn_name: Name,
207}
208
209impl Diagnostic for UnnecessaryUnsafe {
210 fn message(&self) -> String {
211 format!("Unnecessary unsafe marker on fn `{}`", self.fn_name)
212 }
213 fn source(&self) -> InFile<SyntaxNodePtr> {
214 InFile { file_id: self.file, value: self.fn_def.clone().into() }
215 }
216 fn as_any(&self) -> &(dyn Any + Send + 'static) {
217 self
218 }
219}
220
221impl AstDiagnostic for UnnecessaryUnsafe {
222 type AST = ast::FnDef;
223
224 fn ast(&self, db: &impl AstDatabase) -> Self::AST {
225 let root = db.parse_or_expand(self.source().file_id).unwrap();
226 let node = self.source().value.to_node(&root);
227 ast::FnDef::cast(node).unwrap()
228 }
229}
diff --git a/crates/ra_hir_ty/src/expr.rs b/crates/ra_hir_ty/src/expr.rs
index 7db928dde..795f1762c 100644
--- a/crates/ra_hir_ty/src/expr.rs
+++ b/crates/ra_hir_ty/src/expr.rs
@@ -2,7 +2,7 @@
2 2
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use hir_def::{path::path, resolver::HasResolver, AdtId, FunctionId}; 5use hir_def::{path::path, resolver::HasResolver, AdtId, DefWithBodyId, FunctionId};
6use hir_expand::diagnostics::DiagnosticSink; 6use hir_expand::diagnostics::DiagnosticSink;
7use ra_syntax::{ast, AstPtr}; 7use ra_syntax::{ast, AstPtr};
8use rustc_hash::FxHashSet; 8use rustc_hash::FxHashSet;
@@ -312,3 +312,25 @@ pub fn record_pattern_missing_fields(
312 } 312 }
313 Some((variant_def, missed_fields, exhaustive)) 313 Some((variant_def, missed_fields, exhaustive))
314} 314}
315
316pub fn unsafe_expressions(
317 db: &dyn HirDatabase,
318 infer: &InferenceResult,
319 def: DefWithBodyId,
320) -> Vec<ExprId> {
321 let mut unsafe_expr_ids = vec![];
322 let body = db.body(def);
323 for (id, expr) in body.exprs.iter() {
324 if let Expr::Call { callee, .. } = expr {
325 if infer
326 .method_resolution(*callee)
327 .map(|func| db.function_data(func).is_unsafe)
328 .unwrap_or(false)
329 {
330 unsafe_expr_ids.push(id);
331 }
332 }
333 }
334
335 unsafe_expr_ids
336}