diff options
author | Paul Daniel Faria <[email protected]> | 2020-05-28 03:21:20 +0100 |
---|---|---|
committer | Paul Daniel Faria <[email protected]> | 2020-06-27 15:10:26 +0100 |
commit | 7f2219dc76d6cddc46eadb2b2dd674795e0efce8 (patch) | |
tree | 7c2dbb2ea490684de4f49d28fb1c3928f1194728 /crates/ra_hir_ty | |
parent | 9ce44be2ab7e9a99eece1c2e254f15ad1c6d73c5 (diff) |
Track expr parents during lowering, use parent map when checking if unsafe exprs are within unsafe blocks
Diffstat (limited to 'crates/ra_hir_ty')
-rw-r--r-- | crates/ra_hir_ty/src/expr.rs | 22 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests.rs | 2 |
2 files changed, 12 insertions, 12 deletions
diff --git a/crates/ra_hir_ty/src/expr.rs b/crates/ra_hir_ty/src/expr.rs index 5f332aadb..3942aada5 100644 --- a/crates/ra_hir_ty/src/expr.rs +++ b/crates/ra_hir_ty/src/expr.rs | |||
@@ -333,15 +333,12 @@ pub fn unsafe_expressions( | |||
333 | def: DefWithBodyId, | 333 | def: DefWithBodyId, |
334 | ) -> Vec<UnsafeExpr> { | 334 | ) -> Vec<UnsafeExpr> { |
335 | let mut unsafe_exprs = vec![]; | 335 | let mut unsafe_exprs = vec![]; |
336 | let mut unsafe_block_scopes = vec![]; | 336 | let mut unsafe_block_exprs = FxHashSet::default(); |
337 | let body = db.body(def); | 337 | let body = db.body(def); |
338 | let expr_scopes = db.expr_scopes(def); | ||
339 | for (id, expr) in body.exprs.iter() { | 338 | for (id, expr) in body.exprs.iter() { |
340 | match expr { | 339 | match expr { |
341 | Expr::Unsafe { body } => { | 340 | Expr::Unsafe { .. } => { |
342 | if let Some(scope) = expr_scopes.scope_for(*body) { | 341 | unsafe_block_exprs.insert(id); |
343 | unsafe_block_scopes.push(scope); | ||
344 | } | ||
345 | } | 342 | } |
346 | Expr::Call { callee, .. } => { | 343 | Expr::Call { callee, .. } => { |
347 | let ty = &infer[*callee]; | 344 | let ty = &infer[*callee]; |
@@ -374,12 +371,13 @@ pub fn unsafe_expressions( | |||
374 | } | 371 | } |
375 | 372 | ||
376 | 'unsafe_exprs: for unsafe_expr in &mut unsafe_exprs { | 373 | 'unsafe_exprs: for unsafe_expr in &mut unsafe_exprs { |
377 | let scope = expr_scopes.scope_for(unsafe_expr.expr); | 374 | let mut child = unsafe_expr.expr; |
378 | for scope in expr_scopes.scope_chain(scope) { | 375 | while let Some(parent) = body.parent_map.get(&child) { |
379 | if unsafe_block_scopes.contains(&scope) { | 376 | if unsafe_block_exprs.contains(parent) { |
380 | unsafe_expr.inside_unsafe_block = true; | 377 | unsafe_expr.inside_unsafe_block = true; |
381 | continue 'unsafe_exprs; | 378 | continue 'unsafe_exprs; |
382 | } | 379 | } |
380 | child = *parent; | ||
383 | } | 381 | } |
384 | } | 382 | } |
385 | 383 | ||
@@ -417,8 +415,10 @@ impl<'a, 'b> UnsafeValidator<'a, 'b> { | |||
417 | 415 | ||
418 | let (_, body_source) = db.body_with_source_map(def); | 416 | let (_, body_source) = db.body_with_source_map(def); |
419 | for unsafe_expr in unsafe_expressions { | 417 | for unsafe_expr in unsafe_expressions { |
420 | if let Ok(in_file) = body_source.as_ref().expr_syntax(unsafe_expr.expr) { | 418 | if !unsafe_expr.inside_unsafe_block { |
421 | self.sink.push(MissingUnsafe { file: in_file.file_id, expr: in_file.value }) | 419 | if let Ok(in_file) = body_source.as_ref().expr_syntax(unsafe_expr.expr) { |
420 | self.sink.push(MissingUnsafe { file: in_file.file_id, expr: in_file.value }) | ||
421 | } | ||
422 | } | 422 | } |
423 | } | 423 | } |
424 | } | 424 | } |
diff --git a/crates/ra_hir_ty/src/tests.rs b/crates/ra_hir_ty/src/tests.rs index 26b3aeb50..496cb428b 100644 --- a/crates/ra_hir_ty/src/tests.rs +++ b/crates/ra_hir_ty/src/tests.rs | |||
@@ -638,7 +638,7 @@ fn nothing_to_see_move_along() { | |||
638 | .diagnostics() | 638 | .diagnostics() |
639 | .0; | 639 | .0; |
640 | 640 | ||
641 | assert_snapshot!(diagnostics, @""); | 641 | assert_snapshot!(diagnostics, @r#""*x": This operation is unsafe and requires an unsafe function or block"#); |
642 | } | 642 | } |
643 | 643 | ||
644 | #[test] | 644 | #[test] |