diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-08-07 12:26:23 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-08-07 12:26:23 +0000 |
| commit | 7a02cc8845ba4e9e3ec414283c60333143831733 (patch) | |
| tree | 614076ad3ce5cf6c35cccc0828c72e11e53fea50 | |
| parent | 911ef38b24efc3e273f7395578c10e05ceb0cd7b (diff) | |
| parent | f089690a21357ca6d396bce98bf598f0954199b5 (diff) | |
| download | rust-7a02cc8845ba4e9e3ec414283c60333143831733.tar.gz rust-7a02cc8845ba4e9e3ec414283c60333143831733.zip | |
Merge #5679
5679: Account for static mut in missing unsafe diagnostic r=jonas-schievink a=Nashenas88 Accessing or modifying a static mut is an unsafe operation. The "missing unsafe" diagnostic now tracks this. Co-authored-by: Paul Daniel Faria <Nashenas88@users.noreply.github.com>
| -rw-r--r-- | crates/ra_hir_ty/src/diagnostics/unsafe_check.rs | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/crates/ra_hir_ty/src/diagnostics/unsafe_check.rs b/crates/ra_hir_ty/src/diagnostics/unsafe_check.rs index 5cc76bdce41..61ffbf5d151 100644 --- a/crates/ra_hir_ty/src/diagnostics/unsafe_check.rs +++ b/crates/ra_hir_ty/src/diagnostics/unsafe_check.rs @@ -6,6 +6,7 @@ use std::sync::Arc; use hir_def::{ body::Body, expr::{Expr, ExprId, UnaryOp}, + resolver::{resolver_for_expr, ResolveValueResult, ValueNs}, DefWithBodyId, }; use hir_expand::diagnostics::DiagnosticSink; @@ -70,7 +71,7 @@ pub fn unsafe_expressions( ) -> Vec<UnsafeExpr> { let mut unsafe_exprs = vec![]; let body = db.body(def); - walk_unsafe(&mut unsafe_exprs, db, infer, &body, body.body_expr, false); + walk_unsafe(&mut unsafe_exprs, db, infer, def, &body, body.body_expr, false); unsafe_exprs } @@ -79,6 +80,7 @@ fn walk_unsafe( unsafe_exprs: &mut Vec<UnsafeExpr>, db: &dyn HirDatabase, infer: &InferenceResult, + def: DefWithBodyId, body: &Body, current: ExprId, inside_unsafe_block: bool, @@ -97,6 +99,15 @@ fn walk_unsafe( } } } + Expr::Path(path) => { + let resolver = resolver_for_expr(db.upcast(), def, current); + let value_or_partial = resolver.resolve_path_in_value_ns(db.upcast(), path.mod_path()); + if let Some(ResolveValueResult::ValueNs(ValueNs::StaticId(id))) = value_or_partial { + if db.static_data(id).mutable { + unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); + } + } + } Expr::MethodCall { .. } => { if infer .method_resolution(current) @@ -112,13 +123,13 @@ fn walk_unsafe( } } Expr::Unsafe { body: child } => { - return walk_unsafe(unsafe_exprs, db, infer, body, *child, true); + return walk_unsafe(unsafe_exprs, db, infer, def, body, *child, true); } _ => {} } expr.walk_child_exprs(|child| { - walk_unsafe(unsafe_exprs, db, infer, body, child, inside_unsafe_block); + walk_unsafe(unsafe_exprs, db, infer, def, body, child, inside_unsafe_block); }); } @@ -170,4 +181,25 @@ fn main() { "#, ); } + + #[test] + fn missing_unsafe_diagnostic_with_static_mut() { + check_diagnostics( + r#" +struct Ty { + a: u8, +} + +static mut static_mut: Ty = Ty { a: 0 }; + +fn main() { + let x = static_mut.a; + //^^^^^^^^^^ This operation is unsafe and requires an unsafe function or block + unsafe { + let x = static_mut.a; + } +} +"#, + ); + } } |
