11use 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} ;
33use clippy_utils:: ty:: { implements_trait, is_type_diagnostic_item, peel_mid_ty_refs} ;
44use clippy_utils:: { is_lint_allowed, is_unit_expr, is_wild, peel_blocks, peel_hir_pat_refs, peel_n_hir_expr_refs} ;
55use core:: cmp:: max;
66use rustc_errors:: Applicability ;
77use rustc_hir:: { Arm , BindingAnnotation , Block , Expr , ExprKind , Pat , PatKind } ;
88use rustc_lint:: LateContext ;
99use rustc_middle:: ty:: { self , Ty } ;
10- use rustc_span:: sym;
10+ use rustc_span:: { sym, Span } ;
1111
1212use super :: { MATCH_BOOL , SINGLE_MATCH , SINGLE_MATCH_ELSE } ;
1313
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+
1430#[ rustfmt:: skip]
1531pub ( crate ) fn check ( cx : & LateContext < ' _ > , ex : & Expr < ' _ > , arms : & [ Arm < ' _ > ] , expr : & Expr < ' _ > ) {
1632 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:
2541 return ;
2642 }
2743 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 ) {
2945 None
3046 } else if let ExprKind :: Block ( Block { stmts, expr : block_expr, .. } , _) = els. kind {
3147 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:
3551 // block with 2+ statements or 1 expr and 1+ statement
3652 Some ( els)
3753 } else {
38- // not a block, don't lint
54+ // not a block or an emtpy block w/ comments , don't lint
3955 return ;
4056 } ;
4157
0 commit comments