aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/expr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/expr.rs')
-rw-r--r--crates/ra_hir_ty/src/expr.rs71
1 files changed, 1 insertions, 70 deletions
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 @@
2 2
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use hir_def::{path::path, resolver::HasResolver, AdtId, DefWithBodyId, FunctionId}; 5use hir_def::{path::path, resolver::HasResolver, AdtId, 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;
@@ -10,7 +10,6 @@ use rustc_hash::FxHashSet;
10use crate::{ 10use crate::{
11 db::HirDatabase, 11 db::HirDatabase,
12 diagnostics::{MissingFields, MissingMatchArms, MissingOkInTailExpr, MissingPatFields}, 12 diagnostics::{MissingFields, MissingMatchArms, MissingOkInTailExpr, MissingPatFields},
13 lower::CallableDef,
14 utils::variant_data, 13 utils::variant_data,
15 ApplicationTy, InferenceResult, Ty, TypeCtor, 14 ApplicationTy, InferenceResult, Ty, TypeCtor,
16 _match::{is_useful, MatchCheckCtx, Matrix, PatStack, Usefulness}, 15 _match::{is_useful, MatchCheckCtx, Matrix, PatStack, Usefulness},
@@ -313,71 +312,3 @@ pub fn record_pattern_missing_fields(
313 } 312 }
314 Some((variant_def, missed_fields, exhaustive)) 313 Some((variant_def, missed_fields, exhaustive))
315} 314}
316
317pub struct UnsafeExpr {
318 pub expr: ExprId,
319 pub inside_unsafe_block: bool,
320}
321
322impl UnsafeExpr {
323 fn new(expr: ExprId) -> Self {
324 Self { expr, inside_unsafe_block: false }
325 }
326}
327
328pub fn unsafe_expressions(
329 db: &dyn HirDatabase,
330 infer: &InferenceResult,
331 def: DefWithBodyId,
332) -> Vec<UnsafeExpr> {
333 let mut unsafe_exprs = vec![];
334 let mut unsafe_block_exprs = FxHashSet::default();
335 let body = db.body(def);
336 for (id, expr) in body.exprs.iter() {
337 match expr {
338 Expr::Unsafe { .. } => {
339 unsafe_block_exprs.insert(id);
340 }
341 Expr::Call { callee, .. } => {
342 let ty = &infer[*callee];
343 if let &Ty::Apply(ApplicationTy {
344 ctor: TypeCtor::FnDef(CallableDef::FunctionId(func)),
345 ..
346 }) = ty
347 {
348 if db.function_data(func).is_unsafe {
349 unsafe_exprs.push(UnsafeExpr::new(id));
350 }
351 }
352 }
353 Expr::MethodCall { .. } => {
354 if infer
355 .method_resolution(id)
356 .map(|func| db.function_data(func).is_unsafe)
357 .unwrap_or(false)
358 {
359 unsafe_exprs.push(UnsafeExpr::new(id));
360 }
361 }
362 Expr::UnaryOp { expr, op: UnaryOp::Deref } => {
363 if let Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(..), .. }) = &infer[*expr] {
364 unsafe_exprs.push(UnsafeExpr::new(id));
365 }
366 }
367 _ => {}
368 }
369 }
370
371 'unsafe_exprs: for unsafe_expr in &mut unsafe_exprs {
372 let mut child = unsafe_expr.expr;
373 while let Some(parent) = body.parent_map.get(&child) {
374 if unsafe_block_exprs.contains(parent) {
375 unsafe_expr.inside_unsafe_block = true;
376 continue 'unsafe_exprs;
377 }
378 child = *parent;
379 }
380 }
381
382 unsafe_exprs
383}