@@ -2,7 +2,7 @@ use std::ops::Deref;
2
2
use rustc_front:: hir:: * ;
3
3
use reexport:: * ;
4
4
use syntax:: codemap:: Span ;
5
- use rustc_front:: visit:: FnKind ;
5
+ use rustc_front:: visit:: { Visitor , FnKind } ;
6
6
7
7
use rustc:: lint:: * ;
8
8
use rustc:: middle:: def:: Def :: { DefVariant , DefStruct } ;
@@ -269,97 +269,21 @@ fn path_eq_name(name: Name, path: &Path) -> bool {
269
269
path. segments [ 0 ] . identifier . name == name
270
270
}
271
271
272
- fn contains_self ( name : Name , expr : & Expr ) -> bool {
273
- match expr. node {
274
- // the "self" name itself (maybe)
275
- ExprPath ( _, ref path) => path_eq_name ( name, path) ,
276
- // no subexprs
277
- ExprLit ( _) => false ,
278
- // one subexpr
279
- ExprUnary ( _, ref e) | ExprField ( ref e, _) |
280
- ExprTupField ( ref e, _) | ExprAddrOf ( _, ref e) | ExprBox ( ref e) |
281
- ExprCast ( ref e, _) =>
282
- contains_self ( name, e) ,
283
- // two subexprs
284
- ExprBinary ( _, ref l, ref r) | ExprIndex ( ref l, ref r) |
285
- ExprAssign ( ref l, ref r) | ExprAssignOp ( _, ref l, ref r) |
286
- ExprRepeat ( ref l, ref r) =>
287
- contains_self ( name, l) || contains_self ( name, r) ,
288
- // one optional subexpr
289
- ExprRet ( ref oe) =>
290
- oe. as_ref ( ) . map_or ( false , |ref e| contains_self ( name, e) ) ,
291
- // two optional subexprs
292
- ExprRange ( ref ol, ref or) =>
293
- ol. as_ref ( ) . map_or ( false , |ref e| contains_self ( name, e) ) ||
294
- or. as_ref ( ) . map_or ( false , |ref e| contains_self ( name, e) ) ,
295
- // one subblock
296
- ExprBlock ( ref block) | ExprLoop ( ref block, _) |
297
- ExprClosure ( _, _, ref block) =>
298
- contains_block_self ( name, block) ,
299
- // one vec
300
- ExprMethodCall ( _, _, ref v) | ExprVec ( ref v) | ExprTup ( ref v) =>
301
- v. iter ( ) . any ( |ref a| contains_self ( name, a) ) ,
302
- // one expr, one vec
303
- ExprCall ( ref fun, ref args) =>
304
- contains_self ( name, fun) ||
305
- args. iter ( ) . any ( |ref a| contains_self ( name, a) ) ,
306
- // special ones
307
- ExprIf ( ref cond, ref then, ref otherwise) =>
308
- contains_self ( name, cond) || contains_block_self ( name, then) ||
309
- otherwise. as_ref ( ) . map_or ( false , |ref e| contains_self ( name, e) ) ,
310
- ExprWhile ( ref e, ref block, _) =>
311
- contains_self ( name, e) || contains_block_self ( name, block) ,
312
- ExprMatch ( ref e, ref arms, _) =>
313
- contains_self ( name, e) ||
314
- arms. iter ( ) . any (
315
- |ref arm|
316
- arm. pats . iter ( ) . any ( |ref pat| contains_pat_self ( name, pat) ) ||
317
- arm. guard . as_ref ( ) . map_or ( false , |ref g| contains_self ( name, g) ) ||
318
- contains_self ( name, & arm. body ) ) ,
319
- ExprStruct ( _, ref fields, ref other) =>
320
- fields. iter ( ) . any ( |ref f| contains_self ( name, & f. expr ) ) ||
321
- other. as_ref ( ) . map_or ( false , |ref e| contains_self ( name, e) ) ,
322
- _ => false ,
323
- }
272
+ struct ContainsSelf {
273
+ name : Name ,
274
+ result : bool
324
275
}
325
276
326
- fn contains_block_self ( name : Name , block : & Block ) -> bool {
327
- for stmt in & block. stmts {
328
- match stmt. node {
329
- StmtDecl ( ref decl, _) =>
330
- if let DeclLocal ( ref local) = decl. node {
331
- //TODO: We don't currently handle the case where the name
332
- //is shadowed wiithin the block; this means code including this
333
- //degenerate pattern will get the wrong warning.
334
- if let Some ( ref init) = local. init {
335
- if contains_self ( name, init) { return true ; }
336
- }
337
- } ,
338
- StmtExpr ( ref e, _) | StmtSemi ( ref e, _) =>
339
- if contains_self ( name, e) { return true }
277
+ impl < ' v > Visitor < ' v > for ContainsSelf {
278
+ fn visit_name ( & mut self , _: Span , name : Name ) {
279
+ if self . name == name {
280
+ self . result = true ;
340
281
}
341
282
}
342
- if let Some ( ref e) = block. expr { contains_self ( name, e) } else { false }
343
283
}
344
284
345
- fn contains_pat_self ( name : Name , pat : & Pat ) -> bool {
346
- match pat. node {
347
- PatIdent ( _, ref ident, ref inner) => name == ident. node . name ||
348
- inner. as_ref ( ) . map_or ( false , |ref p| contains_pat_self ( name, p) ) ,
349
- PatEnum ( _, ref opats) => opats. as_ref ( ) . map_or ( false ,
350
- |pats| pats. iter ( ) . any ( |p| contains_pat_self ( name, p) ) ) ,
351
- PatQPath ( _, ref path) => path_eq_name ( name, path) ,
352
- PatStruct ( _, ref fieldpats, _) => fieldpats. iter ( ) . any (
353
- |ref fp| contains_pat_self ( name, & fp. node . pat ) ) ,
354
- PatTup ( ref ps) => ps. iter ( ) . any ( |ref p| contains_pat_self ( name, p) ) ,
355
- PatBox ( ref p) |
356
- PatRegion ( ref p, _) => contains_pat_self ( name, p) ,
357
- PatRange ( ref from, ref until) =>
358
- contains_self ( name, from) || contains_self ( name, until) ,
359
- PatVec ( ref pre, ref opt, ref post) =>
360
- pre. iter ( ) . any ( |ref p| contains_pat_self ( name, p) ) ||
361
- opt. as_ref ( ) . map_or ( false , |ref p| contains_pat_self ( name, p) ) ||
362
- post. iter ( ) . any ( |ref p| contains_pat_self ( name, p) ) ,
363
- _ => false ,
364
- }
285
+ fn contains_self ( name : Name , expr : & Expr ) -> bool {
286
+ let mut cs = ContainsSelf { name : name, result : false } ;
287
+ cs. visit_expr ( expr) ;
288
+ cs. result
365
289
}
0 commit comments