@@ -6,7 +6,6 @@ use rustc_errors::Applicability;
6
6
use rustc_lint:: { EarlyContext , EarlyLintPass , LintContext } ;
7
7
use rustc_middle:: lint:: in_external_macro;
8
8
use rustc_session:: impl_lint_pass;
9
- use rustc_span:: Span ;
10
9
11
10
declare_clippy_lint ! {
12
11
/// ### What it does
@@ -41,61 +40,80 @@ impl AlmostCompleteRange {
41
40
}
42
41
impl EarlyLintPass for AlmostCompleteRange {
43
42
fn check_expr ( & mut self , cx : & EarlyContext < ' _ > , e : & Expr ) {
44
- if let ExprKind :: Range ( Some ( start) , Some ( end) , RangeLimits :: HalfOpen ) = & e. kind {
45
- let ctxt = e. span . ctxt ( ) ;
46
- let sugg = if let Some ( start) = walk_span_to_context ( start. span , ctxt)
47
- && let Some ( end) = walk_span_to_context ( end. span , ctxt)
48
- && self . msrv . meets ( msrvs:: RANGE_INCLUSIVE )
49
- {
50
- Some ( ( trim_span ( cx. sess ( ) . source_map ( ) , start. between ( end) ) , "..=" ) )
51
- } else {
52
- None
53
- } ;
54
- check_range ( cx, e. span , start, end, sugg) ;
43
+ if let ExprKind :: Range ( Some ( start) , Some ( end) , RangeLimits :: HalfOpen ) = & e. kind
44
+ && is_incomplete_range ( start, end)
45
+ && !in_external_macro ( cx. sess ( ) , e. span )
46
+ {
47
+ span_lint_and_then (
48
+ cx,
49
+ ALMOST_COMPLETE_RANGE ,
50
+ e. span ,
51
+ "almost complete ascii range" ,
52
+ |diag| {
53
+ let ctxt = e. span . ctxt ( ) ;
54
+ if let Some ( start) = walk_span_to_context ( start. span , ctxt)
55
+ && let Some ( end) = walk_span_to_context ( end. span , ctxt)
56
+ && self . msrv . meets ( msrvs:: RANGE_INCLUSIVE )
57
+ {
58
+ diag. span_suggestion (
59
+ trim_span ( cx. sess ( ) . source_map ( ) , start. between ( end) ) ,
60
+ "use an inclusive range" ,
61
+ "..=" . to_owned ( ) ,
62
+ Applicability :: MaybeIncorrect ,
63
+ ) ;
64
+ }
65
+ } ,
66
+ ) ;
55
67
}
56
68
}
57
69
58
70
fn check_pat ( & mut self , cx : & EarlyContext < ' _ > , p : & Pat ) {
59
71
if let PatKind :: Range ( Some ( start) , Some ( end) , kind) = & p. kind
60
72
&& matches ! ( kind. node, RangeEnd :: Excluded )
73
+ && is_incomplete_range ( start, end)
74
+ && !in_external_macro ( cx. sess ( ) , p. span )
61
75
{
62
- let sugg = if self . msrv . meets ( msrvs:: RANGE_INCLUSIVE ) {
63
- "..="
64
- } else {
65
- "..."
66
- } ;
67
- check_range ( cx, p. span , start, end, Some ( ( kind. span , sugg) ) ) ;
76
+ span_lint_and_then (
77
+ cx,
78
+ ALMOST_COMPLETE_RANGE ,
79
+ p. span ,
80
+ "almost complete ascii range" ,
81
+ |diag| {
82
+ diag. span_suggestion (
83
+ kind. span ,
84
+ "use an inclusive range" ,
85
+ if self . msrv . meets ( msrvs:: RANGE_INCLUSIVE ) {
86
+ "..=" . to_owned ( )
87
+ } else {
88
+ "..." . to_owned ( )
89
+ } ,
90
+ Applicability :: MaybeIncorrect ,
91
+ ) ;
92
+ } ,
93
+ ) ;
68
94
}
69
95
}
70
96
71
97
extract_msrv_attr ! ( EarlyContext ) ;
72
98
}
73
99
74
- fn check_range ( cx : & EarlyContext < ' _ > , span : Span , start : & Expr , end : & Expr , sugg : Option < ( Span , & str ) > ) {
75
- if let ExprKind :: Lit ( start_token_lit) = start. peel_parens ( ) . kind
76
- && let ExprKind :: Lit ( end_token_lit) = end. peel_parens ( ) . kind
77
- && matches ! (
78
- (
79
- LitKind :: from_token_lit( start_token_lit) ,
80
- LitKind :: from_token_lit( end_token_lit) ,
81
- ) ,
82
- (
83
- Ok ( LitKind :: Byte ( b'a' ) | LitKind :: Char ( 'a' ) ) ,
84
- Ok ( LitKind :: Byte ( b'z' ) | LitKind :: Char ( 'z' ) )
85
- ) | (
86
- Ok ( LitKind :: Byte ( b'A' ) | LitKind :: Char ( 'A' ) ) ,
87
- Ok ( LitKind :: Byte ( b'Z' ) | LitKind :: Char ( 'Z' ) ) ,
88
- ) | (
89
- Ok ( LitKind :: Byte ( b'0' ) | LitKind :: Char ( '0' ) ) ,
90
- Ok ( LitKind :: Byte ( b'9' ) | LitKind :: Char ( '9' ) ) ,
100
+ fn is_incomplete_range ( start : & Expr , end : & Expr ) -> bool {
101
+ match ( & start. peel_parens ( ) . kind , & end. peel_parens ( ) . kind ) {
102
+ ( & ExprKind :: Lit ( start_lit) , & ExprKind :: Lit ( end_lit) ) => {
103
+ matches ! (
104
+ ( LitKind :: from_token_lit( start_lit) , LitKind :: from_token_lit( end_lit) , ) ,
105
+ (
106
+ Ok ( LitKind :: Byte ( b'a' ) | LitKind :: Char ( 'a' ) ) ,
107
+ Ok ( LitKind :: Byte ( b'z' ) | LitKind :: Char ( 'z' ) )
108
+ ) | (
109
+ Ok ( LitKind :: Byte ( b'A' ) | LitKind :: Char ( 'A' ) ) ,
110
+ Ok ( LitKind :: Byte ( b'Z' ) | LitKind :: Char ( 'Z' ) ) ,
111
+ ) | (
112
+ Ok ( LitKind :: Byte ( b'0' ) | LitKind :: Char ( '0' ) ) ,
113
+ Ok ( LitKind :: Byte ( b'9' ) | LitKind :: Char ( '9' ) ) ,
114
+ )
91
115
)
92
- )
93
- && !in_external_macro ( cx. sess ( ) , span)
94
- {
95
- span_lint_and_then ( cx, ALMOST_COMPLETE_RANGE , span, "almost complete ascii range" , |diag| {
96
- if let Some ( ( span, sugg) ) = sugg {
97
- diag. span_suggestion ( span, "use an inclusive range" , sugg, Applicability :: MaybeIncorrect ) ;
98
- }
99
- } ) ;
116
+ } ,
117
+ _ => false ,
100
118
}
101
119
}
0 commit comments