diff options
Diffstat (limited to 'crates/ra_hir_ty/src/expr.rs')
-rw-r--r-- | crates/ra_hir_ty/src/expr.rs | 71 |
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 | ||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use hir_def::{path::path, resolver::HasResolver, AdtId, DefWithBodyId, FunctionId}; | 5 | use hir_def::{path::path, resolver::HasResolver, AdtId, FunctionId}; |
6 | use hir_expand::diagnostics::DiagnosticSink; | 6 | use hir_expand::diagnostics::DiagnosticSink; |
7 | use ra_syntax::{ast, AstPtr}; | 7 | use ra_syntax::{ast, AstPtr}; |
8 | use rustc_hash::FxHashSet; | 8 | use rustc_hash::FxHashSet; |
@@ -10,7 +10,6 @@ use rustc_hash::FxHashSet; | |||
10 | use crate::{ | 10 | use 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 | |||
317 | pub struct UnsafeExpr { | ||
318 | pub expr: ExprId, | ||
319 | pub inside_unsafe_block: bool, | ||
320 | } | ||
321 | |||
322 | impl UnsafeExpr { | ||
323 | fn new(expr: ExprId) -> Self { | ||
324 | Self { expr, inside_unsafe_block: false } | ||
325 | } | ||
326 | } | ||
327 | |||
328 | pub 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 | } | ||