From 2608a6fd3a024206d4776cc391e46ef28c018434 Mon Sep 17 00:00:00 2001 From: Paul Daniel Faria Date: Fri, 29 May 2020 08:55:47 -0400 Subject: unsafe: Clean up, improve tracking, add debug_assert Move unsafe_expressions to unsafe_validation.rs, replace vec tracking of child exprs with inline macro, add debug assert to ensure tracked children match walked children exactly --- crates/ra_hir_ty/src/expr.rs | 71 +---------------------------- crates/ra_hir_ty/src/unsafe_validation.rs | 75 ++++++++++++++++++++++++++++++- 2 files changed, 74 insertions(+), 72 deletions(-) (limited to 'crates/ra_hir_ty') diff --git a/crates/ra_hir_ty/src/expr.rs b/crates/ra_hir_ty/src/expr.rs index 99eed949f..7db928dde 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, DefWithBodyId, FunctionId}; +use hir_def::{path::path, resolver::HasResolver, AdtId, FunctionId}; use hir_expand::diagnostics::DiagnosticSink; use ra_syntax::{ast, AstPtr}; use rustc_hash::FxHashSet; @@ -10,7 +10,6 @@ use rustc_hash::FxHashSet; use crate::{ db::HirDatabase, diagnostics::{MissingFields, MissingMatchArms, MissingOkInTailExpr, MissingPatFields}, - lower::CallableDef, utils::variant_data, ApplicationTy, InferenceResult, Ty, TypeCtor, _match::{is_useful, MatchCheckCtx, Matrix, PatStack, Usefulness}, @@ -313,71 +312,3 @@ pub fn record_pattern_missing_fields( } Some((variant_def, missed_fields, exhaustive)) } - -pub struct UnsafeExpr { - pub expr: ExprId, - pub inside_unsafe_block: bool, -} - -impl UnsafeExpr { - fn new(expr: ExprId) -> Self { - Self { expr, inside_unsafe_block: false } - } -} - -pub fn unsafe_expressions( - db: &dyn HirDatabase, - infer: &InferenceResult, - def: DefWithBodyId, -) -> Vec { - let mut unsafe_exprs = vec![]; - let mut unsafe_block_exprs = FxHashSet::default(); - let body = db.body(def); - for (id, expr) in body.exprs.iter() { - match expr { - Expr::Unsafe { .. } => { - unsafe_block_exprs.insert(id); - } - Expr::Call { callee, .. } => { - let ty = &infer[*callee]; - if let &Ty::Apply(ApplicationTy { - ctor: TypeCtor::FnDef(CallableDef::FunctionId(func)), - .. - }) = ty - { - if db.function_data(func).is_unsafe { - unsafe_exprs.push(UnsafeExpr::new(id)); - } - } - } - Expr::MethodCall { .. } => { - if infer - .method_resolution(id) - .map(|func| db.function_data(func).is_unsafe) - .unwrap_or(false) - { - unsafe_exprs.push(UnsafeExpr::new(id)); - } - } - Expr::UnaryOp { expr, op: UnaryOp::Deref } => { - if let Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(..), .. }) = &infer[*expr] { - unsafe_exprs.push(UnsafeExpr::new(id)); - } - } - _ => {} - } - } - - 'unsafe_exprs: for unsafe_expr in &mut unsafe_exprs { - let mut child = unsafe_expr.expr; - while let Some(parent) = body.parent_map.get(&child) { - if unsafe_block_exprs.contains(parent) { - unsafe_expr.inside_unsafe_block = true; - continue 'unsafe_exprs; - } - child = *parent; - } - } - - unsafe_exprs -} diff --git a/crates/ra_hir_ty/src/unsafe_validation.rs b/crates/ra_hir_ty/src/unsafe_validation.rs index 55dbe23fa..430182803 100644 --- a/crates/ra_hir_ty/src/unsafe_validation.rs +++ b/crates/ra_hir_ty/src/unsafe_validation.rs @@ -3,13 +3,16 @@ use std::sync::Arc; -use hir_def::FunctionId; +use hir_def::{DefWithBodyId, FunctionId}; use hir_expand::diagnostics::DiagnosticSink; use crate::{ - db::HirDatabase, diagnostics::MissingUnsafe, expr::unsafe_expressions, InferenceResult, + db::HirDatabase, diagnostics::MissingUnsafe, lower::CallableDef, ApplicationTy, + InferenceResult, Ty, TypeCtor, }; +use rustc_hash::FxHashSet; + pub use hir_def::{ body::{ scope::{ExprScopes, ScopeEntry, ScopeId}, @@ -61,3 +64,71 @@ impl<'a, 'b> UnsafeValidator<'a, 'b> { } } } + +pub struct UnsafeExpr { + pub expr: ExprId, + pub inside_unsafe_block: bool, +} + +impl UnsafeExpr { + fn new(expr: ExprId) -> Self { + Self { expr, inside_unsafe_block: false } + } +} + +pub fn unsafe_expressions( + db: &dyn HirDatabase, + infer: &InferenceResult, + def: DefWithBodyId, +) -> Vec { + let mut unsafe_exprs = vec![]; + let mut unsafe_block_exprs = FxHashSet::default(); + let body = db.body(def); + for (id, expr) in body.exprs.iter() { + match expr { + Expr::Unsafe { .. } => { + unsafe_block_exprs.insert(id); + } + Expr::Call { callee, .. } => { + let ty = &infer[*callee]; + if let &Ty::Apply(ApplicationTy { + ctor: TypeCtor::FnDef(CallableDef::FunctionId(func)), + .. + }) = ty + { + if db.function_data(func).is_unsafe { + unsafe_exprs.push(UnsafeExpr::new(id)); + } + } + } + Expr::MethodCall { .. } => { + if infer + .method_resolution(id) + .map(|func| db.function_data(func).is_unsafe) + .unwrap_or(false) + { + unsafe_exprs.push(UnsafeExpr::new(id)); + } + } + Expr::UnaryOp { expr, op: UnaryOp::Deref } => { + if let Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(..), .. }) = &infer[*expr] { + unsafe_exprs.push(UnsafeExpr::new(id)); + } + } + _ => {} + } + } + + 'unsafe_exprs: for unsafe_expr in &mut unsafe_exprs { + let mut child = unsafe_expr.expr; + while let Some(parent) = body.parent_map.get(child) { + if unsafe_block_exprs.contains(parent) { + unsafe_expr.inside_unsafe_block = true; + continue 'unsafe_exprs; + } + child = *parent; + } + } + + unsafe_exprs +} -- cgit v1.2.3