1
- use clippy_utils:: diagnostics:: span_lint_and_help ;
1
+ use clippy_utils:: diagnostics:: span_lint_and_sugg ;
2
2
use clippy_utils:: ty:: is_type_diagnostic_item;
3
3
use rustc_ast:: ast:: LitKind ;
4
+ use rustc_errors:: Applicability ;
4
5
use rustc_hir:: intravisit:: { walk_expr, NestedVisitorMap , Visitor } ;
5
6
use rustc_hir:: { Arm , Expr , ExprKind , MatchSource , PatKind } ;
6
7
use rustc_lint:: { LateContext , LateLintPass } ;
7
8
use rustc_middle:: hir:: map:: Map ;
8
9
use rustc_middle:: lint:: in_external_macro;
9
10
use rustc_middle:: ty;
10
11
use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
12
+ use rustc_span:: symbol:: SymbolStr ;
11
13
use rustc_span:: { sym, Span } ;
12
14
13
15
declare_clippy_lint ! {
@@ -18,15 +20,19 @@ declare_clippy_lint! {
18
20
/// The arm is unreachable, which is likely a mistake
19
21
///
20
22
/// ### Example
21
- /// ```rust,no_run
23
+ /// ```rust
24
+ /// # let text = "Foo";
25
+ ///
22
26
/// match &*text.to_ascii_lowercase() {
23
27
/// "foo" => {},
24
28
/// "Bar" => {},
25
29
/// _ => {},
26
30
/// }
27
31
/// ```
28
32
/// Use instead:
29
- /// ```rust,no_run
33
+ /// ```rust
34
+ /// # let text = "Foo";
35
+ ///
30
36
/// match &*text.to_ascii_lowercase() {
31
37
/// "foo" => {},
32
38
/// "bar" => {},
@@ -64,8 +70,8 @@ impl LateLintPass<'_> for MatchStrCaseMismatch {
64
70
visitor. visit_expr( match_expr) ;
65
71
66
72
if let Some ( case_method) = visitor. case_method {
67
- if let Some ( bad_case ) = verify_case( & case_method, arms) {
68
- lint( cx, expr . span , & case_method, bad_case ) ;
73
+ if let Some ( ( bad_case_span , bad_case_str ) ) = verify_case( & case_method, arms) {
74
+ lint( cx, & case_method, bad_case_span , & bad_case_str ) ;
69
75
}
70
76
}
71
77
}
@@ -119,9 +125,7 @@ fn get_case_method(segment_ident_str: &str) -> Option<CaseMethod> {
119
125
}
120
126
}
121
127
122
- fn verify_case ( case_method : & CaseMethod , arms : & ' _ [ Arm < ' _ > ] ) -> Option < Span > {
123
- let mut bad_case = None ;
124
-
128
+ fn verify_case < ' a > ( case_method : & ' a CaseMethod , arms : & ' a [ Arm < ' _ > ] ) -> Option < ( Span , SymbolStr ) > {
125
129
let case_check = match case_method {
126
130
CaseMethod :: LowerCase => |input : & str | -> bool { input. chars ( ) . all ( char:: is_lowercase) } ,
127
131
CaseMethod :: AsciiLowerCase => |input : & str | -> bool { input. chars ( ) . all ( |c| matches ! ( c, 'a' ..='z' ) ) } ,
@@ -136,31 +140,32 @@ fn verify_case(case_method: &CaseMethod, arms: &'_ [Arm<'_>]) -> Option<Span> {
136
140
..
137
141
} ) = arm. pat. kind;
138
142
if let LitKind :: Str ( symbol, _) = lit. node;
139
- if !case_check( & symbol. as_str( ) ) ;
143
+ let input = symbol. as_str( ) ;
144
+ if !case_check( & input) ;
140
145
then {
141
- bad_case = Some ( lit. span) ;
142
- break ;
146
+ return Some ( ( lit. span, input) ) ;
143
147
}
144
148
}
145
149
}
146
150
147
- bad_case
151
+ None
148
152
}
149
153
150
- fn lint ( cx : & LateContext < ' _ > , expr_span : Span , case_method : & CaseMethod , bad_case_span : Span ) {
151
- let method_str = match case_method {
152
- CaseMethod :: LowerCase => "to_lower_case" ,
153
- CaseMethod :: AsciiLowerCase => "to_ascii_lowercase" ,
154
- CaseMethod :: UpperCase => "to_uppercase" ,
155
- CaseMethod :: AsciiUppercase => "to_ascii_uppercase" ,
154
+ fn lint ( cx : & LateContext < ' _ > , case_method : & CaseMethod , bad_case_span : Span , bad_case_str : & str ) {
155
+ let ( method_str, suggestion ) = match case_method {
156
+ CaseMethod :: LowerCase => ( "to_lower_case" , bad_case_str . to_lowercase ( ) ) ,
157
+ CaseMethod :: AsciiLowerCase => ( "to_ascii_lowercase" , bad_case_str . to_ascii_lowercase ( ) ) ,
158
+ CaseMethod :: UpperCase => ( "to_uppercase" , bad_case_str . to_uppercase ( ) ) ,
159
+ CaseMethod :: AsciiUppercase => ( "to_ascii_uppercase" , bad_case_str . to_ascii_uppercase ( ) ) ,
156
160
} ;
157
161
158
- span_lint_and_help (
162
+ span_lint_and_sugg (
159
163
cx,
160
164
MATCH_STR_CASE_MISMATCH ,
161
- expr_span,
162
- "this `match` expression alters case, but has non-compliant arms" ,
163
- Some ( bad_case_span) ,
165
+ bad_case_span,
166
+ "this `match` arm has a differing case than its expression" ,
164
167
& * format ! ( "consider changing the case of this arm to respect `{}`" , method_str) ,
168
+ format ! ( "\" {}\" " , suggestion) ,
169
+ Applicability :: MachineApplicable ,
165
170
) ;
166
171
}
0 commit comments