@@ -116,31 +116,35 @@ fn is_unit_expression(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
116
116
/// The expression inside a closure may or may not have surrounding braces and
117
117
/// semicolons, which causes problems when generating a suggestion. Given an
118
118
/// expression that evaluates to '()' or '!', recursively remove useless braces
119
- /// and semi-colons until is suitable for including in the suggestion template
120
- fn reduce_unit_expression ( cx : & LateContext < ' _ > , expr : & hir:: Expr < ' _ > ) -> Option < Span > {
119
+ /// and semi-colons until is suitable for including in the suggestion template.
120
+ /// The `bool` is `true` when the resulting `span` needs to be enclosed in an
121
+ /// `unsafe` block.
122
+ fn reduce_unit_expression ( cx : & LateContext < ' _ > , expr : & hir:: Expr < ' _ > ) -> Option < ( Span , bool ) > {
121
123
if !is_unit_expression ( cx, expr) {
122
124
return None ;
123
125
}
124
126
125
127
match expr. kind {
126
128
hir:: ExprKind :: Call ( _, _) | hir:: ExprKind :: MethodCall ( ..) => {
127
129
// Calls can't be reduced any more
128
- Some ( expr. span )
130
+ Some ( ( expr. span , false ) )
129
131
} ,
130
132
hir:: ExprKind :: Block ( block, _) => {
133
+ let is_unsafe = matches ! ( block. rules, hir:: BlockCheckMode :: UnsafeBlock ( _) ) ;
131
134
match ( block. stmts , block. expr . as_ref ( ) ) {
132
135
( [ ] , Some ( inner_expr) ) => {
133
136
// If block only contains an expression,
134
137
// reduce `{ X }` to `X`
135
138
reduce_unit_expression ( cx, inner_expr)
139
+ . map ( |( span, inner_is_unsafe) | ( span, inner_is_unsafe || is_unsafe) )
136
140
} ,
137
141
( [ inner_stmt] , None ) => {
138
142
// If block only contains statements,
139
143
// reduce `{ X; }` to `X` or `X;`
140
144
match inner_stmt. kind {
141
- hir:: StmtKind :: Let ( local) => Some ( local. span ) ,
142
- hir:: StmtKind :: Expr ( e) => Some ( e. span ) ,
143
- hir:: StmtKind :: Semi ( ..) => Some ( inner_stmt. span ) ,
145
+ hir:: StmtKind :: Let ( local) => Some ( ( local. span , is_unsafe ) ) ,
146
+ hir:: StmtKind :: Expr ( e) => Some ( ( e. span , is_unsafe ) ) ,
147
+ hir:: StmtKind :: Semi ( ..) => Some ( ( inner_stmt. span , is_unsafe ) ) ,
144
148
hir:: StmtKind :: Item ( ..) => None ,
145
149
}
146
150
} ,
@@ -228,10 +232,11 @@ fn lint_map_unit_fn(
228
232
let msg = suggestion_msg ( "closure" , map_type) ;
229
233
230
234
span_lint_and_then ( cx, lint, expr. span , msg, |diag| {
231
- if let Some ( reduced_expr_span) = reduce_unit_expression ( cx, closure_expr) {
235
+ if let Some ( ( reduced_expr_span, is_unsafe ) ) = reduce_unit_expression ( cx, closure_expr) {
232
236
let mut applicability = Applicability :: MachineApplicable ;
237
+ let ( prefix_is_unsafe, suffix_is_unsafe) = if is_unsafe { ( "unsafe { " , " }" ) } else { ( "" , "" ) } ;
233
238
let suggestion = format ! (
234
- "if let {0}({1}) = {2} {{ {3 } }}" ,
239
+ "if let {0}({1}) = {2} {{ {prefix_is_unsafe}{3}{suffix_is_unsafe } }}" ,
235
240
variant,
236
241
snippet_with_applicability( cx, binding. pat. span, "_" , & mut applicability) ,
237
242
snippet_with_applicability( cx, var_arg. span, "_" , & mut applicability) ,
0 commit comments