let lit_val: f64 = match lit.node {
ast::LitFloat(ref v, _) |
ast::LitFloatUnsuffixed(ref v) => {
- match v.parse() {
+ match v.parse().ok() {
Some(f) => f,
None => return
}
impl BoxPointers {
fn check_heap_type<'a, 'tcx>(&self, cx: &Context<'a, 'tcx>,
span: Span, ty: Ty<'tcx>) {
- let mut n_uniq = 0i;
+ let mut n_uniq = 0us;
ty::fold_ty(cx.tcx, ty, |t| {
match t.sty {
ty::ty_uniq(_) => {
return
}
let did = match item.node {
- ast::ItemImpl(..) => {
+ ast::ItemImpl(_, _, _, ref t_ref_opt, _, _) => {
+ // Deriving the Copy trait does not cause a warning
+ if let &Some(ref trait_ref) = t_ref_opt {
+ let def_id = ty::trait_ref_to_def_id(cx.tcx, trait_ref);
+ if Some(def_id) == cx.tcx.lang_items.copy_trait() {
+ return
+ }
+ }
+
match ty::node_id_to_type(cx.tcx, item.id).sty {
ty::ty_enum(did, _) => did,
ty::ty_struct(did, _) => did,
pub struct NonSnakeCase;
impl NonSnakeCase {
+ fn to_snake_case(mut str: &str) -> String {
+ let mut words = vec![];
+ // Preserve leading underscores
+ str = str.trim_left_matches(|&mut: c: char| {
+ if c == '_' {
+ words.push(String::new());
+ true
+ } else { false }
+ });
+ for s in str.split('_') {
+ let mut last_upper = false;
+ let mut buf = String::new();
+ if s.is_empty() { continue; }
+ for ch in s.chars() {
+ if !buf.is_empty() && buf != "'"
+ && ch.is_uppercase()
+ && !last_upper {
+ words.push(buf);
+ buf = String::new();
+ }
+ last_upper = ch.is_uppercase();
+ buf.push(ch.to_lowercase());
+ }
+ words.push(buf);
+ }
+ words.connect("_")
+ }
+
fn check_snake_case(&self, cx: &Context, sort: &str, ident: ast::Ident, span: Span) {
fn is_snake_case(ident: ast::Ident) -> bool {
let ident = token::get_ident(ident);
let mut allow_underscore = true;
ident.chars().all(|c| {
allow_underscore = match c {
- c if c.is_lowercase() || c.is_numeric() => true,
- '_' if allow_underscore => false,
+ '_' if !allow_underscore => return false,
+ '_' => false,
+ c if !c.is_uppercase() => true,
_ => return false,
};
true
})
}
- fn to_snake_case(str: &str) -> String {
- let mut words = vec![];
- for s in str.split('_') {
- let mut last_upper = false;
- let mut buf = String::new();
- if s.is_empty() { continue; }
- for ch in s.chars() {
- if !buf.is_empty() && buf != "'"
- && ch.is_uppercase()
- && !last_upper {
- words.push(buf);
- buf = String::new();
- }
- last_upper = ch.is_uppercase();
- buf.push(ch.to_lowercase());
- }
- words.push(buf);
- }
- words.connect("_")
- }
-
let s = token::get_ident(ident);
if !is_snake_case(ident) {
- cx.span_lint(NON_SNAKE_CASE, span,
- &format!("{} `{}` should have a snake case name such as `{}`",
- sort, s, to_snake_case(s.get()))[]);
+ let sc = NonSnakeCase::to_snake_case(s.get());
+ if sc != s.get() {
+ cx.span_lint(NON_SNAKE_CASE, span,
+ &*format!("{} `{}` should have a snake case name such as `{}`",
+ sort, s, sc));
+ } else {
+ cx.span_lint(NON_SNAKE_CASE, span,
+ &*format!("{} `{}` should have a snake case name",
+ sort, s));
+ }
}
}
}
#[derive(Copy)]
pub struct NonUpperCaseGlobals;
+impl NonUpperCaseGlobals {
+ fn check_upper_case(cx: &Context, sort: &str, ident: ast::Ident, span: Span) {
+ let s = token::get_ident(ident);
+
+ if s.get().chars().any(|c| c.is_lowercase()) {
+ let uc: String = NonSnakeCase::to_snake_case(s.get()).chars()
+ .map(|c| c.to_uppercase()).collect();
+ if uc != s.get() {
+ cx.span_lint(NON_UPPER_CASE_GLOBALS, span,
+ format!("{} `{}` should have an upper case name such as `{}`",
+ sort, s, uc).as_slice());
+ } else {
+ cx.span_lint(NON_UPPER_CASE_GLOBALS, span,
+ format!("{} `{}` should have an upper case name",
+ sort, s).as_slice());
+ }
+ }
+ }
+}
+
impl LintPass for NonUpperCaseGlobals {
fn get_lints(&self) -> LintArray {
lint_array!(NON_UPPER_CASE_GLOBALS)
fn check_item(&mut self, cx: &Context, it: &ast::Item) {
match it.node {
// only check static constants
- ast::ItemStatic(_, ast::MutImmutable, _) |
+ ast::ItemStatic(_, ast::MutImmutable, _) => {
+ NonUpperCaseGlobals::check_upper_case(cx, "static constant", it.ident, it.span);
+ }
ast::ItemConst(..) => {
- let s = token::get_ident(it.ident);
- // check for lowercase letters rather than non-uppercase
- // ones (some scripts don't have a concept of
- // upper/lowercase)
- if s.get().chars().any(|c| c.is_lowercase()) {
- cx.span_lint(NON_UPPER_CASE_GLOBALS, it.span,
- &format!("static constant `{}` should have an uppercase name \
- such as `{}`",
- s.get(), &s.get().chars().map(|c| c.to_uppercase())
- .collect::<String>()[])[]);
- }
+ NonUpperCaseGlobals::check_upper_case(cx, "constant", it.ident, it.span);
}
_ => {}
}
// Lint for constants that look like binding identifiers (#7526)
match (&p.node, cx.tcx.def_map.borrow().get(&p.id)) {
(&ast::PatIdent(_, ref path1, _), Some(&def::DefConst(..))) => {
- let s = token::get_ident(path1.node);
- if s.get().chars().any(|c| c.is_lowercase()) {
- cx.span_lint(NON_UPPER_CASE_GLOBALS, path1.span,
- &format!("static constant in pattern `{}` should have an uppercase \
- name such as `{}`",
- s.get(), &s.get().chars().map(|c| c.to_uppercase())
- .collect::<String>()[])[]);
- }
+ NonUpperCaseGlobals::check_upper_case(cx, "constant in pattern",
+ path1.node, p.span);
}
_ => {}
}
ast::MatchSource::Normal => (head, "`match` head expression", true),
ast::MatchSource::IfLetDesugar { .. } => (head, "`if let` head expression", true),
ast::MatchSource::WhileLetDesugar => (head, "`while let` head expression", true),
+ ast::MatchSource::ForLoopDesugar => (head, "`for` head expression", true),
},
ast::ExprRet(Some(ref value)) => (value, "`return` value", false),
ast::ExprAssign(_, ref value) => (value, "assigned value", false),