trait UnusedDelimLint {
const DELIM_STR: &'static str;
+ /// Due to `ref` pattern, there can be a difference between using
+ /// `{ expr }` and `expr` in pattern-matching contexts. This means
+ /// that we should only lint `unused_parens` and not `unused_braces`
+ /// in this case.
+ ///
+ /// ```rust
+ /// let mut a = 7;
+ /// let ref b = { a }; // We actually borrow a copy of `a` here.
+ /// a += 1; // By mutating `a` we invalidate any borrows of `a`.
+ /// assert_eq!(b + 1, a); // `b` does not borrow `a`, so we can still use it here.
+ /// ```
+ const LINT_EXPR_IN_PATTERN_MATCHING_CTX: bool;
+
// this cannot be a constant is it refers to a static.
fn lint(&self) -> &'static Lint;
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
use rustc_ast::ast::ExprKind::*;
let (value, ctx, followed_by_block, left_pos, right_pos) = match e.kind {
- If(ref cond, ref block, ..) => {
+ // Do not lint `unused_braces` in `if let` expressions.
+ If(ref cond, ref block, ..)
+ if !matches!(cond.kind, Let(_, _)) || Self::LINT_EXPR_IN_PATTERN_MATCHING_CTX =>
+ {
let left = e.span.lo() + rustc_span::BytePos(2);
let right = block.span.lo();
(cond, UnusedDelimsCtx::IfCond, true, Some(left), Some(right))
(cond, UnusedDelimsCtx::ForIterExpr, true, None, Some(block.span.lo()))
}
- Match(ref head, _) => {
+ Match(ref head, _) if Self::LINT_EXPR_IN_PATTERN_MATCHING_CTX => {
let left = e.span.lo() + rustc_span::BytePos(5);
(head, UnusedDelimsCtx::MatchScrutineeExpr, true, Some(left), None)
}
fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) {
match s.kind {
- StmtKind::Local(ref local) => {
+ StmtKind::Local(ref local) if Self::LINT_EXPR_IN_PATTERN_MATCHING_CTX => {
if let Some(ref value) = local.init {
self.check_unused_delims_expr(
cx,
impl UnusedDelimLint for UnusedParens {
const DELIM_STR: &'static str = "parentheses";
+ const LINT_EXPR_IN_PATTERN_MATCHING_CTX: bool = true;
+
fn lint(&self) -> &'static Lint {
UNUSED_PARENS
}
impl UnusedDelimLint for UnusedBraces {
const DELIM_STR: &'static str = "braces";
+ const LINT_EXPR_IN_PATTERN_MATCHING_CTX: bool = false;
+
fn lint(&self) -> &'static Lint {
UNUSED_BRACES
}
// check-pass
#![warn(unused_braces, unused_parens)]
+fn consume<T>(_: T) {}
+
fn main() {
let _ = (7);
//~^WARN unnecessary parentheses
- let _ = { 7 };
- //~^ WARN unnecessary braces
+ // Do not emit a lint in these cases,
+ // as we have to be careful with
+ // `ref` patterns.
+ {
+ let _ = { 7 };
+
+ if let 7 = { 7 } { }
+
+ match { 7 } {
+ _ => (),
+ }
+ }
- if let 7 = { 7 } {
+ if { true } {
+ //~^ WARN unnecessary braces
+ }
+
+ while { false } {
//~^ WARN unnecessary braces
}
let _: [u8; { 3 }];
//~^ WARN unnecessary braces
- // do not emit error for multiline blocks.
+ consume({ 7 });
+ //~^ WARN unnecessary braces
+
+ // Do not emit lint for multiline blocks.
let _ = {
7
};
- // do not emit error for unsafe blocks.
+ // Do not emit lint for unsafe blocks.
let _ = unsafe { 7 };
- // do not emit error, as the `{` would then
+ // Do not emit lint, as the `{` would then
// be parsed as part of the `return`.
if { return } {
warning: unnecessary parentheses around assigned value
- --> $DIR/unused_braces.rs:5:13
+ --> $DIR/unused_braces.rs:7:13
|
LL | let _ = (7);
| ^^^ help: remove these parentheses
LL | #![warn(unused_braces, unused_parens)]
| ^^^^^^^^^^^^^
-warning: unnecessary braces around assigned value
- --> $DIR/unused_braces.rs:8:13
+warning: unnecessary braces around `if` condition
+ --> $DIR/unused_braces.rs:23:8
|
-LL | let _ = { 7 };
- | ^^^^^ help: remove these braces
+LL | if { true } {
+ | ^^^^^^^^ help: remove these braces
|
note: the lint level is defined here
--> $DIR/unused_braces.rs:2:9
LL | #![warn(unused_braces, unused_parens)]
| ^^^^^^^^^^^^^
-warning: unnecessary braces around `let` scrutinee expression
- --> $DIR/unused_braces.rs:11:16
+warning: unnecessary braces around `while` condition
+ --> $DIR/unused_braces.rs:27:11
|
-LL | if let 7 = { 7 } {
- | ^^^^^ help: remove these braces
+LL | while { false } {
+ | ^^^^^^^^^ help: remove these braces
warning: unnecessary braces around const expression
- --> $DIR/unused_braces.rs:15:17
+ --> $DIR/unused_braces.rs:31:17
|
LL | let _: [u8; { 3 }];
| ^^^^^ help: remove these braces
+warning: unnecessary braces around function argument
+ --> $DIR/unused_braces.rs:34:13
+ |
+LL | consume({ 7 });
+ | ^^^^^ help: remove these braces
+
--- /dev/null
+// check-pass
+#![warn(unused_braces)]
+
+// changing `&{ expr }` to `&expr` changes the semantic of the program
+// so we should not warn this case
+
+#[repr(packed)]
+struct A {
+ a: u8,
+ b: u32,
+}
+
+fn consume<T>(_: T) {}
+
+fn main() {
+ let a = A {
+ a: 42,
+ b: 1729,
+ };
+
+ consume(&{ a.b });
+ consume({ a.b });
+ //~^ WARN unnecessary braces
+}
--- /dev/null
+warning: unnecessary braces around function argument
+ --> $DIR/unused_braces_borrow.rs:22:13
+ |
+LL | consume({ a.b });
+ | ^^^^^^^ help: remove these braces
+ |
+note: the lint level is defined here
+ --> $DIR/unused_braces_borrow.rs:2:9
+ |
+LL | #![warn(unused_braces)]
+ | ^^^^^^^^^^^^^
+
+++ /dev/null
-// check-pass
-#![warn(unused_braces)]
-
-// changing `&{ expr }` to `&expr` changes the semantic of the program
-// so we should not warn this case
-
-#[repr(packed)]
-struct A {
- a: u8,
- b: u32,
-}
-
-fn main() {
- let a = A {
- a: 42,
- b: 1729,
- };
-
- let _ = &{ a.b };
- let _ = { a.b };
- //~^ WARN unnecessary braces
-}
+++ /dev/null
-warning: unnecessary braces around assigned value
- --> $DIR/unused_parens_borrow.rs:20:13
- |
-LL | let _ = { a.b };
- | ^^^^^^^ help: remove these braces
- |
-note: the lint level is defined here
- --> $DIR/unused_parens_borrow.rs:2:9
- |
-LL | #![warn(unused_braces)]
- | ^^^^^^^^^^^^^
-