Created
November 9, 2014 01:33
-
-
Save mrhota/d11ade4db40b911e7dcf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![forbid(shadowed_name)] | |
#![allow(unused_variables)] | |
pub fn main() { | |
let foo = 0i; | |
{ | |
let foo = Some(2.0f64); //~ ERROR foo is shadowed | |
} | |
} | |
// $> rustc src/test/compile-fail/lint-simple-shadow.rs | |
// src/test/compile-fail/lint-simple-shadow.rs:17:13: 17:16 error: foo is shadowed | |
// src/test/compile-fail/lint-simple-shadow.rs:17 let foo = Some(2.0f64); //~ ERROR foo is shadowed | |
// ^~~ | |
// src/test/compile-fail/lint-simple-shadow.rs:11:11: 11:24 note: lint level defined here | |
// src/test/compile-fail/lint-simple-shadow.rs:11 #![forbid(shadowed_name)] | |
// ^~~~~~~~~~~~~ | |
// src/test/compile-fail/lint-simple-shadow.rs:15:9: 15:12 note: foo shadowed here | |
// src/test/compile-fail/lint-simple-shadow.rs:15 let foo = 0i; | |
// -------- | |
declare_lint!(pub SHADOWED_NAME, Allow, | |
"detects declarations which shadow names from enclosing scopes") | |
pub struct ShadowedName { | |
shadowed_names: HashMap<ast::Name, ast::NodeId>, | |
} | |
impl ShadowedName { | |
pub fn new() -> ShadowedName { | |
ShadowedName { | |
shadowed_names: HashMap::new(), | |
} | |
} | |
} | |
impl LintPass for ShadowedName { | |
fn get_lints(&self) -> LintArray { | |
lint_array!(SHADOWED_NAME) | |
} | |
fn check_pat(&mut self, cx: &Context, p: &ast::Pat) { | |
match p.node { | |
ast::PatIdent(_, spannedident, _) => { | |
let name = spannedident.node.name; | |
match self.shadowed_names.entry(name) { | |
Vacant(entry) => { | |
entry.set(p.id); | |
}, | |
Occupied(entry) => { | |
// name is potentially shadowing something! | |
let ref rmap = cx.tcx.region_maps; | |
let &origid = entry.get(); | |
let origscope = match rmap.opt_encl_scope(origid) { | |
Some(s) => s, | |
None => return | |
}; | |
let thisscope = match rmap.opt_encl_scope(p.id) { | |
Some(s) => s, | |
None => return | |
}; | |
if origscope != thisscope { | |
let lvl = cx.current_level(SHADOWED_NAME); | |
if rmap.is_subscope_of(thisscope, origscope) { | |
cx.span_lint(SHADOWED_NAME, cx.tcx.map.span(origid), | |
format!("{} is shadowed", | |
token::get_name(name)).as_slice()); | |
if lvl > lint::Allow { | |
span_note!(cx.sess(), p.span, "{} shadowed here", | |
token::get_name(name)); | |
} | |
} else { | |
cx.span_lint(SHADOWED_NAME, p.span, | |
format!("{} is shadowed", | |
token::get_name(name)).as_slice()); | |
if lvl > lint::Allow { | |
span_note!(cx.sess(), cx.tcx.map.span(origid), | |
"{} shadowed here", | |
token::get_name(name)); | |
} | |
} | |
} else { | |
println!("{} scope was weird", name); | |
println!("origscope: {}", origscope); | |
println!("thisscope: {}", thisscope); | |
} | |
}, | |
} | |
}, | |
_ => {}, | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment