{"action":"created","comment":{"url":"https://api.github.com/repos/Manishearth/rust-clippy/pulls/comments/37844064","id":37844064,"diff_hunk":"@@ -0,0 +1,224 @@\n+use syntax::ast::*;\n+use syntax::codemap::Span;\n+use syntax::visit::FnKind;\n+\n+use rustc::lint::{Context, LintArray, LintPass};\n+use utils::{in_external_macro, snippet, span_lint};\n+\n+declare_lint!(pub SHADOW_SAME, Allow,\n+    \"rebinding a name to itself, e.g. `let mut x = &mut x`\");\n+declare_lint!(pub SHADOW_REUSE, Allow,\n+    \"rebinding a name to an expression that re-uses the original value, e.g. \\\n+    `let x = x + 1`\");\n+declare_lint!(pub SHADOW_FOREIGN, Warn,\n+    \"The name is re-bound without even using the original value\");\n+\n+#[derive(Copy, Clone)]\n+pub struct ShadowPass;\n+\n+impl LintPass for ShadowPass {\n+    fn get_lints(&self) -> LintArray {\n+        lint_array!(SHADOW_SAME, SHADOW_REUSE, SHADOW_FOREIGN)\n+    }\n+\n+    fn check_fn(&mut self, cx: &Context, _: FnKind, decl: &FnDecl,\n+            block: &Block, _: Span, _: NodeId) {\n+        if in_external_macro(cx, block.span) { return; }\n+        check_fn(cx, decl, block);\n+    }\n+}\n+\n+fn check_fn(cx: &Context, decl: &FnDecl, block: &Block) {\n+    let mut bindings = Vec::new();\n+    for arg in &decl.inputs {\n+        if let PatIdent(_, ident, _) = arg.pat.node {\n+            bindings.push(ident.node.name)\n+        }\n+    }\n+    check_block(cx, block, &mut bindings);\n+}\n+\n+fn named(pat: &Pat) -> Option<Name> {\n+    if let PatIdent(_, ident, _) = pat.node {\n+       Some(ident.node.name)\n+    } else { None }\n+}\n+\n+fn add(bindings: &mut Vec<Name>, pat: &Pat) {\n+    named(pat).map(|name| bindings.push(name));\n+}\n+\n+fn check_block(cx: &Context, block: &Block, bindings: &mut Vec<Name>) {\n+    let len = bindings.len();\n+    for stmt in &block.stmts {\n+        match stmt.node {\n+            StmtDecl(ref decl, _) => check_decl(cx, decl, bindings),\n+            StmtExpr(ref e, _) | StmtSemi(ref e, _) =>\n+                check_expr(cx, e, bindings),\n+            _ => ()\n+        }\n+    }\n+    if let Some(ref o) = block.expr { check_expr(cx, o, bindings); }\n+    bindings.truncate(len);\n+}\n+\n+fn check_decl(cx: &Context, decl: &Decl, bindings: &mut Vec<Name>) {\n+    if in_external_macro(cx, decl.span) { return; }\n+    if let DeclLocal(ref local) = decl.node {\n+        let Local{ ref pat, ref ty, ref init, id: _, span: _ } = **local;\n+        if let &Some(ref t) = ty { check_ty(cx, t, bindings); }\n+        named(pat).map(|name| if bindings.contains(&name) {\n+            if let &Some(ref o) = init {\n+                if in_external_macro(cx, o.span) { return; }\n+                check_expr(cx, o, bindings);\n+                bindings.push(name);\n+                lint_shadow(cx, name, decl.span, pat.span, o);\n+            }\n+        });\n+        add(bindings, pat);\n+        if let &Some(ref o) = init {\n+            check_expr(cx, o, bindings)\n+        }\n+    }\n+}\n+\n+fn lint_shadow(cx: &Context, name: Name, span: Span, lspan: Span, init: &Expr) {\n+    if is_self_shadow(name, init) {\n+        span_lint(cx, SHADOW_SAME, span, &format!(\n+            \"{} is shadowed by itself in {}\",\n+            snippet(cx, lspan, \"_\"),\n+            snippet(cx, init.span, \"..\")));\n+    } else {\n+        if contains_self(name, init) {\n+            span_lint(cx, SHADOW_REUSE, span, &format!(\n+                \"{} is shadowed by {} which reuses the original value\",\n+                snippet(cx, lspan, \"_\"),\n+                snippet(cx, init.span, \"..\")));\n+        } else {\n+            span_lint(cx, SHADOW_FOREIGN, span, &format!(\n+                \"{} is shadowed by {} in this declaration\",\n+                snippet(cx, lspan, \"_\"),\n+                snippet(cx, init.span, \"..\")));\n+        }\n+    }\n+}\n+\n+fn check_expr(cx: &Context, expr: &Expr, bindings: &mut Vec<Name>) {\n+    if in_external_macro(cx, expr.span) { return; }\n+    match expr.node {\n+        ExprUnary(_, ref e) | ExprParen(ref e) | ExprField(ref e, _) |\n+        ExprTupField(ref e, _) | ExprAddrOf(_, ref e) | ExprBox(None, ref e)\n+            => { check_expr(cx, e, bindings) },\n+        ExprBox(Some(ref place), ref e) => {\n+            check_expr(cx, place, bindings); check_expr(cx, e, bindings) }\n+        ExprBlock(ref block) | ExprLoop(ref block, _) =>\n+            { check_block(cx, block, bindings) },\n+        ExprVec(ref v) | ExprTup(ref v) =>\n+            for ref e in v { check_expr(cx, e, bindings) },\n+        ExprIf(ref cond, ref then, ref otherwise) => {\n+            check_expr(cx, cond, bindings);\n+            check_block(cx, then, bindings);\n+            if let &Some(ref o) = otherwise { check_expr(cx, o, bindings); }\n+        },\n+        ExprIfLet(ref pat, ref e, ref block, ref otherwise) => {\n+            check_expr(cx, e, bindings);\n+            let len = bindings.len();\n+            add(bindings, pat);","path":"src/shadow.rs","position":126,"original_position":126,"commit_id":"209e6981a3ec67ddc8d94cb46d876550948f6238","original_commit_id":"017b976769d1de25d0c366e7e2ae1026c74908d3","user":{"login":"Manishearth","id":1617736,"avatar_url":"https://avatars.githubusercontent.com/u/1617736?v=3","gravatar_id":"","url":"https://api.github.com/users/Manishearth","html_url":"https://github.com/Manishearth","followers_url":"https://api.github.com/users/Manishearth/followers","following_url":"https://api.github.com/users/Manishearth/following{/other_user}","gists_url":"https://api.github.com/users/Manishearth/gists{/gist_id}","starred_url":"https://api.github.com/users/Manishearth/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Manishearth/subscriptions","organizations_url":"https://api.github.com/users/Manishearth/orgs","repos_url":"https://api.github.com/users/Manishearth/repos","events_url":"https://api.github.com/users/Manishearth/events{/privacy}","received_events_url":"https://api.github.com/users/Manishearth/received_events","type":"User","site_admin":false},"body":"Expriflet shouldn't exist at this stage anyway. But yeah, we should add pats from exprmatch","created_at":"2015-08-25T08:37:30Z","updated_at":"2015-08-25T08:37:30Z","html_url":"https://github.com/Manishearth/rust-clippy/pull/224#discussion_r37844064","pull_request_url":"https://api.github.com/repos/Manishearth/rust-clippy/pulls/224","_links":{"self":{"href":"https://api.github.com/repos/Manishearth/rust-clippy/pulls/comments/37844064"},"html":{"href":"https://github.com/Manishearth/rust-clippy/pull/224#discussion_r37844064"},"pull_request":{"href":"https://api.github.com/repos/Manishearth/rust-clippy/pulls/224"}}},"pull_request":{"url":"https://api.github.com/repos/Manishearth/rust-clippy/pulls/224","id":43149963,"html_url":"https://github.com/Manishearth/rust-clippy/pull/224","diff_url":"https://github.com/Manishearth/rust-clippy/pull/224.diff","patch_url":"https://github.com/Manishearth/rust-clippy/pull/224.patch","issue_url":"https://api.github.com/repos/Manishearth/rust-clippy/issues/224","number":224,"state":"open","locked":false,"title":"Name Shadowing Lint","user":{"login":"llogiq","id":4200835,"avatar_url":"https://avatars.githubusercontent.com/u/4200835?v=3","gravatar_id":"","url":"https://api.github.com/users/llogiq","html_url":"https://github.com/llogiq","followers_url":"https://api.github.com/users/llogiq/followers","following_url":"https://api.github.com/users/llogiq/following{/other_user}","gists_url":"https://api.github.com/users/llogiq/gists{/gist_id}","starred_url":"https://api.github.com/users/llogiq/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/llogiq/subscriptions","organizations_url":"https://api.github.com/users/llogiq/orgs","repos_url":"https://api.github.com/users/llogiq/repos","events_url":"https://api.github.com/users/llogiq/events{/privacy}","received_events_url":"https://api.github.com/users/llogiq/received_events","type":"User","site_admin":false},"body":"This closes #83.\r\n\r\nAlso I got rid of all spurious warnings while compiling `regex_macros`. I didn't even need to make the macro check more strict. I'd sure like to see what it finds on servo :smile:","created_at":"2015-08-24T08:18:32Z","updated_at":"2015-08-25T08:37:30Z","closed_at":null,"merged_at":null,"merge_commit_sha":"571bc9cb4eac38e7cd0972e43aedae751163f914","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/Manishearth/rust-clippy/pulls/224/commits","review_comments_url":"https://api.github.com/repos/Manishearth/rust-clippy/pulls/224/comments","review_comment_url":"https://api.github.com/repos/Manishearth/rust-clippy/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Manishearth/rust-clippy/issues/224/comments","statuses_url":"https://api.github.com/repos/Manishearth/rust-clippy/statuses/209e6981a3ec67ddc8d94cb46d876550948f6238","head":{"label":"Manishearth:shadow","ref":"shadow","sha":"209e6981a3ec67ddc8d94cb46d876550948f6238","user":{"login":"Manishearth","id":1617736,"avatar_url":"https://avatars.githubusercontent.com/u/1617736?v=3","gravatar_id":"","url":"https://api.github.com/users/Manishearth","html_url":"https://github.com/Manishearth","followers_url":"https://api.github.com/users/Manishearth/followers","following_url":"https://api.github.com/users/Manishearth/following{/other_user}","gists_url":"https://api.github.com/users/Manishearth/gists{/gist_id}","starred_url":"https://api.github.com/users/Manishearth/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Manishearth/subscriptions","organizations_url":"https://api.github.com/users/Manishearth/orgs","repos_url":"https://api.github.com/users/Manishearth/repos","events_url":"https://api.github.com/users/Manishearth/events{/privacy}","received_events_url":"https://api.github.com/users/Manishearth/received_events","type":"User","site_admin":false},"repo":{"id":26850443,"name":"rust-clippy","full_name":"Manishearth/rust-clippy","owner":{"login":"Manishearth","id":1617736,"avatar_url":"https://avatars.githubusercontent.com/u/1617736?v=3","gravatar_id":"","url":"https://api.github.com/users/Manishearth","html_url":"https://github.com/Manishearth","followers_url":"https://api.github.com/users/Manishearth/followers","following_url":"https://api.github.com/users/Manishearth/following{/other_user}","gists_url":"https://api.github.com/users/Manishearth/gists{/gist_id}","starred_url":"https://api.github.com/users/Manishearth/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Manishearth/subscriptions","organizations_url":"https://api.github.com/users/Manishearth/orgs","repos_url":"https://api.github.com/users/Manishearth/repos","events_url":"https://api.github.com/users/Manishearth/events{/privacy}","received_events_url":"https://api.github.com/users/Manishearth/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Manishearth/rust-clippy","description":"A bunch of lints to help avoid newbie pitfalls.","fork":false,"url":"https://api.github.com/repos/Manishearth/rust-clippy","forks_url":"https://api.github.com/repos/Manishearth/rust-clippy/forks","keys_url":"https://api.github.com/repos/Manishearth/rust-clippy/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Manishearth/rust-clippy/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Manishearth/rust-clippy/teams","hooks_url":"https://api.github.com/repos/Manishearth/rust-clippy/hooks","issue_events_url":"https://api.github.com/repos/Manishearth/rust-clippy/issues/events{/number}","events_url":"https://api.github.com/repos/Manishearth/rust-clippy/events","assignees_url":"https://api.github.com/repos/Manishearth/rust-clippy/assignees{/user}","branches_url":"https://api.github.com/repos/Manishearth/rust-clippy/branches{/branch}","tags_url":"https://api.github.com/repos/Manishearth/rust-clippy/tags","blobs_url":"https://api.github.com/repos/Manishearth/rust-clippy/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Manishearth/rust-clippy/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Manishearth/rust-clippy/git/refs{/sha}","trees_url":"https://api.github.com/repos/Manishearth/rust-clippy/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Manishearth/rust-clippy/statuses/{sha}","languages_url":"https://api.github.com/repos/Manishearth/rust-clippy/languages","stargazers_url":"https://api.github.com/repos/Manishearth/rust-clippy/stargazers","contributors_url":"https://api.github.com/repos/Manishearth/rust-clippy/contributors","subscribers_url":"https://api.github.com/repos/Manishearth/rust-clippy/subscribers","subscription_url":"https://api.github.com/repos/Manishearth/rust-clippy/subscription","commits_url":"https://api.github.com/repos/Manishearth/rust-clippy/commits{/sha}","git_commits_url":"https://api.github.com/repos/Manishearth/rust-clippy/git/commits{/sha}","comments_url":"https://api.github.com/repos/Manishearth/rust-clippy/comments{/number}","issue_comment_url":"https://api.github.com/repos/Manishearth/rust-clippy/issues/comments{/number}","contents_url":"https://api.github.com/repos/Manishearth/rust-clippy/contents/{+path}","compare_url":"https://api.github.com/repos/Manishearth/rust-clippy/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Manishearth/rust-clippy/merges","archive_url":"https://api.github.com/repos/Manishearth/rust-clippy/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Manishearth/rust-clippy/downloads","issues_url":"https://api.github.com/repos/Manishearth/rust-clippy/issues{/number}","pulls_url":"https://api.github.com/repos/Manishearth/rust-clippy/pulls{/number}","milestones_url":"https://api.github.com/repos/Manishearth/rust-clippy/milestones{/number}","notifications_url":"https://api.github.com/repos/Manishearth/rust-clippy/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Manishearth/rust-clippy/labels{/name}","releases_url":"https://api.github.com/repos/Manishearth/rust-clippy/releases{/id}","created_at":"2014-11-19T07:49:21Z","updated_at":"2015-08-24T14:40:09Z","pushed_at":"2015-08-24T16:42:56Z","git_url":"git://github.com/Manishearth/rust-clippy.git","ssh_url":"git@github.com:Manishearth/rust-clippy.git","clone_url":"https://github.com/Manishearth/rust-clippy.git","svn_url":"https://github.com/Manishearth/rust-clippy","homepage":"","size":2465,"stargazers_count":210,"watchers_count":210,"language":"Rust","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":25,"mirror_url":null,"open_issues_count":44,"forks":25,"open_issues":44,"watchers":210,"default_branch":"master"}},"base":{"label":"Manishearth:master","ref":"master","sha":"802d56c46c9879da9a45f936b3b5160967e04381","user":{"login":"Manishearth","id":1617736,"avatar_url":"https://avatars.githubusercontent.com/u/1617736?v=3","gravatar_id":"","url":"https://api.github.com/users/Manishearth","html_url":"https://github.com/Manishearth","followers_url":"https://api.github.com/users/Manishearth/followers","following_url":"https://api.github.com/users/Manishearth/following{/other_user}","gists_url":"https://api.github.com/users/Manishearth/gists{/gist_id}","starred_url":"https://api.github.com/users/Manishearth/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Manishearth/subscriptions","organizations_url":"https://api.github.com/users/Manishearth/orgs","repos_url":"https://api.github.com/users/Manishearth/repos","events_url":"https://api.github.com/users/Manishearth/events{/privacy}","received_events_url":"https://api.github.com/users/Manishearth/received_events","type":"User","site_admin":false},"repo":{"id":26850443,"name":"rust-clippy","full_name":"Manishearth/rust-clippy","owner":{"login":"Manishearth","id":1617736,"avatar_url":"https://avatars.githubusercontent.com/u/1617736?v=3","gravatar_id":"","url":"https://api.github.com/users/Manishearth","html_url":"https://github.com/Manishearth","followers_url":"https://api.github.com/users/Manishearth/followers","following_url":"https://api.github.com/users/Manishearth/following{/other_user}","gists_url":"https://api.github.com/users/Manishearth/gists{/gist_id}","starred_url":"https://api.github.com/users/Manishearth/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Manishearth/subscriptions","organizations_url":"https://api.github.com/users/Manishearth/orgs","repos_url":"https://api.github.com/users/Manishearth/repos","events_url":"https://api.github.com/users/Manishearth/events{/privacy}","received_events_url":"https://api.github.com/users/Manishearth/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Manishearth/rust-clippy","description":"A bunch of lints to help avoid newbie pitfalls.","fork":false,"url":"https://api.github.com/repos/Manishearth/rust-clippy","forks_url":"https://api.github.com/repos/Manishearth/rust-clippy/forks","keys_url":"https://api.github.com/repos/Manishearth/rust-clippy/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Manishearth/rust-clippy/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Manishearth/rust-clippy/teams","hooks_url":"https://api.github.com/repos/Manishearth/rust-clippy/hooks","issue_events_url":"https://api.github.com/repos/Manishearth/rust-clippy/issues/events{/number}","events_url":"https://api.github.com/repos/Manishearth/rust-clippy/events","assignees_url":"https://api.github.com/repos/Manishearth/rust-clippy/assignees{/user}","branches_url":"https://api.github.com/repos/Manishearth/rust-clippy/branches{/branch}","tags_url":"https://api.github.com/repos/Manishearth/rust-clippy/tags","blobs_url":"https://api.github.com/repos/Manishearth/rust-clippy/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Manishearth/rust-clippy/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Manishearth/rust-clippy/git/refs{/sha}","trees_url":"https://api.github.com/repos/Manishearth/rust-clippy/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Manishearth/rust-clippy/statuses/{sha}","languages_url":"https://api.github.com/repos/Manishearth/rust-clippy/languages","stargazers_url":"https://api.github.com/repos/Manishearth/rust-clippy/stargazers","contributors_url":"https://api.github.com/repos/Manishearth/rust-clippy/contributors","subscribers_url":"https://api.github.com/repos/Manishearth/rust-clippy/subscribers","subscription_url":"https://api.github.com/repos/Manishearth/rust-clippy/subscription","commits_url":"https://api.github.com/repos/Manishearth/rust-clippy/commits{/sha}","git_commits_url":"https://api.github.com/repos/Manishearth/rust-clippy/git/commits{/sha}","comments_url":"https://api.github.com/repos/Manishearth/rust-clippy/comments{/number}","issue_comment_url":"https://api.github.com/repos/Manishearth/rust-clippy/issues/comments{/number}","contents_url":"https://api.github.com/repos/Manishearth/rust-clippy/contents/{+path}","compare_url":"https://api.github.com/repos/Manishearth/rust-clippy/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Manishearth/rust-clippy/merges","archive_url":"https://api.github.com/repos/Manishearth/rust-clippy/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Manishearth/rust-clippy/downloads","issues_url":"https://api.github.com/repos/Manishearth/rust-clippy/issues{/number}","pulls_url":"https://api.github.com/repos/Manishearth/rust-clippy/pulls{/number}","milestones_url":"https://api.github.com/repos/Manishearth/rust-clippy/milestones{/number}","notifications_url":"https://api.github.com/repos/Manishearth/rust-clippy/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Manishearth/rust-clippy/labels{/name}","releases_url":"https://api.github.com/repos/Manishearth/rust-clippy/releases{/id}","created_at":"2014-11-19T07:49:21Z","updated_at":"2015-08-24T14:40:09Z","pushed_at":"2015-08-24T16:42:56Z","git_url":"git://github.com/Manishearth/rust-clippy.git","ssh_url":"git@github.com:Manishearth/rust-clippy.git","clone_url":"https://github.com/Manishearth/rust-clippy.git","svn_url":"https://github.com/Manishearth/rust-clippy","homepage":"","size":2465,"stargazers_count":210,"watchers_count":210,"language":"Rust","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":25,"mirror_url":null,"open_issues_count":44,"forks":25,"open_issues":44,"watchers":210,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/Manishearth/rust-clippy/pulls/224"},"html":{"href":"https://github.com/Manishearth/rust-clippy/pull/224"},"issue":{"href":"https://api.github.com/repos/Manishearth/rust-clippy/issues/224"},"comments":{"href":"https://api.github.com/repos/Manishearth/rust-clippy/issues/224/comments"},"review_comments":{"href":"https://api.github.com/repos/Manishearth/rust-clippy/pulls/224/comments"},"review_comment":{"href":"https://api.github.com/repos/Manishearth/rust-clippy/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Manishearth/rust-clippy/pulls/224/commits"},"statuses":{"href":"https://api.github.com/repos/Manishearth/rust-clippy/statuses/209e6981a3ec67ddc8d94cb46d876550948f6238"}}}}