@@ -9,7 +9,7 @@ use std::error::Error;
9
9
use syntax:: ast:: { LitKind , NodeId } ;
10
10
use syntax:: codemap:: { Span , BytePos } ;
11
11
use syntax:: parse:: token:: InternedString ;
12
- use utils:: { is_expn_of, match_path , match_type, paths, span_lint, span_help_and_lint} ;
12
+ use utils:: { is_expn_of, match_def_path , match_type, paths, span_lint, span_help_and_lint} ;
13
13
14
14
/// **What it does:** This lint checks `Regex::new(_)` invocations for correct regex syntax.
15
15
///
@@ -81,7 +81,7 @@ impl LateLintPass for RegexPass {
81
81
span,
82
82
"`regex!(_)` found. \
83
83
Please use `Regex::new(_)`, which is faster for now.") ;
84
- self . spans. insert( span) ;
84
+ self . spans. insert( span) ;
85
85
}
86
86
self . last = Some ( block. id) ;
87
87
} }
@@ -96,46 +96,22 @@ impl LateLintPass for RegexPass {
96
96
fn check_expr ( & mut self , cx : & LateContext , expr : & Expr ) {
97
97
if_let_chain ! { [
98
98
let ExprCall ( ref fun, ref args) = expr. node,
99
- let ExprPath ( _ , ref path ) = fun . node ,
100
- match_path ( path , & paths :: REGEX_NEW ) && args . len ( ) == 1
99
+ args . len ( ) == 1 ,
100
+ let Some ( def ) = cx . tcx . def_map . borrow ( ) . get ( & fun . id ) ,
101
101
] , {
102
- if let ExprLit ( ref lit) = args[ 0 ] . node {
103
- if let LitKind :: Str ( ref r, _) = lit. node {
104
- match regex_syntax:: Expr :: parse( r) {
105
- Ok ( r) => {
106
- if let Some ( repl) = is_trivial_regex( & r) {
107
- span_help_and_lint( cx, TRIVIAL_REGEX , args[ 0 ] . span,
108
- "trivial regex" ,
109
- & format!( "consider using {}" , repl) ) ;
110
- }
111
- }
112
- Err ( e) => {
113
- span_lint( cx,
114
- INVALID_REGEX ,
115
- str_span( args[ 0 ] . span, & r, e. position( ) ) ,
116
- & format!( "regex syntax error: {}" ,
117
- e. description( ) ) ) ;
118
- }
119
- }
120
- }
121
- } else if let Some ( r) = const_str( cx, & * args[ 0 ] ) {
122
- match regex_syntax:: Expr :: parse( & r) {
123
- Ok ( r) => {
124
- if let Some ( repl) = is_trivial_regex( & r) {
125
- span_help_and_lint( cx, TRIVIAL_REGEX , args[ 0 ] . span,
126
- "trivial regex" ,
127
- & format!( "consider using {}" , repl) ) ;
128
- }
129
- }
130
- Err ( e) => {
131
- span_lint( cx,
132
- INVALID_REGEX ,
133
- args[ 0 ] . span,
134
- & format!( "regex syntax error on position {}: {}" ,
135
- e. position( ) ,
136
- e. description( ) ) ) ;
137
- }
138
- }
102
+ let def_id = def. def_id( ) ;
103
+ if match_def_path( cx, def_id, & paths:: REGEX_NEW ) {
104
+ check_regex( cx, & args[ 0 ] , true ) ;
105
+ } else if match_def_path( cx, def_id, & paths:: REGEX_BYTES_NEW ) {
106
+ check_regex( cx, & args[ 0 ] , false ) ;
107
+ } else if match_def_path( cx, def_id, & paths:: REGEX_BUILDER_NEW ) {
108
+ check_regex( cx, & args[ 0 ] , true ) ;
109
+ } else if match_def_path( cx, def_id, & paths:: REGEX_BYTES_BUILDER_NEW ) {
110
+ check_regex( cx, & args[ 0 ] , false ) ;
111
+ } else if match_def_path( cx, def_id, & paths:: REGEX_SET_NEW ) {
112
+ check_set( cx, & args[ 0 ] , true ) ;
113
+ } else if match_def_path( cx, def_id, & paths:: REGEX_BYTES_SET_NEW ) {
114
+ check_set( cx, & args[ 0 ] , false ) ;
139
115
}
140
116
} }
141
117
}
@@ -193,3 +169,57 @@ fn is_trivial_regex(s: ®ex_syntax::Expr) -> Option<&'static str> {
193
169
_ => None ,
194
170
}
195
171
}
172
+
173
+ fn check_set ( cx : & LateContext , expr : & Expr , utf8 : bool ) {
174
+ if_let_chain ! { [
175
+ let ExprAddrOf ( _, ref expr) = expr. node,
176
+ let ExprVec ( ref exprs) = expr. node,
177
+ ] , {
178
+ for expr in exprs {
179
+ check_regex( cx, expr, utf8) ;
180
+ }
181
+ } }
182
+ }
183
+
184
+ fn check_regex ( cx : & LateContext , expr : & Expr , utf8 : bool ) {
185
+ let builder = regex_syntax:: ExprBuilder :: new ( ) . unicode ( utf8) ;
186
+
187
+ if let ExprLit ( ref lit) = expr. node {
188
+ if let LitKind :: Str ( ref r, _) = lit. node {
189
+ match builder. parse ( r) {
190
+ Ok ( r) => {
191
+ if let Some ( repl) = is_trivial_regex ( & r) {
192
+ span_help_and_lint ( cx, TRIVIAL_REGEX , expr. span ,
193
+ "trivial regex" ,
194
+ & format ! ( "consider using {}" , repl) ) ;
195
+ }
196
+ }
197
+ Err ( e) => {
198
+ span_lint ( cx,
199
+ INVALID_REGEX ,
200
+ str_span ( expr. span , r, e. position ( ) ) ,
201
+ & format ! ( "regex syntax error: {}" ,
202
+ e. description( ) ) ) ;
203
+ }
204
+ }
205
+ }
206
+ } else if let Some ( r) = const_str ( cx, expr) {
207
+ match builder. parse ( & r) {
208
+ Ok ( r) => {
209
+ if let Some ( repl) = is_trivial_regex ( & r) {
210
+ span_help_and_lint ( cx, TRIVIAL_REGEX , expr. span ,
211
+ "trivial regex" ,
212
+ & format ! ( "consider using {}" , repl) ) ;
213
+ }
214
+ }
215
+ Err ( e) => {
216
+ span_lint ( cx,
217
+ INVALID_REGEX ,
218
+ expr. span ,
219
+ & format ! ( "regex syntax error on position {}: {}" ,
220
+ e. position( ) ,
221
+ e. description( ) ) ) ;
222
+ }
223
+ }
224
+ }
225
+ }
0 commit comments