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);
+ fn check_snake_case(&self, cx: &Context, sort: &str, name: &str, span: Option<Span>) {
+ fn is_snake_case(ident: &str) -> bool {
if ident.is_empty() {
return true;
}
allow_underscore = match c {
'_' if !allow_underscore => return false,
'_' => false,
+ // It would be more obvious to use `c.is_lowercase()`,
+ // but some characters do not have a lowercase form
c if !c.is_uppercase() => true,
_ => return false,
};
})
}
- let s = token::get_ident(ident);
-
- if !is_snake_case(ident) {
- let sc = NonSnakeCase::to_snake_case(&s);
- if sc != &s[..] {
- cx.span_lint(NON_SNAKE_CASE, span,
- &*format!("{} `{}` should have a snake case name such as `{}`",
- sort, s, sc));
+ if !is_snake_case(name) {
+ let sc = NonSnakeCase::to_snake_case(name);
+ let msg = if sc != name {
+ format!("{} `{}` should have a snake case name such as `{}`",
+ sort, name, sc)
} else {
- cx.span_lint(NON_SNAKE_CASE, span,
- &*format!("{} `{}` should have a snake case name",
- sort, s));
+ format!("{} `{}` should have a snake case name",
+ sort, name)
+ };
+ match span {
+ Some(span) => cx.span_lint(NON_SNAKE_CASE, span, &msg),
+ None => cx.lint(NON_SNAKE_CASE, &msg),
}
}
}
lint_array!(NON_SNAKE_CASE)
}
+ fn check_crate(&mut self, cx: &Context, cr: &ast::Crate) {
+ let attr_crate_name = cr.attrs.iter().find(|at| at.check_name("crate_name"))
+ .and_then(|at| at.value_str().map(|s| (at, s)));
+ if let Some(ref name) = cx.tcx.sess.opts.crate_name {
+ self.check_snake_case(cx, "crate", name, None);
+ } else if let Some((attr, ref name)) = attr_crate_name {
+ self.check_snake_case(cx, "crate", name, Some(attr.span));
+ }
+ }
+
fn check_fn(&mut self, cx: &Context,
fk: visit::FnKind, _: &ast::FnDecl,
_: &ast::Block, span: Span, id: ast::NodeId) {
match fk {
visit::FkMethod(ident, _, _) => match method_context(cx, id, span) {
MethodContext::PlainImpl => {
- self.check_snake_case(cx, "method", ident, span)
+ self.check_snake_case(cx, "method", &token::get_ident(ident), Some(span))
},
MethodContext::TraitDefaultImpl => {
- self.check_snake_case(cx, "trait method", ident, span)
+ self.check_snake_case(cx, "trait method", &token::get_ident(ident), Some(span))
},
_ => (),
},
visit::FkItemFn(ident, _, _, _, _) => {
- self.check_snake_case(cx, "function", ident, span)
+ self.check_snake_case(cx, "function", &token::get_ident(ident), Some(span))
},
_ => (),
}
fn check_item(&mut self, cx: &Context, it: &ast::Item) {
if let ast::ItemMod(_) = it.node {
- self.check_snake_case(cx, "module", it.ident, it.span);
+ self.check_snake_case(cx, "module", &token::get_ident(it.ident), Some(it.span));
}
}
fn check_trait_item(&mut self, cx: &Context, trait_item: &ast::TraitItem) {
if let ast::MethodTraitItem(_, None) = trait_item.node {
- self.check_snake_case(cx, "trait method", trait_item.ident, trait_item.span);
+ self.check_snake_case(cx, "trait method", &token::get_ident(trait_item.ident),
+ Some(trait_item.span));
}
}
fn check_lifetime_def(&mut self, cx: &Context, t: &ast::LifetimeDef) {
- self.check_snake_case(cx, "lifetime", t.lifetime.name.ident(), t.lifetime.span);
+ self.check_snake_case(cx, "lifetime", &token::get_ident(t.lifetime.name.ident()),
+ Some(t.lifetime.span));
}
fn check_pat(&mut self, cx: &Context, p: &ast::Pat) {
if let &ast::PatIdent(_, ref path1, _) = &p.node {
let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def());
if let Some(def::DefLocal(_)) = def {
- self.check_snake_case(cx, "variable", path1.node, p.span);
+ self.check_snake_case(cx, "variable", &token::get_ident(path1.node), Some(p.span));
}
}
}
_: ast::Ident, _: &ast::Generics, _: ast::NodeId) {
for sf in &s.fields {
if let ast::StructField_ { kind: ast::NamedField(ident, _), .. } = sf.node {
- self.check_snake_case(cx, "structure field", ident, sf.span);
+ self.check_snake_case(cx, "structure field", &token::get_ident(ident),
+ Some(sf.span));
}
}
}
}
}
+ fn check_trait_item(&mut self, cx: &Context, ti: &ast::TraitItem) {
+ match ti.node {
+ ast::ConstTraitItem(..) => {
+ NonUpperCaseGlobals::check_upper_case(cx, "associated constant",
+ ti.ident, ti.span);
+ }
+ _ => {}
+ }
+ }
+
+ fn check_impl_item(&mut self, cx: &Context, ii: &ast::ImplItem) {
+ match ii.node {
+ ast::ConstImplItem(..) => {
+ NonUpperCaseGlobals::check_upper_case(cx, "associated constant",
+ ii.ident, ii.span);
+ }
+ _ => {}
+ }
+ }
+
fn check_pat(&mut self, cx: &Context, p: &ast::Pat) {
// Lint for constants that look like binding identifiers (#7526)
match (&p.node, cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def())) {
if self.private_traits.contains(&trait_item.id) { return }
let desc = match trait_item.node {
+ ast::ConstTraitItem(..) => "an associated constant",
ast::MethodTraitItem(..) => "a trait method",
- ast::TypeTraitItem(..) => "an associated type"
+ ast::TypeTraitItem(..) => "an associated type",
};
self.check_missing_docs_attrs(cx, Some(trait_item.id),
}
let desc = match impl_item.node {
+ ast::ConstImplItem(..) => "an associated constant",
ast::MethodImplItem(..) => "a method",
ast::TypeImplItem(_) => "an associated type",
- ast::MacImplItem(_) => "an impl item macro"
+ ast::MacImplItem(_) => "an impl item macro",
};
self.check_missing_docs_attrs(cx, Some(impl_item.id),
&impl_item.attrs,
};
if self.impling_types.is_none() {
- let impls = cx.tcx.trait_impls.borrow();
- let impls = match impls.get(&debug) {
- Some(impls) => {
- impls.borrow().iter()
- .filter(|d| d.krate == ast::LOCAL_CRATE)
- .filter_map(|d| ty::ty_to_def_id(ty::node_id_to_type(cx.tcx, d.node)))
- .map(|d| d.node)
- .collect()
+ let debug_def = ty::lookup_trait_def(cx.tcx, debug);
+ let mut impls = NodeSet();
+ debug_def.for_each_impl(cx.tcx, |d| {
+ if d.krate == ast::LOCAL_CRATE {
+ if let Some(ty_def) = ty::ty_to_def_id(ty::node_id_to_type(cx.tcx, d.node)) {
+ impls.insert(ty_def.node);
+ }
}
- None => NodeSet(),
- };
+ });
+
self.impling_types = Some(impls);
debug!("{:?}", self.impling_types);
}
continue;
}
// add the successors of this node to explore the graph further.
- cfg.graph.each_outgoing_edge(idx, |_, edge| {
+ for (_, edge) in cfg.graph.outgoing_edges(idx) {
let target_idx = edge.target();
let target_cfg_id = target_idx.node_id();
if !visited.contains(&target_cfg_id) {
work_queue.push(target_idx)
}
- true
- });
+ }
}
// Check the number of self calls because a function that