1
1
use clippy_utils:: diagnostics:: span_lint_and_sugg;
2
- use clippy_utils:: source:: { expr_block, snippet} ;
2
+ use clippy_utils:: source:: { expr_block, get_source_text , snippet} ;
3
3
use clippy_utils:: ty:: { implements_trait, is_type_diagnostic_item, peel_mid_ty_refs} ;
4
4
use clippy_utils:: { is_lint_allowed, is_unit_expr, is_wild, peel_blocks, peel_hir_pat_refs, peel_n_hir_expr_refs} ;
5
5
use core:: cmp:: max;
6
6
use rustc_errors:: Applicability ;
7
7
use rustc_hir:: { Arm , BindingAnnotation , Block , Expr , ExprKind , Pat , PatKind } ;
8
8
use rustc_lint:: LateContext ;
9
9
use rustc_middle:: ty:: { self , Ty } ;
10
- use rustc_span:: sym;
10
+ use rustc_span:: { sym, Span } ;
11
11
12
12
use super :: { MATCH_BOOL , SINGLE_MATCH , SINGLE_MATCH_ELSE } ;
13
13
14
+ /// Checks if there are comments contained within a span.
15
+ /// This is a very "naive" check, as it just looks for the literal characters // and /* in the
16
+ /// source text. This won't be accurate if there are potentially expressions contained within the
17
+ /// span, e.g. a string literal `"//"`, but we know that this isn't the case for empty
18
+ /// match arms.
19
+ fn empty_arm_has_comment ( cx : & LateContext < ' _ > , span : Span ) -> bool {
20
+ if let Some ( ff) = get_source_text ( cx, span)
21
+ && let Some ( text) = ff. as_str ( )
22
+ {
23
+ text. as_bytes ( ) . windows ( 2 )
24
+ . any ( |w| w == b"//" || w == b"/*" )
25
+ } else {
26
+ false
27
+ }
28
+ }
29
+
14
30
#[ rustfmt:: skip]
15
31
pub ( crate ) fn check ( cx : & LateContext < ' _ > , ex : & Expr < ' _ > , arms : & [ Arm < ' _ > ] , expr : & Expr < ' _ > ) {
16
32
if arms. len ( ) == 2 && arms[ 0 ] . guard . is_none ( ) && arms[ 1 ] . guard . is_none ( ) {
@@ -25,7 +41,7 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr:
25
41
return ;
26
42
}
27
43
let els = arms[ 1 ] . body ;
28
- let els = if is_unit_expr ( peel_blocks ( els) ) {
44
+ let els = if is_unit_expr ( peel_blocks ( els) ) && ! empty_arm_has_comment ( cx , els . span ) {
29
45
None
30
46
} else if let ExprKind :: Block ( Block { stmts, expr : block_expr, .. } , _) = els. kind {
31
47
if stmts. len ( ) == 1 && block_expr. is_none ( ) || stmts. is_empty ( ) && block_expr. is_some ( ) {
@@ -35,7 +51,7 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr:
35
51
// block with 2+ statements or 1 expr and 1+ statement
36
52
Some ( els)
37
53
} else {
38
- // not a block, don't lint
54
+ // not a block or an emtpy block w/ comments , don't lint
39
55
return ;
40
56
} ;
41
57
0 commit comments