diff options
author | Paul Daniel Faria <[email protected]> | 2020-05-27 13:51:08 +0100 |
---|---|---|
committer | Paul Daniel Faria <[email protected]> | 2020-06-27 15:10:26 +0100 |
commit | 9ce44be2ab7e9a99eece1c2e254f15ad1c6d73c5 (patch) | |
tree | 904c2c860ff62242bb01af23ea662c70cbe1152f | |
parent | b9569886a915f2411adaecbcad28eda8b163c3e3 (diff) |
Address review comments, have MissingUnsafe diagnostic point to each unsafe use, update tests
-rw-r--r-- | crates/ra_hir_ty/src/diagnostics.rs | 15 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/expr.rs | 23 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests.rs | 6 |
3 files changed, 19 insertions, 25 deletions
diff --git a/crates/ra_hir_ty/src/diagnostics.rs b/crates/ra_hir_ty/src/diagnostics.rs index 0b7bcdc9d..a59efb347 100644 --- a/crates/ra_hir_ty/src/diagnostics.rs +++ b/crates/ra_hir_ty/src/diagnostics.rs | |||
@@ -3,10 +3,7 @@ | |||
3 | use std::any::Any; | 3 | use std::any::Any; |
4 | 4 | ||
5 | use hir_expand::{db::AstDatabase, name::Name, HirFileId, InFile}; | 5 | use hir_expand::{db::AstDatabase, name::Name, HirFileId, InFile}; |
6 | use ra_syntax::{ | 6 | use ra_syntax::{ast, AstNode, AstPtr, SyntaxNodePtr}; |
7 | ast::{self, NameOwner}, | ||
8 | AstNode, AstPtr, SyntaxNodePtr, | ||
9 | }; | ||
10 | use stdx::format_to; | 7 | use stdx::format_to; |
11 | 8 | ||
12 | pub use hir_def::{diagnostics::UnresolvedModule, expr::MatchArm, path::Path}; | 9 | pub use hir_def::{diagnostics::UnresolvedModule, expr::MatchArm, path::Path}; |
@@ -176,15 +173,15 @@ impl AstDiagnostic for BreakOutsideOfLoop { | |||
176 | #[derive(Debug)] | 173 | #[derive(Debug)] |
177 | pub struct MissingUnsafe { | 174 | pub struct MissingUnsafe { |
178 | pub file: HirFileId, | 175 | pub file: HirFileId, |
179 | pub fn_def: AstPtr<ast::FnDef>, | 176 | pub expr: AstPtr<ast::Expr>, |
180 | } | 177 | } |
181 | 178 | ||
182 | impl Diagnostic for MissingUnsafe { | 179 | impl Diagnostic for MissingUnsafe { |
183 | fn message(&self) -> String { | 180 | fn message(&self) -> String { |
184 | format!("Missing unsafe keyword on fn") | 181 | format!("This operation is unsafe and requires an unsafe function or block") |
185 | } | 182 | } |
186 | fn source(&self) -> InFile<SyntaxNodePtr> { | 183 | fn source(&self) -> InFile<SyntaxNodePtr> { |
187 | InFile { file_id: self.file, value: self.fn_def.clone().into() } | 184 | InFile { file_id: self.file, value: self.expr.clone().into() } |
188 | } | 185 | } |
189 | fn as_any(&self) -> &(dyn Any + Send + 'static) { | 186 | fn as_any(&self) -> &(dyn Any + Send + 'static) { |
190 | self | 187 | self |
@@ -192,11 +189,11 @@ impl Diagnostic for MissingUnsafe { | |||
192 | } | 189 | } |
193 | 190 | ||
194 | impl AstDiagnostic for MissingUnsafe { | 191 | impl AstDiagnostic for MissingUnsafe { |
195 | type AST = ast::Name; | 192 | type AST = ast::Expr; |
196 | 193 | ||
197 | fn ast(&self, db: &impl AstDatabase) -> Self::AST { | 194 | fn ast(&self, db: &impl AstDatabase) -> Self::AST { |
198 | let root = db.parse_or_expand(self.source().file_id).unwrap(); | 195 | let root = db.parse_or_expand(self.source().file_id).unwrap(); |
199 | let node = self.source().value.to_node(&root); | 196 | let node = self.source().value.to_node(&root); |
200 | ast::FnDef::cast(node).unwrap().name().unwrap() | 197 | ast::Expr::cast(node).unwrap() |
201 | } | 198 | } |
202 | } | 199 | } |
diff --git a/crates/ra_hir_ty/src/expr.rs b/crates/ra_hir_ty/src/expr.rs index ce73251b8..5f332aadb 100644 --- a/crates/ra_hir_ty/src/expr.rs +++ b/crates/ra_hir_ty/src/expr.rs | |||
@@ -2,9 +2,7 @@ | |||
2 | 2 | ||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use hir_def::{ | 5 | use hir_def::{path::path, resolver::HasResolver, AdtId, DefWithBodyId, FunctionId}; |
6 | path::path, resolver::HasResolver, src::HasSource, AdtId, DefWithBodyId, FunctionId, Lookup, | ||
7 | }; | ||
8 | use hir_expand::diagnostics::DiagnosticSink; | 6 | use hir_expand::diagnostics::DiagnosticSink; |
9 | use ra_syntax::{ast, AstPtr}; | 7 | use ra_syntax::{ast, AstPtr}; |
10 | use rustc_hash::FxHashSet; | 8 | use rustc_hash::FxHashSet; |
@@ -346,7 +344,7 @@ pub fn unsafe_expressions( | |||
346 | } | 344 | } |
347 | } | 345 | } |
348 | Expr::Call { callee, .. } => { | 346 | Expr::Call { callee, .. } => { |
349 | let ty = &infer.type_of_expr[*callee]; | 347 | let ty = &infer[*callee]; |
350 | if let &Ty::Apply(ApplicationTy { | 348 | if let &Ty::Apply(ApplicationTy { |
351 | ctor: TypeCtor::FnDef(CallableDef::FunctionId(func)), | 349 | ctor: TypeCtor::FnDef(CallableDef::FunctionId(func)), |
352 | .. | 350 | .. |
@@ -361,7 +359,7 @@ pub fn unsafe_expressions( | |||
361 | if infer | 359 | if infer |
362 | .method_resolution(id) | 360 | .method_resolution(id) |
363 | .map(|func| db.function_data(func).is_unsafe) | 361 | .map(|func| db.function_data(func).is_unsafe) |
364 | .unwrap_or_else(|| false) | 362 | .unwrap_or(false) |
365 | { | 363 | { |
366 | unsafe_exprs.push(UnsafeExpr::new(id)); | 364 | unsafe_exprs.push(UnsafeExpr::new(id)); |
367 | } | 365 | } |
@@ -409,7 +407,7 @@ impl<'a, 'b> UnsafeValidator<'a, 'b> { | |||
409 | let func_data = db.function_data(self.func); | 407 | let func_data = db.function_data(self.func); |
410 | if func_data.is_unsafe | 408 | if func_data.is_unsafe |
411 | || unsafe_expressions | 409 | || unsafe_expressions |
412 | .into_iter() | 410 | .iter() |
413 | .filter(|unsafe_expr| !unsafe_expr.inside_unsafe_block) | 411 | .filter(|unsafe_expr| !unsafe_expr.inside_unsafe_block) |
414 | .count() | 412 | .count() |
415 | == 0 | 413 | == 0 |
@@ -417,12 +415,11 @@ impl<'a, 'b> UnsafeValidator<'a, 'b> { | |||
417 | return; | 415 | return; |
418 | } | 416 | } |
419 | 417 | ||
420 | let loc = self.func.lookup(db.upcast()); | 418 | let (_, body_source) = db.body_with_source_map(def); |
421 | let in_file = loc.source(db.upcast()); | 419 | for unsafe_expr in unsafe_expressions { |
422 | 420 | if let Ok(in_file) = body_source.as_ref().expr_syntax(unsafe_expr.expr) { | |
423 | let file = in_file.file_id; | 421 | self.sink.push(MissingUnsafe { file: in_file.file_id, expr: in_file.value }) |
424 | let fn_def = AstPtr::new(&in_file.value); | 422 | } |
425 | 423 | } | |
426 | self.sink.push(MissingUnsafe { file, fn_def }) | ||
427 | } | 424 | } |
428 | } | 425 | } |
diff --git a/crates/ra_hir_ty/src/tests.rs b/crates/ra_hir_ty/src/tests.rs index 4bc2e8b27..26b3aeb50 100644 --- a/crates/ra_hir_ty/src/tests.rs +++ b/crates/ra_hir_ty/src/tests.rs | |||
@@ -552,7 +552,7 @@ fn missing_unsafe() { | |||
552 | .diagnostics() | 552 | .diagnostics() |
553 | .0; | 553 | .0; |
554 | 554 | ||
555 | assert_snapshot!(diagnostics, @r#""fn missing_unsafe() {\n let x = &5 as *const usize;\n let y = *x;\n}": Missing unsafe keyword on fn"#); | 555 | assert_snapshot!(diagnostics, @r#""*x": This operation is unsafe and requires an unsafe function or block"#); |
556 | } | 556 | } |
557 | 557 | ||
558 | #[test] | 558 | #[test] |
@@ -573,7 +573,7 @@ fn missing_unsafe() { | |||
573 | .diagnostics() | 573 | .diagnostics() |
574 | .0; | 574 | .0; |
575 | 575 | ||
576 | assert_snapshot!(diagnostics, @r#""fn missing_unsafe() {\n unsafe_fn();\n}": Missing unsafe keyword on fn"#); | 576 | assert_snapshot!(diagnostics, @r#""unsafe_fn()": This operation is unsafe and requires an unsafe function or block"#); |
577 | } | 577 | } |
578 | 578 | ||
579 | #[test] | 579 | #[test] |
@@ -599,7 +599,7 @@ fn missing_unsafe() { | |||
599 | .diagnostics() | 599 | .diagnostics() |
600 | .0; | 600 | .0; |
601 | 601 | ||
602 | assert_snapshot!(diagnostics, @r#""fn missing_unsafe() {\n HasUnsafe.unsafe_fn();\n}": Missing unsafe keyword on fn"#); | 602 | assert_snapshot!(diagnostics, @r#""HasUnsafe.unsafe_fn()": This operation is unsafe and requires an unsafe function or block"#); |
603 | } | 603 | } |
604 | 604 | ||
605 | #[test] | 605 | #[test] |