@@ -355,6 +355,19 @@ impl From<UnusedDelimsCtx> for &'static str {
355
355
trait UnusedDelimLint {
356
356
const DELIM_STR : & ' static str ;
357
357
358
+ /// Due to `ref` pattern, there can be a difference between using
359
+ /// `{ expr }` and `expr` in pattern-matching contexts. This means
360
+ /// that we should only lint `unused_parens` and not `unused_braces`
361
+ /// in this case.
362
+ ///
363
+ /// ```rust
364
+ /// let mut a = 7;
365
+ /// let ref b = { a }; // We actually borrow a copy of `a` here.
366
+ /// a += 1; // By mutating `a` we invalidate any borrows of `a`.
367
+ /// assert_eq!(b + 1, a); // `b` does not borrow `a`, so we can still use it here.
368
+ /// ```
369
+ const LINT_EXPR_IN_PATTERN_MATCHING_CTX : bool ;
370
+
358
371
// this cannot be a constant is it refers to a static.
359
372
fn lint ( & self ) -> & ' static Lint ;
360
373
@@ -454,7 +467,10 @@ trait UnusedDelimLint {
454
467
fn check_expr ( & mut self , cx : & EarlyContext < ' _ > , e : & ast:: Expr ) {
455
468
use rustc_ast:: ast:: ExprKind :: * ;
456
469
let ( value, ctx, followed_by_block, left_pos, right_pos) = match e. kind {
457
- If ( ref cond, ref block, ..) => {
470
+ // Do not lint `unused_braces` in `if let` expressions.
471
+ If ( ref cond, ref block, ..)
472
+ if !matches ! ( cond. kind, Let ( _, _) ) || Self :: LINT_EXPR_IN_PATTERN_MATCHING_CTX =>
473
+ {
458
474
let left = e. span . lo ( ) + rustc_span:: BytePos ( 2 ) ;
459
475
let right = block. span . lo ( ) ;
460
476
( cond, UnusedDelimsCtx :: IfCond , true , Some ( left) , Some ( right) )
@@ -470,7 +486,7 @@ trait UnusedDelimLint {
470
486
( cond, UnusedDelimsCtx :: ForIterExpr , true , None , Some ( block. span . lo ( ) ) )
471
487
}
472
488
473
- Match ( ref head, _) => {
489
+ Match ( ref head, _) if Self :: LINT_EXPR_IN_PATTERN_MATCHING_CTX => {
474
490
let left = e. span . lo ( ) + rustc_span:: BytePos ( 5 ) ;
475
491
( head, UnusedDelimsCtx :: MatchScrutineeExpr , true , Some ( left) , None )
476
492
}
@@ -512,7 +528,7 @@ trait UnusedDelimLint {
512
528
513
529
fn check_stmt ( & mut self , cx : & EarlyContext < ' _ > , s : & ast:: Stmt ) {
514
530
match s. kind {
515
- StmtKind :: Local ( ref local) => {
531
+ StmtKind :: Local ( ref local) if Self :: LINT_EXPR_IN_PATTERN_MATCHING_CTX => {
516
532
if let Some ( ref value) = local. init {
517
533
self . check_unused_delims_expr (
518
534
cx,
@@ -565,6 +581,8 @@ declare_lint_pass!(UnusedParens => [UNUSED_PARENS]);
565
581
impl UnusedDelimLint for UnusedParens {
566
582
const DELIM_STR : & ' static str = "parentheses" ;
567
583
584
+ const LINT_EXPR_IN_PATTERN_MATCHING_CTX : bool = true ;
585
+
568
586
fn lint ( & self ) -> & ' static Lint {
569
587
UNUSED_PARENS
570
588
}
@@ -736,6 +754,8 @@ declare_lint_pass!(UnusedBraces => [UNUSED_BRACES]);
736
754
impl UnusedDelimLint for UnusedBraces {
737
755
const DELIM_STR : & ' static str = "braces" ;
738
756
757
+ const LINT_EXPR_IN_PATTERN_MATCHING_CTX : bool = false ;
758
+
739
759
fn lint ( & self ) -> & ' static Lint {
740
760
UNUSED_BRACES
741
761
}
0 commit comments