diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir_ty/src/diagnostics.rs | 33 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/expr.rs | 29 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests.rs | 28 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/generated/nodes.rs | 2 |
4 files changed, 22 insertions, 70 deletions
diff --git a/crates/ra_hir_ty/src/diagnostics.rs b/crates/ra_hir_ty/src/diagnostics.rs index c6ca322fa..0b7bcdc9d 100644 --- a/crates/ra_hir_ty/src/diagnostics.rs +++ b/crates/ra_hir_ty/src/diagnostics.rs | |||
@@ -3,7 +3,10 @@ | |||
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::{ast::{self, NameOwner}, AstNode, AstPtr, SyntaxNodePtr}; | 6 | use ra_syntax::{ |
7 | ast::{self, NameOwner}, | ||
8 | AstNode, AstPtr, SyntaxNodePtr, | ||
9 | }; | ||
7 | use stdx::format_to; | 10 | use stdx::format_to; |
8 | 11 | ||
9 | pub use hir_def::{diagnostics::UnresolvedModule, expr::MatchArm, path::Path}; | 12 | pub use hir_def::{diagnostics::UnresolvedModule, expr::MatchArm, path::Path}; |
@@ -197,31 +200,3 @@ impl AstDiagnostic for MissingUnsafe { | |||
197 | ast::FnDef::cast(node).unwrap().name().unwrap() | 200 | ast::FnDef::cast(node).unwrap().name().unwrap() |
198 | } | 201 | } |
199 | } | 202 | } |
200 | |||
201 | #[derive(Debug)] | ||
202 | pub struct UnnecessaryUnsafe { | ||
203 | pub file: HirFileId, | ||
204 | pub fn_def: AstPtr<ast::FnDef>, | ||
205 | } | ||
206 | |||
207 | impl Diagnostic for UnnecessaryUnsafe { | ||
208 | fn message(&self) -> String { | ||
209 | format!("Unnecessary unsafe keyword on fn") | ||
210 | } | ||
211 | fn source(&self) -> InFile<SyntaxNodePtr> { | ||
212 | InFile { file_id: self.file, value: self.fn_def.clone().into() } | ||
213 | } | ||
214 | fn as_any(&self) -> &(dyn Any + Send + 'static) { | ||
215 | self | ||
216 | } | ||
217 | } | ||
218 | |||
219 | impl AstDiagnostic for UnnecessaryUnsafe { | ||
220 | type AST = ast::Name; | ||
221 | |||
222 | fn ast(&self, db: &impl AstDatabase) -> Self::AST { | ||
223 | let root = db.parse_or_expand(self.source().file_id).unwrap(); | ||
224 | let node = self.source().value.to_node(&root); | ||
225 | ast::FnDef::cast(node).unwrap().name().unwrap() | ||
226 | } | ||
227 | } | ||
diff --git a/crates/ra_hir_ty/src/expr.rs b/crates/ra_hir_ty/src/expr.rs index 04668f486..1a0710e0b 100644 --- a/crates/ra_hir_ty/src/expr.rs +++ b/crates/ra_hir_ty/src/expr.rs | |||
@@ -13,8 +13,8 @@ use crate::{ | |||
13 | db::HirDatabase, | 13 | db::HirDatabase, |
14 | diagnostics::{ | 14 | diagnostics::{ |
15 | MissingFields, MissingMatchArms, MissingOkInTailExpr, MissingPatFields, MissingUnsafe, | 15 | MissingFields, MissingMatchArms, MissingOkInTailExpr, MissingPatFields, MissingUnsafe, |
16 | UnnecessaryUnsafe, | ||
17 | }, | 16 | }, |
17 | lower::CallableDef, | ||
18 | utils::variant_data, | 18 | utils::variant_data, |
19 | ApplicationTy, InferenceResult, Ty, TypeCtor, | 19 | ApplicationTy, InferenceResult, Ty, TypeCtor, |
20 | _match::{is_useful, MatchCheckCtx, Matrix, PatStack, Usefulness}, | 20 | _match::{is_useful, MatchCheckCtx, Matrix, PatStack, Usefulness}, |
@@ -328,17 +328,14 @@ pub fn unsafe_expressions( | |||
328 | for (id, expr) in body.exprs.iter() { | 328 | for (id, expr) in body.exprs.iter() { |
329 | match expr { | 329 | match expr { |
330 | Expr::Call { callee, .. } => { | 330 | Expr::Call { callee, .. } => { |
331 | if infer | 331 | let ty = &infer.type_of_expr[*callee]; |
332 | .method_resolution(/* id */ *callee) | 332 | if let &Ty::Apply(ApplicationTy {ctor: TypeCtor::FnDef(CallableDef::FunctionId(func)), .. }) = ty { |
333 | .map(|func| db.function_data(func).is_unsafe) | 333 | if db.function_data(func).is_unsafe { |
334 | .unwrap_or(false) | 334 | unsafe_expr_ids.push(id); |
335 | { | 335 | } |
336 | unsafe_expr_ids.push(id); | 336 | } |
337 | } | ||
338 | } | 337 | } |
339 | Expr::MethodCall {/*_receiver, method_name,*/ .. } => { | 338 | Expr::MethodCall { .. } => { |
340 | // let receiver_ty = &infer.type_of_expr[*receiver]; | ||
341 | // receiver_ty | ||
342 | if infer | 339 | if infer |
343 | .method_resolution(id) | 340 | .method_resolution(id) |
344 | .map(|func| { | 341 | .map(|func| { |
@@ -382,9 +379,7 @@ impl<'a, 'b> UnsafeValidator<'a, 'b> { | |||
382 | let def = self.func.into(); | 379 | let def = self.func.into(); |
383 | let unsafe_expressions = unsafe_expressions(db, self.infer.as_ref(), def); | 380 | let unsafe_expressions = unsafe_expressions(db, self.infer.as_ref(), def); |
384 | let func_data = db.function_data(self.func); | 381 | let func_data = db.function_data(self.func); |
385 | let unnecessary = func_data.is_unsafe && unsafe_expressions.len() == 0; | 382 | if func_data.is_unsafe || unsafe_expressions.len() == 0 { |
386 | let missing = !func_data.is_unsafe && unsafe_expressions.len() > 0; | ||
387 | if !(unnecessary || missing) { | ||
388 | return; | 383 | return; |
389 | } | 384 | } |
390 | 385 | ||
@@ -394,10 +389,6 @@ impl<'a, 'b> UnsafeValidator<'a, 'b> { | |||
394 | let file = in_file.file_id; | 389 | let file = in_file.file_id; |
395 | let fn_def = AstPtr::new(&in_file.value); | 390 | let fn_def = AstPtr::new(&in_file.value); |
396 | 391 | ||
397 | if unnecessary { | 392 | self.sink.push(MissingUnsafe { file, fn_def }) |
398 | self.sink.push(UnnecessaryUnsafe { file, fn_def }) | ||
399 | } else { | ||
400 | self.sink.push(MissingUnsafe { file, fn_def }) | ||
401 | } | ||
402 | } | 393 | } |
403 | } | 394 | } |
diff --git a/crates/ra_hir_ty/src/tests.rs b/crates/ra_hir_ty/src/tests.rs index c1f6fbab8..28faccf38 100644 --- a/crates/ra_hir_ty/src/tests.rs +++ b/crates/ra_hir_ty/src/tests.rs | |||
@@ -544,7 +544,7 @@ fn missing_unsafe_diagnostic_with_raw_ptr() { | |||
544 | r" | 544 | r" |
545 | //- /lib.rs | 545 | //- /lib.rs |
546 | fn missing_unsafe() { | 546 | fn missing_unsafe() { |
547 | let x = &5 as *usize; | 547 | let x = &5 as *const usize; |
548 | let y = *x; | 548 | let y = *x; |
549 | } | 549 | } |
550 | ", | 550 | ", |
@@ -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 *usize;\n let y = *x;\n}": Missing unsafe keyword on fn"#); | 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"#); |
556 | } | 556 | } |
557 | 557 | ||
558 | #[test] | 558 | #[test] |
@@ -561,7 +561,7 @@ fn missing_unsafe_diagnostic_with_unsafe_call() { | |||
561 | r" | 561 | r" |
562 | //- /lib.rs | 562 | //- /lib.rs |
563 | unsafe fn unsafe_fn() { | 563 | unsafe fn unsafe_fn() { |
564 | let x = &5 as *usize; | 564 | let x = &5 as *const usize; |
565 | let y = *x; | 565 | let y = *x; |
566 | } | 566 | } |
567 | 567 | ||
@@ -585,7 +585,7 @@ struct HasUnsafe; | |||
585 | 585 | ||
586 | impl HasUnsafe { | 586 | impl HasUnsafe { |
587 | unsafe fn unsafe_fn() { | 587 | unsafe fn unsafe_fn() { |
588 | let x = &5 as *usize; | 588 | let x = &5 as *const usize; |
589 | let y = *x; | 589 | let y = *x; |
590 | } | 590 | } |
591 | } | 591 | } |
@@ -609,7 +609,7 @@ fn no_missing_unsafe_diagnostic_with_raw_ptr_in_unsafe_block() { | |||
609 | //- /lib.rs | 609 | //- /lib.rs |
610 | fn nothing_to_see_move_along() { | 610 | fn nothing_to_see_move_along() { |
611 | unsafe { | 611 | unsafe { |
612 | let x = &5 as *usize; | 612 | let x = &5 as *const usize; |
613 | let y = *x; | 613 | let y = *x; |
614 | } | 614 | } |
615 | } | 615 | } |
@@ -627,7 +627,7 @@ fn no_missing_unsafe_diagnostic_with_unsafe_call_in_unsafe_block() { | |||
627 | r" | 627 | r" |
628 | //- /lib.rs | 628 | //- /lib.rs |
629 | unsafe fn unsafe_fn() { | 629 | unsafe fn unsafe_fn() { |
630 | let x = &5 as *usize; | 630 | let x = &5 as *const usize; |
631 | let y = *x; | 631 | let y = *x; |
632 | } | 632 | } |
633 | 633 | ||
@@ -653,7 +653,7 @@ struct HasUnsafe; | |||
653 | 653 | ||
654 | impl HasUnsafe { | 654 | impl HasUnsafe { |
655 | unsafe fn unsafe_fn() { | 655 | unsafe fn unsafe_fn() { |
656 | let x = &5 as *usize; | 656 | let x = &5 as *const usize; |
657 | let y = *x; | 657 | let y = *x; |
658 | } | 658 | } |
659 | } | 659 | } |
@@ -673,20 +673,6 @@ fn nothing_to_see_move_along() { | |||
673 | } | 673 | } |
674 | 674 | ||
675 | #[test] | 675 | #[test] |
676 | fn unnecessary_unsafe_diagnostic() { | ||
677 | let diagnostics = TestDB::with_files( | ||
678 | r" | ||
679 | //- /lib.rs | ||
680 | unsafe fn actually_safe_fn() {} | ||
681 | ", | ||
682 | ) | ||
683 | .diagnostics() | ||
684 | .0; | ||
685 | |||
686 | assert_snapshot!(diagnostics, @r#""unsafe fn actually_safe_fn() {}": Unnecessary unsafe keyword on fn"#); | ||
687 | } | ||
688 | |||
689 | #[test] | ||
690 | fn break_outside_of_loop() { | 676 | fn break_outside_of_loop() { |
691 | let diagnostics = TestDB::with_files( | 677 | let diagnostics = TestDB::with_files( |
692 | r" | 678 | r" |
diff --git a/crates/ra_syntax/src/ast/generated/nodes.rs b/crates/ra_syntax/src/ast/generated/nodes.rs index 58141da11..a2366f997 100644 --- a/crates/ra_syntax/src/ast/generated/nodes.rs +++ b/crates/ra_syntax/src/ast/generated/nodes.rs | |||
@@ -899,7 +899,7 @@ impl ast::LoopBodyOwner for LoopExpr {} | |||
899 | impl LoopExpr { | 899 | impl LoopExpr { |
900 | pub fn loop_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![loop]) } | 900 | pub fn loop_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![loop]) } |
901 | } | 901 | } |
902 | /// Block expression with an optional prefix (label, try ketword, | 902 | /// Block expression with an optional prefix (label, try keyword, |
903 | /// unsafe keyword, async keyword...). | 903 | /// unsafe keyword, async keyword...). |
904 | /// | 904 | /// |
905 | /// ``` | 905 | /// ``` |