1
1
use crate :: Lint ;
2
2
use crate :: { EarlyContext , EarlyLintPass , LateContext , LateLintPass , LintContext } ;
3
3
use rustc_ast as ast;
4
- use rustc_ast:: util:: parser;
4
+ use rustc_ast:: util:: { classify , parser} ;
5
5
use rustc_ast:: { ExprKind , StmtKind } ;
6
6
use rustc_ast_pretty:: pprust;
7
7
use rustc_errors:: { pluralize, Applicability } ;
@@ -382,6 +382,7 @@ enum UnusedDelimsCtx {
382
382
FunctionArg ,
383
383
MethodArg ,
384
384
AssignedValue ,
385
+ AssignedValueLetElse ,
385
386
IfCond ,
386
387
WhileCond ,
387
388
ForIterExpr ,
@@ -398,7 +399,9 @@ impl From<UnusedDelimsCtx> for &'static str {
398
399
match ctx {
399
400
UnusedDelimsCtx :: FunctionArg => "function argument" ,
400
401
UnusedDelimsCtx :: MethodArg => "method argument" ,
401
- UnusedDelimsCtx :: AssignedValue => "assigned value" ,
402
+ UnusedDelimsCtx :: AssignedValue | UnusedDelimsCtx :: AssignedValueLetElse => {
403
+ "assigned value"
404
+ }
402
405
UnusedDelimsCtx :: IfCond => "`if` condition" ,
403
406
UnusedDelimsCtx :: WhileCond => "`while` condition" ,
404
407
UnusedDelimsCtx :: ForIterExpr => "`for` iterator expression" ,
@@ -441,14 +444,26 @@ trait UnusedDelimLint {
441
444
right_pos : Option < BytePos > ,
442
445
) ;
443
446
444
- fn is_expr_delims_necessary ( inner : & ast:: Expr , followed_by_block : bool ) -> bool {
447
+ fn is_expr_delims_necessary (
448
+ inner : & ast:: Expr ,
449
+ followed_by_block : bool ,
450
+ followed_by_else : bool ,
451
+ ) -> bool {
452
+ if followed_by_else {
453
+ match inner. kind {
454
+ ast:: ExprKind :: Binary ( op, ..) if op. node . lazy ( ) => return true ,
455
+ _ if classify:: expr_trailing_brace ( inner) . is_some ( ) => return true ,
456
+ _ => { }
457
+ }
458
+ }
459
+
445
460
// Prevent false-positives in cases like `fn x() -> u8 { ({ 0 } + 1) }`
446
461
let lhs_needs_parens = {
447
462
let mut innermost = inner;
448
463
loop {
449
464
if let ExprKind :: Binary ( _, lhs, _rhs) = & innermost. kind {
450
465
innermost = lhs;
451
- if !rustc_ast :: util :: classify:: expr_requires_semi_to_be_stmt ( innermost) {
466
+ if !classify:: expr_requires_semi_to_be_stmt ( innermost) {
452
467
break true ;
453
468
}
454
469
} else {
@@ -618,15 +633,12 @@ trait UnusedDelimLint {
618
633
fn check_stmt ( & mut self , cx : & EarlyContext < ' _ > , s : & ast:: Stmt ) {
619
634
match s. kind {
620
635
StmtKind :: Local ( ref local) if Self :: LINT_EXPR_IN_PATTERN_MATCHING_CTX => {
621
- if let Some ( value) = local. kind . init ( ) {
622
- self . check_unused_delims_expr (
623
- cx,
624
- & value,
625
- UnusedDelimsCtx :: AssignedValue ,
626
- false ,
627
- None ,
628
- None ,
629
- ) ;
636
+ if let Some ( ( init, els) ) = local. kind . init_else_opt ( ) {
637
+ let ctx = match els {
638
+ None => UnusedDelimsCtx :: AssignedValue ,
639
+ Some ( _) => UnusedDelimsCtx :: AssignedValueLetElse ,
640
+ } ;
641
+ self . check_unused_delims_expr ( cx, init, ctx, false , None , None ) ;
630
642
}
631
643
}
632
644
StmtKind :: Expr ( ref expr) => {
@@ -702,7 +714,8 @@ impl UnusedDelimLint for UnusedParens {
702
714
) {
703
715
match value. kind {
704
716
ast:: ExprKind :: Paren ( ref inner) => {
705
- if !Self :: is_expr_delims_necessary ( inner, followed_by_block)
717
+ let followed_by_else = ctx == UnusedDelimsCtx :: AssignedValueLetElse ;
718
+ if !Self :: is_expr_delims_necessary ( inner, followed_by_block, followed_by_else)
706
719
&& value. attrs . is_empty ( )
707
720
&& !value. span . from_expansion ( )
708
721
&& ( ctx != UnusedDelimsCtx :: LetScrutineeExpr
@@ -941,7 +954,7 @@ impl UnusedDelimLint for UnusedBraces {
941
954
// FIXME(const_generics): handle paths when #67075 is fixed.
942
955
if let [ stmt] = inner. stmts . as_slice ( ) {
943
956
if let ast:: StmtKind :: Expr ( ref expr) = stmt. kind {
944
- if !Self :: is_expr_delims_necessary ( expr, followed_by_block)
957
+ if !Self :: is_expr_delims_necessary ( expr, followed_by_block, false )
945
958
&& ( ctx != UnusedDelimsCtx :: AnonConst
946
959
|| matches ! ( expr. kind, ast:: ExprKind :: Lit ( _) ) )
947
960
&& !cx. sess ( ) . source_map ( ) . is_multiline ( value. span )
0 commit comments