1use rustc_abi::ExternAbi;
2use rustc_attr_parsing::AttributeParser;
3use rustc_errors::Applicability;
4use rustc_hir::attrs::{AttributeKind, ReprAttr};
5use rustc_hir::def::{DefKind, Res};
6use rustc_hir::def_id::DefId;
7use rustc_hir::intravisit::{FnKind, Visitor};
8use rustc_hir::{Attribute, GenericParamKind, PatExprKind, PatKind, find_attr};
9use rustc_middle::hir::nested_filter::All;
10use rustc_middle::ty::AssocContainer;
11use rustc_session::config::CrateType;
12use rustc_session::{declare_lint, declare_lint_pass};
13use rustc_span::def_id::LocalDefId;
14use rustc_span::{BytePos, Ident, Span, sym};
15use {rustc_ast as ast, rustc_hir as hir};
16
17use crate::lints::{
18 NonCamelCaseType, NonCamelCaseTypeSub, NonSnakeCaseDiag, NonSnakeCaseDiagSub,
19 NonUpperCaseGlobal, NonUpperCaseGlobalSub, NonUpperCaseGlobalSubTool,
20};
21use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
22
23#[doc =
r" The `non_camel_case_types` lint detects types, variants, traits and"]
#[doc = r" type parameters that don't have camel case names."]
#[doc = r""]
#[doc = r" ### Example"]
#[doc = r""]
#[doc = r" ```rust"]
#[doc = r" struct my_struct;"]
#[doc = r" ```"]
#[doc = r""]
#[doc = r" {{produces}}"]
#[doc = r""]
#[doc = r" ### Explanation"]
#[doc = r""]
#[doc =
r#" The preferred style for these identifiers is to use "camel case", such"#]
#[doc =
r" as `MyStruct`, where the first letter should not be lowercase, and"]
#[doc =
r" should not use underscores between letters. Underscores are allowed at"]
#[doc = r" the beginning and end of the identifier, as well as between"]
#[doc = r" non-letters (such as `X86_64`)."]
pub static NON_CAMEL_CASE_TYPES: &::rustc_lint_defs::Lint =
&::rustc_lint_defs::Lint {
name: "NON_CAMEL_CASE_TYPES",
default_level: ::rustc_lint_defs::Warn,
desc: "types, variants, traits and type parameters should have camel case names",
is_externally_loaded: false,
..::rustc_lint_defs::Lint::default_fields_for_macro()
};declare_lint! {
24 pub NON_CAMEL_CASE_TYPES,
43 Warn,
44 "types, variants, traits and type parameters should have camel case names"
45}
46
47pub struct NonCamelCaseTypes;
#[automatically_derived]
impl ::core::marker::Copy for NonCamelCaseTypes { }
#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for NonCamelCaseTypes { }
#[automatically_derived]
impl ::core::clone::Clone for NonCamelCaseTypes {
#[inline]
fn clone(&self) -> NonCamelCaseTypes { *self }
}
impl ::rustc_lint_defs::LintPass for NonCamelCaseTypes {
fn name(&self) -> &'static str { "NonCamelCaseTypes" }
fn get_lints(&self) -> ::rustc_lint_defs::LintVec {
::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[NON_CAMEL_CASE_TYPES]))
}
}
impl NonCamelCaseTypes {
#[allow(unused)]
pub fn lint_vec() -> ::rustc_lint_defs::LintVec {
::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[NON_CAMEL_CASE_TYPES]))
}
}declare_lint_pass!(NonCamelCaseTypes => [NON_CAMEL_CASE_TYPES]);
48
49fn char_has_case(c: char) -> bool {
53 let mut l = c.to_lowercase();
54 let mut u = c.to_uppercase();
55 while let Some(l) = l.next() {
56 match u.next() {
57 Some(u) if l != u => return true,
58 _ => {}
59 }
60 }
61 u.next().is_some()
62}
63
64fn is_camel_case(name: &str) -> bool {
65 let name = name.trim_matches('_');
66 if name.is_empty() {
67 return true;
68 }
69
70 !name.chars().next().unwrap().is_lowercase()
73 && !name.contains("__")
74 && !name.chars().collect::<Vec<_>>().array_windows().any(|&[fst, snd]| {
75 char_has_case(fst) && snd == '_' || char_has_case(snd) && fst == '_'
77 })
78}
79
80fn to_camel_case(s: &str) -> String {
81 s.trim_matches('_')
82 .split('_')
83 .filter(|component| !component.is_empty())
84 .map(|component| {
85 let mut camel_cased_component = String::new();
86
87 let mut new_word = true;
88 let mut prev_is_lower_case = true;
89
90 for c in component.chars() {
91 if prev_is_lower_case && c.is_uppercase() {
94 new_word = true;
95 }
96
97 if new_word {
98 camel_cased_component.extend(c.to_uppercase());
99 } else {
100 camel_cased_component.extend(c.to_lowercase());
101 }
102
103 prev_is_lower_case = c.is_lowercase();
104 new_word = false;
105 }
106
107 camel_cased_component
108 })
109 .fold((String::new(), None), |(acc, prev): (String, Option<String>), next| {
110 let join = if let Some(prev) = prev {
113 let l = prev.chars().last().unwrap();
114 let f = next.chars().next().unwrap();
115 !char_has_case(l) && !char_has_case(f)
116 } else {
117 false
118 };
119 (acc + if join { "_" } else { "" } + &next, Some(next))
120 })
121 .0
122}
123
124impl NonCamelCaseTypes {
125 fn check_case(&self, cx: &EarlyContext<'_>, sort: &str, ident: &Ident) {
126 let name = ident.name.as_str();
127
128 if !is_camel_case(name) {
129 let cc = to_camel_case(name);
130 let sub = if *name != cc {
131 NonCamelCaseTypeSub::Suggestion { span: ident.span, replace: cc }
132 } else {
133 NonCamelCaseTypeSub::Label { span: ident.span }
134 };
135 cx.emit_span_lint(
136 NON_CAMEL_CASE_TYPES,
137 ident.span,
138 NonCamelCaseType { sort, name, sub },
139 );
140 }
141 }
142}
143
144impl EarlyLintPass for NonCamelCaseTypes {
145 fn check_item(&mut self, cx: &EarlyContext<'_>, it: &ast::Item) {
146 let has_repr_c = #[allow(non_exhaustive_omitted_patterns)] match AttributeParser::parse_limited(cx.sess(),
&it.attrs, sym::repr, it.span, it.id, None) {
Some(Attribute::Parsed(AttributeKind::Repr { reprs, .. })) if
reprs.iter().any(|(r, _)| r == &ReprAttr::ReprC) => true,
_ => false,
}matches!(
147 AttributeParser::parse_limited(cx.sess(), &it.attrs, sym::repr, it.span, it.id, None),
148 Some(Attribute::Parsed(AttributeKind::Repr { reprs, ..})) if reprs.iter().any(|(r, _)| r == &ReprAttr::ReprC)
149 );
150
151 if has_repr_c {
152 return;
153 }
154
155 match &it.kind {
156 ast::ItemKind::TyAlias(box ast::TyAlias { ident, .. })
157 | ast::ItemKind::Enum(ident, ..)
158 | ast::ItemKind::Struct(ident, ..)
159 | ast::ItemKind::Union(ident, ..) => self.check_case(cx, "type", ident),
160 ast::ItemKind::Trait(box ast::Trait { ident, .. }) => {
161 self.check_case(cx, "trait", ident)
162 }
163 ast::ItemKind::TraitAlias(box ast::TraitAlias { ident, .. }) => {
164 self.check_case(cx, "trait alias", ident)
165 }
166
167 ast::ItemKind::Impl(ast::Impl { of_trait: None, items, .. }) => {
170 for it in items {
171 if let ast::AssocItemKind::Type(alias) = &it.kind {
173 self.check_case(cx, "associated type", &alias.ident);
174 }
175 }
176 }
177 _ => (),
178 }
179 }
180
181 fn check_trait_item(&mut self, cx: &EarlyContext<'_>, it: &ast::AssocItem) {
182 if let ast::AssocItemKind::Type(alias) = &it.kind {
183 self.check_case(cx, "associated type", &alias.ident);
184 }
185 }
186
187 fn check_variant(&mut self, cx: &EarlyContext<'_>, v: &ast::Variant) {
188 self.check_case(cx, "variant", &v.ident);
189 }
190
191 fn check_generic_param(&mut self, cx: &EarlyContext<'_>, param: &ast::GenericParam) {
192 if let ast::GenericParamKind::Type { .. } = param.kind {
193 self.check_case(cx, "type parameter", ¶m.ident);
194 }
195 }
196}
197
198#[doc = r" The `non_snake_case` lint detects variables, methods, functions,"]
#[doc = r" lifetime parameters and modules that don't have snake case names."]
#[doc = r""]
#[doc = r" ### Example"]
#[doc = r""]
#[doc = r" ```rust"]
#[doc = r" let MY_VALUE = 5;"]
#[doc = r" ```"]
#[doc = r""]
#[doc = r" {{produces}}"]
#[doc = r""]
#[doc = r" ### Explanation"]
#[doc = r""]
#[doc =
r#" The preferred style for these identifiers is to use "snake case","#]
#[doc =
r" where all the characters are in lowercase, with words separated with a"]
#[doc = r" single underscore, such as `my_value`."]
pub static NON_SNAKE_CASE: &::rustc_lint_defs::Lint =
&::rustc_lint_defs::Lint {
name: "NON_SNAKE_CASE",
default_level: ::rustc_lint_defs::Warn,
desc: "variables, methods, functions, lifetime parameters and modules should have snake case names",
is_externally_loaded: false,
..::rustc_lint_defs::Lint::default_fields_for_macro()
};declare_lint! {
199 pub NON_SNAKE_CASE,
216 Warn,
217 "variables, methods, functions, lifetime parameters and modules should have snake case names"
218}
219
220pub struct NonSnakeCase;
#[automatically_derived]
impl ::core::marker::Copy for NonSnakeCase { }
#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for NonSnakeCase { }
#[automatically_derived]
impl ::core::clone::Clone for NonSnakeCase {
#[inline]
fn clone(&self) -> NonSnakeCase { *self }
}
impl ::rustc_lint_defs::LintPass for NonSnakeCase {
fn name(&self) -> &'static str { "NonSnakeCase" }
fn get_lints(&self) -> ::rustc_lint_defs::LintVec {
::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[NON_SNAKE_CASE]))
}
}
impl NonSnakeCase {
#[allow(unused)]
pub fn lint_vec() -> ::rustc_lint_defs::LintVec {
::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[NON_SNAKE_CASE]))
}
}declare_lint_pass!(NonSnakeCase => [NON_SNAKE_CASE]);
221
222impl NonSnakeCase {
223 fn to_snake_case(mut name: &str) -> String {
224 let mut words = ::alloc::vec::Vec::new()vec![];
225 name = name.trim_start_matches(|c: char| {
227 if c == '_' {
228 words.push(String::new());
229 true
230 } else {
231 false
232 }
233 });
234 for s in name.split('_') {
235 let mut last_upper = false;
236 let mut buf = String::new();
237 if s.is_empty() {
238 continue;
239 }
240 for ch in s.chars() {
241 if !buf.is_empty() && buf != "'" && ch.is_uppercase() && !last_upper {
242 words.push(buf);
243 buf = String::new();
244 }
245 last_upper = ch.is_uppercase();
246 buf.extend(ch.to_lowercase());
247 }
248 words.push(buf);
249 }
250 words.join("_")
251 }
252
253 fn check_snake_case(&self, cx: &LateContext<'_>, sort: &str, ident: &Ident) {
255 fn is_snake_case(ident: &str) -> bool {
256 if ident.is_empty() {
257 return true;
258 }
259 let ident = ident.trim_start_matches('\'');
260 let ident = ident.trim_matches('_');
261
262 if ident.contains("__") {
263 return false;
264 }
265
266 !ident.chars().any(char::is_uppercase)
269 }
270
271 let name = ident.name.as_str();
272
273 if !is_snake_case(name) {
274 let span = ident.span;
275 let sc = NonSnakeCase::to_snake_case(name);
276 let sub = if name != sc {
279 if !span.is_dummy() {
282 let sc_ident = Ident::from_str_and_span(&sc, span);
283 if sc_ident.is_reserved() {
284 if sc_ident.name.can_be_raw() {
288 NonSnakeCaseDiagSub::RenameOrConvertSuggestion {
289 span,
290 suggestion: sc_ident,
291 }
292 } else {
293 NonSnakeCaseDiagSub::SuggestionAndNote { span }
294 }
295 } else {
296 NonSnakeCaseDiagSub::ConvertSuggestion { span, suggestion: sc.clone() }
297 }
298 } else {
299 NonSnakeCaseDiagSub::Help
300 }
301 } else {
302 NonSnakeCaseDiagSub::Label { span }
303 };
304 cx.emit_span_lint(NON_SNAKE_CASE, span, NonSnakeCaseDiag { sort, name, sc, sub });
305 }
306 }
307}
308
309impl<'tcx> LateLintPass<'tcx> for NonSnakeCase {
310 fn check_mod(&mut self, cx: &LateContext<'_>, _: &'tcx hir::Mod<'tcx>, id: hir::HirId) {
311 if id != hir::CRATE_HIR_ID {
312 return;
313 }
314
315 if cx.tcx.crate_types().iter().all(|&crate_type| crate_type == CrateType::Executable) {
319 return;
320 }
321
322 let crate_ident = if let Some(name) = &cx.tcx.sess.opts.crate_name {
323 Some(Ident::from_str(name))
324 } else {
325 {
'done:
{
for i in cx.tcx.hir_krate_attrs() {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(CrateName { name, name_span, ..
}) => {
break 'done Some((name, name_span));
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}find_attr!(cx.tcx, crate, CrateName{name, name_span,..} => (name, name_span)).map(
326 |(&name, &span)| {
327 let sp = cx
329 .sess()
330 .source_map()
331 .span_to_snippet(span)
332 .ok()
333 .and_then(|snippet| {
334 let left = snippet.find('"')?;
335 let right = snippet.rfind('"').map(|pos| snippet.len() - pos)?;
336
337 Some(
338 span.with_lo(span.lo() + BytePos(left as u32 + 1))
339 .with_hi(span.hi() - BytePos(right as u32)),
340 )
341 })
342 .unwrap_or(span);
343
344 Ident::new(name, sp)
345 },
346 )
347 };
348
349 if let Some(ident) = &crate_ident {
350 self.check_snake_case(cx, "crate", ident);
351 }
352 }
353
354 fn check_generic_param(&mut self, cx: &LateContext<'_>, param: &hir::GenericParam<'_>) {
355 if let GenericParamKind::Lifetime { .. } = param.kind {
356 self.check_snake_case(cx, "lifetime", ¶m.name.ident());
357 }
358 }
359
360 fn check_fn(
361 &mut self,
362 cx: &LateContext<'_>,
363 fk: FnKind<'_>,
364 _: &hir::FnDecl<'_>,
365 _: &hir::Body<'_>,
366 _: Span,
367 id: LocalDefId,
368 ) {
369 match &fk {
370 FnKind::Method(ident, sig, ..) => match cx.tcx.associated_item(id).container {
371 AssocContainer::InherentImpl => {
372 if sig.header.abi != ExternAbi::Rust && {
#[allow(deprecated)]
{
{
'done:
{
for i in cx.tcx.get_all_attrs(id) {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(NoMangle(..)) => {
break 'done Some(());
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}
}
}.is_some()find_attr!(cx.tcx, id, NoMangle(..)) {
373 return;
374 }
375 self.check_snake_case(cx, "method", ident);
376 }
377 AssocContainer::Trait => {
378 self.check_snake_case(cx, "trait method", ident);
379 }
380 AssocContainer::TraitImpl(_) => {}
381 },
382 FnKind::ItemFn(ident, _, header) => {
383 if header.abi != ExternAbi::Rust && {
#[allow(deprecated)]
{
{
'done:
{
for i in cx.tcx.get_all_attrs(id) {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(NoMangle(..)) => {
break 'done Some(());
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}
}
}.is_some()find_attr!(cx.tcx, id, NoMangle(..)) {
385 return;
386 }
387 self.check_snake_case(cx, "function", ident);
388 }
389 FnKind::Closure => (),
390 }
391 }
392
393 fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
394 if let hir::ItemKind::Mod(ident, _) = it.kind {
395 self.check_snake_case(cx, "module", &ident);
396 }
397 }
398
399 fn check_ty(&mut self, cx: &LateContext<'_>, ty: &hir::Ty<'_, hir::AmbigArg>) {
400 if let hir::TyKind::FnPtr(hir::FnPtrTy { param_idents, .. }) = &ty.kind {
401 for param_ident in *param_idents {
402 if let Some(param_ident) = param_ident {
403 self.check_snake_case(cx, "variable", param_ident);
404 }
405 }
406 }
407 }
408
409 fn check_trait_item(&mut self, cx: &LateContext<'_>, item: &hir::TraitItem<'_>) {
410 if let hir::TraitItemKind::Fn(_, hir::TraitFn::Required(param_idents)) = item.kind {
411 self.check_snake_case(cx, "trait method", &item.ident);
412 for param_ident in param_idents {
413 if let Some(param_ident) = param_ident {
414 self.check_snake_case(cx, "variable", param_ident);
415 }
416 }
417 }
418 }
419
420 fn check_pat(&mut self, cx: &LateContext<'_>, p: &hir::Pat<'_>) {
421 if let PatKind::Binding(_, hid, ident, _) = p.kind {
422 if let hir::Node::PatField(field) = cx.tcx.parent_hir_node(hid) {
423 if !field.is_shorthand {
424 self.check_snake_case(cx, "variable", &ident);
427 }
428 return;
429 }
430 self.check_snake_case(cx, "variable", &ident);
431 }
432 }
433
434 fn check_struct_def(&mut self, cx: &LateContext<'_>, s: &hir::VariantData<'_>) {
435 for sf in s.fields() {
436 self.check_snake_case(cx, "structure field", &sf.ident);
437 }
438 }
439}
440
441#[doc =
r" The `non_upper_case_globals` lint detects static items that don't have"]
#[doc = r" uppercase identifiers."]
#[doc = r""]
#[doc = r" ### Example"]
#[doc = r""]
#[doc = r" ```rust"]
#[doc = r" static max_points: i32 = 5;"]
#[doc = r" ```"]
#[doc = r""]
#[doc = r" {{produces}}"]
#[doc = r""]
#[doc = r" ### Explanation"]
#[doc = r""]
#[doc = r" The preferred style is for static item names to use all uppercase"]
#[doc = r" letters such as `MAX_POINTS`."]
pub static NON_UPPER_CASE_GLOBALS: &::rustc_lint_defs::Lint =
&::rustc_lint_defs::Lint {
name: "NON_UPPER_CASE_GLOBALS",
default_level: ::rustc_lint_defs::Warn,
desc: "static constants should have uppercase identifiers",
is_externally_loaded: false,
..::rustc_lint_defs::Lint::default_fields_for_macro()
};declare_lint! {
442 pub NON_UPPER_CASE_GLOBALS,
458 Warn,
459 "static constants should have uppercase identifiers"
460}
461
462pub struct NonUpperCaseGlobals;
#[automatically_derived]
impl ::core::marker::Copy for NonUpperCaseGlobals { }
#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for NonUpperCaseGlobals { }
#[automatically_derived]
impl ::core::clone::Clone for NonUpperCaseGlobals {
#[inline]
fn clone(&self) -> NonUpperCaseGlobals { *self }
}
impl ::rustc_lint_defs::LintPass for NonUpperCaseGlobals {
fn name(&self) -> &'static str { "NonUpperCaseGlobals" }
fn get_lints(&self) -> ::rustc_lint_defs::LintVec {
::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[NON_UPPER_CASE_GLOBALS]))
}
}
impl NonUpperCaseGlobals {
#[allow(unused)]
pub fn lint_vec() -> ::rustc_lint_defs::LintVec {
::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[NON_UPPER_CASE_GLOBALS]))
}
}declare_lint_pass!(NonUpperCaseGlobals => [NON_UPPER_CASE_GLOBALS]);
463
464impl NonUpperCaseGlobals {
465 fn check_upper_case(cx: &LateContext<'_>, sort: &str, did: Option<LocalDefId>, ident: &Ident) {
466 let name = ident.name.as_str();
467 if name.chars().any(|c| c.is_lowercase()) {
468 let uc = NonSnakeCase::to_snake_case(name).to_uppercase();
469
470 let can_change_usages = if let Some(did) = did {
473 !cx.tcx.effective_visibilities(()).is_exported(did)
474 } else {
475 false
476 };
477
478 let sub = if *name != uc {
481 NonUpperCaseGlobalSub::Suggestion {
482 span: ident.span,
483 replace: uc.clone(),
484 applicability: if can_change_usages {
485 Applicability::MachineApplicable
486 } else {
487 Applicability::MaybeIncorrect
488 },
489 }
490 } else {
491 NonUpperCaseGlobalSub::Label { span: ident.span }
492 };
493
494 struct UsageCollector<'a, 'tcx> {
495 cx: &'tcx LateContext<'a>,
496 did: DefId,
497 collected: Vec<Span>,
498 }
499
500 impl<'v, 'tcx> Visitor<'v> for UsageCollector<'v, 'tcx> {
501 type NestedFilter = All;
502
503 fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
504 self.cx.tcx
505 }
506
507 fn visit_path(
508 &mut self,
509 path: &rustc_hir::Path<'v>,
510 _id: rustc_hir::HirId,
511 ) -> Self::Result {
512 if let Some(final_seg) = path.segments.last()
513 && final_seg.res.opt_def_id() == Some(self.did)
514 {
515 self.collected.push(final_seg.ident.span);
516 }
517 }
518 }
519
520 cx.emit_span_lint_lazy(NON_UPPER_CASE_GLOBALS, ident.span, || {
521 let usages = if can_change_usages
524 && *name != uc
525 && let Some(did) = did
526 {
527 let mut usage_collector =
528 UsageCollector { cx, did: did.to_def_id(), collected: Vec::new() };
529 cx.tcx.hir_walk_toplevel_module(&mut usage_collector);
530 usage_collector
531 .collected
532 .into_iter()
533 .map(|span| NonUpperCaseGlobalSubTool { span, replace: uc.clone() })
534 .collect()
535 } else {
536 ::alloc::vec::Vec::new()vec![]
537 };
538
539 NonUpperCaseGlobal { sort, name, sub, usages }
540 });
541 }
542 }
543}
544
545impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals {
546 fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
547 let attrs = cx.tcx.hir_attrs(it.hir_id());
548 match it.kind {
549 hir::ItemKind::Static(_, ident, ..) if !{
{
'done:
{
for i in attrs {
#[allow(unused_imports)]
use rustc_hir::attrs::AttributeKind::*;
let i: &rustc_hir::Attribute = i;
match i {
rustc_hir::Attribute::Parsed(NoMangle(..)) => {
break 'done Some(());
}
rustc_hir::Attribute::Unparsed(..) =>
{}
#[deny(unreachable_patterns)]
_ => {}
}
}
None
}
}.is_some()
}find_attr!(attrs, NoMangle(..)) => {
550 NonUpperCaseGlobals::check_upper_case(
551 cx,
552 "static variable",
553 Some(it.owner_id.def_id),
554 &ident,
555 );
556 }
557 hir::ItemKind::Const(ident, ..) => {
558 NonUpperCaseGlobals::check_upper_case(
559 cx,
560 "constant",
561 Some(it.owner_id.def_id),
562 &ident,
563 );
564 }
565 _ => {}
566 }
567 }
568
569 fn check_trait_item(&mut self, cx: &LateContext<'_>, ti: &hir::TraitItem<'_>) {
570 if let hir::TraitItemKind::Const(..) = ti.kind {
571 NonUpperCaseGlobals::check_upper_case(cx, "associated constant", None, &ti.ident);
572 }
573 }
574
575 fn check_impl_item(&mut self, cx: &LateContext<'_>, ii: &hir::ImplItem<'_>) {
576 if let hir::ImplItemKind::Const(..) = ii.kind
577 && let hir::ImplItemImplKind::Inherent { .. } = ii.impl_kind
578 {
579 NonUpperCaseGlobals::check_upper_case(cx, "associated constant", None, &ii.ident);
580 }
581 }
582
583 fn check_pat(&mut self, cx: &LateContext<'_>, p: &hir::Pat<'_>) {
584 if let PatKind::Expr(hir::PatExpr {
586 kind: PatExprKind::Path(hir::QPath::Resolved(None, path)),
587 ..
588 }) = p.kind
589 {
590 if let Res::Def(DefKind::Const, _) = path.res
591 && let [segment] = path.segments
592 {
593 NonUpperCaseGlobals::check_upper_case(
594 cx,
595 "constant in pattern",
596 None,
597 &segment.ident,
598 );
599 }
600 }
601 }
602
603 fn check_generic_param(&mut self, cx: &LateContext<'_>, param: &hir::GenericParam<'_>) {
604 if let GenericParamKind::Const { .. } = param.kind {
605 NonUpperCaseGlobals::check_upper_case(
606 cx,
607 "const parameter",
608 Some(param.def_id),
609 ¶m.name.ident(),
610 );
611 }
612 }
613}
614
615#[cfg(test)]
616mod tests;