refactoring and bugfix

This commit is contained in:
Oliver Schneider 2016-03-08 14:36:21 +01:00
parent 463897fd39
commit 077481053c
4 changed files with 74 additions and 37 deletions

View file

@ -14,7 +14,7 @@ Table of contents:
* [License](#license)
##Lints
There are 136 lints included in this crate:
There are 138 lints included in this crate:
name | default | meaning
---------------------------------------------------------------------------------------------------------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

View file

@ -76,13 +76,23 @@ impl<'a, 'b, 'c> SimilarNamesNameVisitor<'a, 'b, 'c> {
}
let count = interned_name.chars().count();
if count < 3 {
if count == 1 {
let c = interned_name.chars().next().expect("already checked");
// make sure we ignore shadowing
if !self.0.single_char_names.contains(&c) {
self.0.single_char_names.push(c);
}
if count != 1 {
return;
}
let c = interned_name.chars().next().expect("already checked");
// make sure we ignore shadowing
if self.0.single_char_names.contains(&c) {
return;
}
self.0.single_char_names.push(c);
if self.0.single_char_names.len() < self.0.lint.max_single_char_names {
return;
}
span_lint(self.0.cx,
MANY_SINGLE_CHAR_NAMES,
span,
&format!("{}th binding whose name is just one char",
self.0.single_char_names.len()));
return;
}
for &allow in WHITELIST {
@ -157,39 +167,33 @@ impl<'a, 'b, 'c> SimilarNamesNameVisitor<'a, 'b, 'c> {
}
impl<'a, 'b> SimilarNamesLocalVisitor<'a, 'b> {
fn check_single_char_count(&self, span: Span) {
if self.single_char_names.len() < self.lint.max_single_char_names {
return;
}
span_lint(self.cx,
MANY_SINGLE_CHAR_NAMES,
span,
&format!("scope contains {} bindings whose name are just one char",
self.single_char_names.len()));
/// ensure scoping rules work
fn apply<F: for<'c> Fn(&'c mut Self)>(&mut self, f: F) {
let n = self.names.len();
let single_char_count = self.single_char_names.len();
f(self);
self.names.truncate(n);
self.single_char_names.truncate(single_char_count);
}
}
impl<'v, 'a, 'b> visit::Visitor<'v> for SimilarNamesLocalVisitor<'a, 'b> {
fn visit_local(&mut self, local: &'v Local) {
SimilarNamesNameVisitor(self).visit_local(local)
if let Some(ref init) = local.init {
self.apply(|this| visit::walk_expr(this, &**init));
}
// add the pattern after the expression because the bindings aren't available yet in the init expression
SimilarNamesNameVisitor(self).visit_pat(&*local.pat);
}
fn visit_block(&mut self, blk: &'v Block) {
// ensure scoping rules work
let n = self.names.len();
let single_char_count = self.single_char_names.len();
visit::walk_block(self, blk);
self.names.truncate(n);
self.check_single_char_count(blk.span);
self.single_char_names.truncate(single_char_count);
self.apply(|this| visit::walk_block(this, blk));
}
fn visit_arm(&mut self, arm: &'v Arm) {
let n = self.names.len();
let single_char_count = self.single_char_names.len();
// just go through the first pattern, as either all patterns bind the same bindings or rustc would have errored much earlier
SimilarNamesNameVisitor(self).visit_pat(&arm.pats[0]);
self.names.truncate(n);
self.check_single_char_count(arm.body.span);
self.single_char_names.truncate(single_char_count);
self.apply(|this| {
// just go through the first pattern, as either all patterns bind the same bindings or rustc would have errored much earlier
SimilarNamesNameVisitor(this).visit_pat(&arm.pats[0]);
this.apply(|this| visit::walk_expr(this, &arm.body));
});
}
fn visit_item(&mut self, _: &'v Item) {
// do nothing

View file

@ -34,8 +34,40 @@ fn main() {
let cake: i32; //~ NOTE: existing binding defined here
let cakes: i32;
let coke: i32; //~ ERROR: name is too similar
match 5 {
cheese @ 1 => {},
rabbit => panic!(),
}
let cheese: i32;
match (42, 43) {
(cheese1, 1) => {},
(cheese2, 2) => panic!(),
_ => println!(""),
}
}
#[derive(Clone, Debug)]
enum MaybeInst {
Split,
Split1(usize),
Split2(usize),
}
struct InstSplit {
uiae: usize,
}
impl MaybeInst {
fn fill(&mut self) {
let filled = match *self {
MaybeInst::Split1(goto1) => panic!(1),
MaybeInst::Split2(goto2) => panic!(2),
_ => unimplemented!(),
};
unimplemented!()
}
}
fn bla() {
let a: i32;
@ -45,16 +77,16 @@ fn bla() {
let cdefg: i32;
let blar: i32;
}
{ //~ ERROR: scope contains 5 bindings whose name are just one char
let e: i32;
{
let e: i32; //~ ERROR: 5th binding whose name is just one char
}
{ //~ ERROR: scope contains 6 bindings whose name are just one char
let e: i32;
let f: i32;
{
let e: i32; //~ ERROR: 5th binding whose name is just one char
let f: i32; //~ ERROR: 6th binding whose name is just one char
}
match 5 {
1 => println!(""),
e => panic!(), //~ ERROR: scope contains 5 bindings whose name are just one char
e => panic!(), //~ ERROR: 5th binding whose name is just one char
}
match 5 {
1 => println!(""),

View file

@ -1,6 +1,7 @@
#![feature(plugin)]
#![plugin(clippy)]
#![allow(many_single_char_names)]
#![deny(overflow_check_conditional)]
fn main() {