Skip to content

Commit b7c2339

Browse files
committed
Fix linting false positive when block used as val
1 parent c68032f commit b7c2339

File tree

3 files changed

+37
-3
lines changed

3 files changed

+37
-3
lines changed

compiler/rustc_lint/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ early_lint_methods!(
165165
pub BuiltinCombinedEarlyLintPass,
166166
[
167167
UnusedParens: UnusedParens::default(),
168-
UnusedBraces: UnusedBraces,
168+
UnusedBraces: UnusedBraces::default(),
169169
UnusedImportBraces: UnusedImportBraces,
170170
UnsafeCode: UnsafeCode,
171171
SpecialModuleName: SpecialModuleName,

compiler/rustc_lint/src/unused.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,7 +1340,12 @@ declare_lint! {
13401340
"unnecessary braces around an expression"
13411341
}
13421342

1343-
declare_lint_pass!(UnusedBraces => [UNUSED_BRACES]);
1343+
#[derive(Default)]
1344+
pub(crate) struct UnusedBraces {
1345+
block_as_value: bool,
1346+
}
1347+
1348+
impl_lint_pass!(UnusedBraces => [UNUSED_BRACES]);
13441349

13451350
impl UnusedDelimLint for UnusedBraces {
13461351
const DELIM_STR: &'static str = "braces";
@@ -1369,7 +1374,11 @@ impl UnusedDelimLint for UnusedBraces {
13691374
//
13701375
// - the block does not have a label
13711376
// - the block is not `unsafe`
1372-
// - the block contains exactly one expression (do not lint `{ expr; }`)
1377+
// - the block contains exactly one expression
1378+
// - do not lint `{ expr; }`
1379+
// - do not lint `{ epxr }` if block is used as value by other
1380+
// expressions, e.g. `return`, `match`, `break`, which may cause
1381+
// false positive.
13731382
// - `followed_by_block` is true and the internal expr may contain a `{`
13741383
// - the block is not multiline (do not lint multiline match arms)
13751384
// ```
@@ -1399,6 +1408,7 @@ impl UnusedDelimLint for UnusedBraces {
13991408
&& value.attrs.is_empty()
14001409
&& !value.span.from_expansion()
14011410
&& !inner.span.from_expansion()
1411+
&& !self.block_as_value
14021412
{
14031413
self.emit_unused_delims_expr(cx, value, ctx, left_pos, right_pos, is_kw)
14041414
}
@@ -1428,6 +1438,16 @@ impl EarlyLintPass for UnusedBraces {
14281438

14291439
#[inline]
14301440
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
1441+
use rustc_ast::ast::ExprKind::*;
1442+
self.block_as_value = match e.kind {
1443+
Ret(Some(ref expr)) | Match(ref expr, ..) | Break(_, Some(ref expr))
1444+
if matches!(expr.kind, Block(..)) =>
1445+
{
1446+
true
1447+
}
1448+
_ => false,
1449+
};
1450+
14311451
<Self as UnusedDelimLint>::check_expr(self, cx, e);
14321452

14331453
if let ExprKind::Repeat(_, ref anon_const) = e.kind {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//@ check-pass
2+
#[allow(unreachable_code)]
3+
#[warn(unused_braces)]
4+
5+
fn main() {
6+
return { return };
7+
if return { return } { return } else { return }
8+
match return { return } {
9+
_ => { return }
10+
}
11+
loop {
12+
break { break };
13+
}
14+
}

0 commit comments

Comments
 (0)