Skip to content

Commit d3c53e3

Browse files
committed
Merge pull request rust-lang#285 from Manishearth/contains_self
shadow: complete coverage of "contains_self" checker
2 parents 8edc87e + 7649d1c commit d3c53e3

File tree

1 file changed

+39
-13
lines changed

1 file changed

+39
-13
lines changed

src/shadow.rs

+39-13
Original file line numberDiff line numberDiff line change
@@ -255,29 +255,55 @@ fn path_eq_name(name: Name, path: &Path) -> bool {
255255

256256
fn contains_self(name: Name, expr: &Expr) -> bool {
257257
match expr.node {
258+
// the "self" name itself (maybe)
259+
ExprPath(_, ref path) => path_eq_name(name, path),
260+
// no subexprs
261+
ExprLit(_) => false,
262+
// one subexpr
258263
ExprUnary(_, ref e) | ExprParen(ref e) | ExprField(ref e, _) |
259-
ExprTupField(ref e, _) | ExprAddrOf(_, ref e) | ExprBox(_, ref e)
260-
=> contains_self(name, e),
261-
ExprBinary(_, ref l, ref r) =>
264+
ExprTupField(ref e, _) | ExprAddrOf(_, ref e) | ExprBox(_, ref e) |
265+
ExprCast(ref e, _) =>
266+
contains_self(name, e),
267+
// two subexprs
268+
ExprBinary(_, ref l, ref r) | ExprIndex(ref l, ref r) |
269+
ExprAssign(ref l, ref r) | ExprAssignOp(_, ref l, ref r) |
270+
ExprRepeat(ref l, ref r) =>
262271
contains_self(name, l) || contains_self(name, r),
263-
ExprBlock(ref block) | ExprLoop(ref block, _) =>
272+
// one optional subexpr
273+
ExprRet(ref oe) =>
274+
oe.as_ref().map_or(false, |ref e| contains_self(name, e)),
275+
// two optional subexprs
276+
ExprRange(ref ol, ref or) =>
277+
ol.as_ref().map_or(false, |ref e| contains_self(name, e)) ||
278+
or.as_ref().map_or(false, |ref e| contains_self(name, e)),
279+
// one subblock
280+
ExprBlock(ref block) | ExprLoop(ref block, _) |
281+
ExprClosure(_, _, ref block) =>
264282
contains_block_self(name, block),
265-
ExprCall(ref fun, ref args) => contains_self(name, fun) ||
266-
args.iter().any(|ref a| contains_self(name, a)),
267-
ExprMethodCall(_, _, ref args) =>
283+
// one vec
284+
ExprMethodCall(_, _, ref v) | ExprVec(ref v) | ExprTup(ref v) =>
285+
v.iter().any(|ref a| contains_self(name, a)),
286+
// one expr, one vec
287+
ExprCall(ref fun, ref args) =>
288+
contains_self(name, fun) ||
268289
args.iter().any(|ref a| contains_self(name, a)),
269-
ExprVec(ref v) | ExprTup(ref v) =>
270-
v.iter().any(|ref e| contains_self(name, e)),
290+
// special ones
271291
ExprIf(ref cond, ref then, ref otherwise) =>
272292
contains_self(name, cond) || contains_block_self(name, then) ||
273293
otherwise.as_ref().map_or(false, |ref e| contains_self(name, e)),
274294
ExprWhile(ref e, ref block, _) =>
275295
contains_self(name, e) || contains_block_self(name, block),
276296
ExprMatch(ref e, ref arms, _) =>
277-
arms.iter().any(|ref arm| arm.pats.iter().any(|ref pat|
278-
contains_pat_self(name, pat))) || contains_self(name, e),
279-
ExprPath(_, ref path) => path_eq_name(name, path),
280-
_ => false
297+
contains_self(name, e) ||
298+
arms.iter().any(
299+
|ref arm|
300+
arm.pats.iter().any(|ref pat| contains_pat_self(name, pat)) ||
301+
arm.guard.as_ref().map_or(false, |ref g| contains_self(name, g)) ||
302+
contains_self(name, &arm.body)),
303+
ExprStruct(_, ref fields, ref other) =>
304+
fields.iter().any(|ref f| contains_self(name, &f.expr)) ||
305+
other.as_ref().map_or(false, |ref e| contains_self(name, e)),
306+
_ => false,
281307
}
282308
}
283309

0 commit comments

Comments
 (0)