Skip to content

Commit e926148

Browse files
committed
Fix unsafe blocks
1 parent 1c277d1 commit e926148

File tree

3 files changed

+152
-6
lines changed

3 files changed

+152
-6
lines changed

clippy_utils/src/source.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use rustc_data_structures::sync::Lrc;
66
use rustc_errors::Applicability;
7-
use rustc_hir::{Expr, ExprKind};
7+
use rustc_hir::{BlockCheckMode, Expr, ExprKind, UnsafeSource};
88
use rustc_lint::{LateContext, LintContext};
99
use rustc_session::Session;
1010
use rustc_span::source_map::{original_sp, SourceMap};
@@ -71,11 +71,17 @@ pub fn expr_block<T: LintContext>(
7171
app: &mut Applicability,
7272
) -> String {
7373
let (code, from_macro) = snippet_block_with_context(cx, expr.span, outer, default, indent_relative_to, app);
74-
if from_macro {
75-
format!("{{ {code} }}")
76-
} else if let ExprKind::Block(_, _) = expr.kind {
74+
if !from_macro &&
75+
let ExprKind::Block(block, _) = expr.kind &&
76+
// TODO: Is this enough UnsafeSource::UserProvided, or should CompilerGenerated be also included?
77+
block.rules != BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided)
78+
{
7779
format!("{code}")
7880
} else {
81+
// FIXME: add extra indent for the unsafe blocks:
82+
// original code: unsafe { ... }
83+
// result code: { unsafe { ... } }
84+
// desired code: {\n unsafe { ... }\n}
7985
format!("{{ {code} }}")
8086
}
8187
}

tests/ui/single_match.stderr

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,5 +155,48 @@ LL | | (..) => {},
155155
LL | | }
156156
| |_____^ help: try this: `if let (.., Some(E::V), _) = (Some(42), Some(E::V), Some(42)) {}`
157157

158-
error: aborting due to 16 previous errors
158+
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
159+
--> $DIR/single_match.rs:249:5
160+
|
161+
LL | / match bar {
162+
LL | | Some(v) => unsafe {
163+
LL | | let r = &v as *const i32;
164+
LL | | println!("{}", *r);
165+
LL | | },
166+
LL | | _ => {},
167+
LL | | }
168+
| |_____^
169+
|
170+
help: try this
171+
|
172+
LL ~ if let Some(v) = bar { unsafe {
173+
LL + let r = &v as *const i32;
174+
LL + println!("{}", *r);
175+
LL + } }
176+
|
177+
178+
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
179+
--> $DIR/single_match.rs:257:5
180+
|
181+
LL | / match bar {
182+
LL | | Some(v) => {
183+
LL | | // this comment prevents rustfmt from collapsing the block
184+
LL | | unsafe {
185+
... |
186+
LL | | _ => {},
187+
LL | | }
188+
| |_____^
189+
|
190+
help: try this
191+
|
192+
LL ~ if let Some(v) = bar {
193+
LL + // this comment prevents rustfmt from collapsing the block
194+
LL + unsafe {
195+
LL + let r = &v as *const i32;
196+
LL + println!("{}", *r);
197+
LL + }
198+
LL + }
199+
|
200+
201+
error: aborting due to 18 previous errors
159202

tests/ui/single_match_else.stderr

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,5 +100,102 @@ LL + return;
100100
LL + }
101101
|
102102

103-
error: aborting due to 5 previous errors
103+
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
104+
--> $DIR/single_match_else.rs:120:5
105+
|
106+
LL | / match bar {
107+
LL | | Some(v) => unsafe {
108+
LL | | let r = &v as *const i32;
109+
LL | | println!("{}", *r);
110+
... |
111+
LL | | },
112+
LL | | }
113+
| |_____^
114+
|
115+
help: try this
116+
|
117+
LL ~ if let Some(v) = bar { unsafe {
118+
LL + let r = &v as *const i32;
119+
LL + println!("{}", *r);
120+
LL + } } else {
121+
LL + println!("None1");
122+
LL + println!("None2");
123+
LL + }
124+
|
125+
126+
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
127+
--> $DIR/single_match_else.rs:131:5
128+
|
129+
LL | / match bar {
130+
LL | | Some(v) => {
131+
LL | | println!("Some");
132+
LL | | println!("{v}");
133+
... |
134+
LL | | },
135+
LL | | }
136+
| |_____^
137+
|
138+
help: try this
139+
|
140+
LL ~ if let Some(v) = bar {
141+
LL + println!("Some");
142+
LL + println!("{v}");
143+
LL + } else { unsafe {
144+
LL + let v = 0;
145+
LL + let r = &v as *const i32;
146+
LL + println!("{}", *r);
147+
LL + } }
148+
|
149+
150+
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
151+
--> $DIR/single_match_else.rs:143:5
152+
|
153+
LL | / match bar {
154+
LL | | Some(v) => unsafe {
155+
LL | | let r = &v as *const i32;
156+
LL | | println!("{}", *r);
157+
... |
158+
LL | | },
159+
LL | | }
160+
| |_____^
161+
|
162+
help: try this
163+
|
164+
LL ~ if let Some(v) = bar { unsafe {
165+
LL + let r = &v as *const i32;
166+
LL + println!("{}", *r);
167+
LL + } } else { unsafe {
168+
LL + let v = 0;
169+
LL + let r = &v as *const i32;
170+
LL + println!("{}", *r);
171+
LL + } }
172+
|
173+
174+
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
175+
--> $DIR/single_match_else.rs:155:5
176+
|
177+
LL | / match bar {
178+
LL | | Some(v) => {
179+
LL | | // this comment prevents rustfmt from collapsing the block
180+
LL | | unsafe {
181+
... |
182+
LL | | },
183+
LL | | }
184+
| |_____^
185+
|
186+
help: try this
187+
|
188+
LL ~ if let Some(v) = bar {
189+
LL + // this comment prevents rustfmt from collapsing the block
190+
LL + unsafe {
191+
LL + let r = &v as *const i32;
192+
LL + println!("{}", *r);
193+
LL + }
194+
LL + } else {
195+
LL + println!("None");
196+
LL + println!("None");
197+
LL + }
198+
|
199+
200+
error: aborting due to 9 previous errors
104201

0 commit comments

Comments
 (0)