aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir_ty/src/diagnostics.rs33
-rw-r--r--crates/ra_hir_ty/src/expr.rs29
-rw-r--r--crates/ra_hir_ty/src/tests.rs28
-rw-r--r--crates/ra_syntax/src/ast/generated/nodes.rs2
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 @@
3use std::any::Any; 3use std::any::Any;
4 4
5use hir_expand::{db::AstDatabase, name::Name, HirFileId, InFile}; 5use hir_expand::{db::AstDatabase, name::Name, HirFileId, InFile};
6use ra_syntax::{ast::{self, NameOwner}, AstNode, AstPtr, SyntaxNodePtr}; 6use ra_syntax::{
7 ast::{self, NameOwner},
8 AstNode, AstPtr, SyntaxNodePtr,
9};
7use stdx::format_to; 10use stdx::format_to;
8 11
9pub use hir_def::{diagnostics::UnresolvedModule, expr::MatchArm, path::Path}; 12pub 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)]
202pub struct UnnecessaryUnsafe {
203 pub file: HirFileId,
204 pub fn_def: AstPtr<ast::FnDef>,
205}
206
207impl 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
219impl 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
546fn missing_unsafe() { 546fn 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
563unsafe fn unsafe_fn() { 563unsafe 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
586impl HasUnsafe { 586impl 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
610fn nothing_to_see_move_along() { 610fn 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
629unsafe fn unsafe_fn() { 629unsafe 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
654impl HasUnsafe { 654impl 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]
676fn unnecessary_unsafe_diagnostic() {
677 let diagnostics = TestDB::with_files(
678 r"
679//- /lib.rs
680unsafe 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]
690fn break_outside_of_loop() { 676fn 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 {}
899impl LoopExpr { 899impl 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/// ```