about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuri Astrakhan <YuriAstrakhan@gmail.com>2023-05-22 04:07:17 -0400
committerYuri Astrakhan <YuriAstrakhan@gmail.com>2023-05-22 04:07:17 -0400
commite92614818879f24994c3890dcb958b8baa2d0678 (patch)
treef80037a9a44f7256144b357c063026b2d401ecfb
parent1c277d1be896ad5499a464d92a3d427488df470e (diff)
downloadrust-e92614818879f24994c3890dcb958b8baa2d0678.tar.gz
rust-e92614818879f24994c3890dcb958b8baa2d0678.zip
Fix unsafe blocks
-rw-r--r--clippy_utils/src/source.rs14
-rw-r--r--tests/ui/single_match.stderr45
-rw-r--r--tests/ui/single_match_else.stderr99
3 files changed, 152 insertions, 6 deletions
diff --git a/clippy_utils/src/source.rs b/clippy_utils/src/source.rs
index 0f60290644a..61e249b995e 100644
--- a/clippy_utils/src/source.rs
+++ b/clippy_utils/src/source.rs
@@ -4,7 +4,7 @@
 
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind};
+use rustc_hir::{BlockCheckMode, Expr, ExprKind, UnsafeSource};
 use rustc_lint::{LateContext, LintContext};
 use rustc_session::Session;
 use rustc_span::source_map::{original_sp, SourceMap};
@@ -71,11 +71,17 @@ pub fn expr_block<T: LintContext>(
     app: &mut Applicability,
 ) -> String {
     let (code, from_macro) = snippet_block_with_context(cx, expr.span, outer, default, indent_relative_to, app);
-    if from_macro {
-        format!("{{ {code} }}")
-    } else if let ExprKind::Block(_, _) = expr.kind {
+    if !from_macro &&
+        let ExprKind::Block(block, _) = expr.kind &&
+        // TODO: Is this enough UnsafeSource::UserProvided, or should CompilerGenerated be also included?
+        block.rules != BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided)
+    {
         format!("{code}")
     } else {
+        // FIXME: add extra indent for the unsafe blocks:
+        //     original code:   unsafe { ... }
+        //     result code:     { unsafe { ... } }
+        //     desired code:    {\n  unsafe { ... }\n}
         format!("{{ {code} }}")
     }
 }
diff --git a/tests/ui/single_match.stderr b/tests/ui/single_match.stderr
index 7cecc1b7395..810f153fe62 100644
--- a/tests/ui/single_match.stderr
+++ b/tests/ui/single_match.stderr
@@ -155,5 +155,48 @@ LL | |         (..) => {},
 LL | |     }
    | |_____^ help: try this: `if let (.., Some(E::V), _) = (Some(42), Some(E::V), Some(42)) {}`
 
-error: aborting due to 16 previous errors
+error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
+  --> $DIR/single_match.rs:249:5
+   |
+LL | /     match bar {
+LL | |         Some(v) => unsafe {
+LL | |             let r = &v as *const i32;
+LL | |             println!("{}", *r);
+LL | |         },
+LL | |         _ => {},
+LL | |     }
+   | |_____^
+   |
+help: try this
+   |
+LL ~     if let Some(v) = bar { unsafe {
+LL +         let r = &v as *const i32;
+LL +         println!("{}", *r);
+LL +     } }
+   |
+
+error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
+  --> $DIR/single_match.rs:257:5
+   |
+LL | /     match bar {
+LL | |         Some(v) => {
+LL | |             // this comment prevents rustfmt from collapsing the block
+LL | |             unsafe {
+...  |
+LL | |         _ => {},
+LL | |     }
+   | |_____^
+   |
+help: try this
+   |
+LL ~     if let Some(v) = bar {
+LL +         // this comment prevents rustfmt from collapsing the block
+LL +         unsafe {
+LL +             let r = &v as *const i32;
+LL +             println!("{}", *r);
+LL +         }
+LL +     }
+   |
+
+error: aborting due to 18 previous errors
 
diff --git a/tests/ui/single_match_else.stderr b/tests/ui/single_match_else.stderr
index 62876a55dc6..6537156d515 100644
--- a/tests/ui/single_match_else.stderr
+++ b/tests/ui/single_match_else.stderr
@@ -100,5 +100,102 @@ LL +         return;
 LL +     }
    |
 
-error: aborting due to 5 previous errors
+error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
+  --> $DIR/single_match_else.rs:120:5
+   |
+LL | /     match bar {
+LL | |         Some(v) => unsafe {
+LL | |             let r = &v as *const i32;
+LL | |             println!("{}", *r);
+...  |
+LL | |         },
+LL | |     }
+   | |_____^
+   |
+help: try this
+   |
+LL ~     if let Some(v) = bar { unsafe {
+LL +         let r = &v as *const i32;
+LL +         println!("{}", *r);
+LL +     } } else {
+LL +         println!("None1");
+LL +         println!("None2");
+LL +     }
+   |
+
+error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
+  --> $DIR/single_match_else.rs:131:5
+   |
+LL | /     match bar {
+LL | |         Some(v) => {
+LL | |             println!("Some");
+LL | |             println!("{v}");
+...  |
+LL | |         },
+LL | |     }
+   | |_____^
+   |
+help: try this
+   |
+LL ~     if let Some(v) = bar {
+LL +         println!("Some");
+LL +         println!("{v}");
+LL +     } else { unsafe {
+LL +         let v = 0;
+LL +         let r = &v as *const i32;
+LL +         println!("{}", *r);
+LL +     } }
+   |
+
+error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
+  --> $DIR/single_match_else.rs:143:5
+   |
+LL | /     match bar {
+LL | |         Some(v) => unsafe {
+LL | |             let r = &v as *const i32;
+LL | |             println!("{}", *r);
+...  |
+LL | |         },
+LL | |     }
+   | |_____^
+   |
+help: try this
+   |
+LL ~     if let Some(v) = bar { unsafe {
+LL +         let r = &v as *const i32;
+LL +         println!("{}", *r);
+LL +     } } else { unsafe {
+LL +         let v = 0;
+LL +         let r = &v as *const i32;
+LL +         println!("{}", *r);
+LL +     } }
+   |
+
+error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
+  --> $DIR/single_match_else.rs:155:5
+   |
+LL | /     match bar {
+LL | |         Some(v) => {
+LL | |             // this comment prevents rustfmt from collapsing the block
+LL | |             unsafe {
+...  |
+LL | |         },
+LL | |     }
+   | |_____^
+   |
+help: try this
+   |
+LL ~     if let Some(v) = bar {
+LL +         // this comment prevents rustfmt from collapsing the block
+LL +         unsafe {
+LL +             let r = &v as *const i32;
+LL +             println!("{}", *r);
+LL +         }
+LL +     } else {
+LL +         println!("None");
+LL +         println!("None");
+LL +     }
+   |
+
+error: aborting due to 9 previous errors