From 0b95bed83fc8db897f54b350168567f14527e8de Mon Sep 17 00:00:00 2001 From: Paul Daniel Faria Date: Sat, 23 May 2020 17:49:53 -0400 Subject: Add unsafe diagnostics and unsafe highlighting --- crates/ra_hir_ty/src/diagnostics.rs | 58 +++++++++++++++++++++++++++++++++++++ crates/ra_hir_ty/src/expr.rs | 24 ++++++++++++++- 2 files changed, 81 insertions(+), 1 deletion(-) (limited to 'crates/ra_hir_ty') 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 { ast::Expr::cast(node).unwrap() } } + +#[derive(Debug)] +pub struct MissingUnsafe { + pub file: HirFileId, + pub fn_def: AstPtr, + pub fn_name: Name, +} + +impl Diagnostic for MissingUnsafe { + fn message(&self) -> String { + format!("Missing unsafe marker on fn `{}`", self.fn_name) + } + fn source(&self) -> InFile { + InFile { file_id: self.file, value: self.fn_def.clone().into() } + } + fn as_any(&self) -> &(dyn Any + Send + 'static) { + self + } +} + +impl AstDiagnostic for MissingUnsafe { + type AST = ast::FnDef; + + fn ast(&self, db: &impl AstDatabase) -> Self::AST { + let root = db.parse_or_expand(self.source().file_id).unwrap(); + let node = self.source().value.to_node(&root); + ast::FnDef::cast(node).unwrap() + } +} + +#[derive(Debug)] +pub struct UnnecessaryUnsafe { + pub file: HirFileId, + pub fn_def: AstPtr, + pub fn_name: Name, +} + +impl Diagnostic for UnnecessaryUnsafe { + fn message(&self) -> String { + format!("Unnecessary unsafe marker on fn `{}`", self.fn_name) + } + fn source(&self) -> InFile { + InFile { file_id: self.file, value: self.fn_def.clone().into() } + } + fn as_any(&self) -> &(dyn Any + Send + 'static) { + self + } +} + +impl AstDiagnostic for UnnecessaryUnsafe { + type AST = ast::FnDef; + + fn ast(&self, db: &impl AstDatabase) -> Self::AST { + let root = db.parse_or_expand(self.source().file_id).unwrap(); + let node = self.source().value.to_node(&root); + ast::FnDef::cast(node).unwrap() + } +} 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 @@ use std::sync::Arc; -use hir_def::{path::path, resolver::HasResolver, AdtId, FunctionId}; +use hir_def::{path::path, resolver::HasResolver, AdtId, DefWithBodyId, FunctionId}; use hir_expand::diagnostics::DiagnosticSink; use ra_syntax::{ast, AstPtr}; use rustc_hash::FxHashSet; @@ -312,3 +312,25 @@ pub fn record_pattern_missing_fields( } Some((variant_def, missed_fields, exhaustive)) } + +pub fn unsafe_expressions( + db: &dyn HirDatabase, + infer: &InferenceResult, + def: DefWithBodyId, +) -> Vec { + let mut unsafe_expr_ids = vec![]; + let body = db.body(def); + for (id, expr) in body.exprs.iter() { + if let Expr::Call { callee, .. } = expr { + if infer + .method_resolution(*callee) + .map(|func| db.function_data(func).is_unsafe) + .unwrap_or(false) + { + unsafe_expr_ids.push(id); + } + } + } + + unsafe_expr_ids +} -- cgit v1.2.3