Skip to content

Commit ab74712

Browse files
committed
extract pattern lint from non_upper_case_globals
1 parent 9cd3bef commit ab74712

File tree

8 files changed

+140
-113
lines changed

8 files changed

+140
-113
lines changed

src/libpanic_unwind/dwarf/eh.rs

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
//! (<root>/libgcc/unwind-c.c as of this writing)
2020
2121
#![allow(non_upper_case_globals)]
22+
#![cfg_attr(not(stage0), allow(misleading_constant_patterns))]
2223
#![allow(unused)]
2324

2425
use dwarf::DwarfReader;

src/librustc_lint/lib.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
139139
NonCamelCaseTypes: NonCamelCaseTypes,
140140
NonSnakeCase: NonSnakeCase,
141141
NonUpperCaseGlobals: NonUpperCaseGlobals,
142+
MisleadingConstantPatterns: MisleadingConstantPatterns,
142143
NonShorthandFieldPatterns: NonShorthandFieldPatterns,
143144
UnsafeCode: UnsafeCode,
144145
UnusedAllocation: UnusedAllocation,
@@ -165,7 +166,8 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
165166
"nonstandard_style",
166167
NON_CAMEL_CASE_TYPES,
167168
NON_SNAKE_CASE,
168-
NON_UPPER_CASE_GLOBALS);
169+
NON_UPPER_CASE_GLOBALS,
170+
MISLEADING_CONSTANT_PATTERNS);
169171

170172
add_lint_group!(sess,
171173
"unused",

src/librustc_lint/nonstandard_style.rs

+52-5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use lint::{LintPass, LateLintPass};
1616
use rustc_target::spec::abi::Abi;
1717
use syntax::ast;
1818
use syntax::attr;
19+
use syntax::errors::Applicability;
1920
use syntax_pos::Span;
2021

2122
use rustc::hir::{self, GenericParamKind, PatKind};
@@ -340,7 +341,7 @@ pub struct NonUpperCaseGlobals;
340341

341342
impl NonUpperCaseGlobals {
342343
fn check_upper_case(cx: &LateContext, sort: &str, name: ast::Name, span: Span) {
343-
if name.as_str().chars().any(|c| c.is_lowercase()) {
344+
if has_lower_case_chars(&name.as_str()) {
344345
let uc = NonSnakeCase::to_snake_case(&name.as_str()).to_uppercase();
345346
if name != &*uc {
346347
cx.span_lint(NON_UPPER_CASE_GLOBALS,
@@ -399,18 +400,64 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonUpperCaseGlobals {
399400
_ => {}
400401
}
401402
}
403+
}
404+
405+
declare_lint! {
406+
pub MISLEADING_CONSTANT_PATTERNS,
407+
Warn,
408+
"constants in patterns should have upper case identifiers"
409+
}
402410

411+
#[derive(Copy, Clone)]
412+
pub struct MisleadingConstantPatterns;
413+
414+
impl MisleadingConstantPatterns {
415+
fn check_upper_case(cx: &LateContext, name: ast::Name, span: Span) {
416+
if has_lower_case_chars(&name.as_str()) {
417+
let uc = NonSnakeCase::to_snake_case(&name.as_str()).to_uppercase();
418+
419+
cx.struct_span_lint(
420+
MISLEADING_CONSTANT_PATTERNS,
421+
span,
422+
&format!("constant pattern `{}` should be upper case", name),
423+
)
424+
.span_label(span, "looks like a binding")
425+
.span_suggestion_with_applicability(
426+
span,
427+
"convert the pattern to upper case",
428+
uc,
429+
Applicability::MaybeIncorrect,
430+
)
431+
.emit();
432+
}
433+
}
434+
}
435+
436+
impl LintPass for MisleadingConstantPatterns {
437+
fn get_lints(&self) -> LintArray {
438+
lint_array!(MISLEADING_CONSTANT_PATTERNS)
439+
}
440+
}
441+
442+
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MisleadingConstantPatterns {
403443
fn check_pat(&mut self, cx: &LateContext, p: &hir::Pat) {
404444
// Lint for constants that look like binding identifiers (#7526)
405445
if let PatKind::Path(hir::QPath::Resolved(None, ref path)) = p.node {
406446
if let Def::Const(..) = path.def {
407447
if path.segments.len() == 1 {
408-
NonUpperCaseGlobals::check_upper_case(cx,
409-
"constant in pattern",
410-
path.segments[0].ident.name,
411-
path.span);
448+
MisleadingConstantPatterns::check_upper_case(
449+
cx,
450+
path.segments[0].ident.name,
451+
path.span,
452+
);
412453
}
413454
}
414455
}
415456
}
416457
}
458+
459+
/// Returns whether a string contains any lower case characters. Note that this is different from
460+
/// checking if a string is not fully upper case, since most scripts do not have case distinctions.
461+
fn has_lower_case_chars(s: &str) -> bool {
462+
s.chars().any(char::is_lowercase)
463+
}

src/test/run-pass/structs-enums/empty-struct-braces.rs

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
// run-pass
1212
#![allow(unused_variables)]
1313
#![allow(non_upper_case_globals)]
14+
#![allow(misleading_constant_patterns)]
1415

1516
// Empty struct defined with braces add names into type namespace
1617
// Empty struct defined without braces add names into both type and value namespaces

src/test/run-pass/binding/match-static-const-rename.rs renamed to src/test/ui/lint/lint-misleading-constant-patterns.rs

+48-20
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,58 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// run-pass
1211
// Issue #7526: lowercase static constants in patterns look like bindings
1312

14-
// This is similar to compile-fail/match-static-const-lc, except it
15-
// shows the expected usual workaround (choosing a different name for
16-
// the static definition) and also demonstrates that one can work
17-
// around this problem locally by renaming the constant in the `use`
18-
// form to an uppercase identifier that placates the lint.
13+
#![deny(misleading_constant_patterns)]
14+
#![allow(dead_code)]
1915

16+
#[allow(non_upper_case_globals)]
17+
pub const a : isize = 97;
2018

21-
#![deny(non_upper_case_globals)]
19+
fn f() {
20+
let r = match (0,0) {
21+
(0, a) => 0, //~ ERROR should be upper case
22+
//| HELP convert the pattern to upper case
23+
//| SUGGESTION A
24+
(x, y) => 1 + x + y,
25+
};
26+
assert_eq!(r, 1);
27+
}
28+
29+
mod m {
30+
#[allow(non_upper_case_globals)]
31+
pub const aha : isize = 7;
32+
}
33+
34+
fn g() {
35+
use self::m::aha;
36+
let r = match (0,0) {
37+
(0, aha) => 0, //~ ERROR should be upper case
38+
//| HELP convert the pattern to upper case
39+
//| SUGGESTION AHA
40+
(x, y) => 1 + x + y,
41+
};
42+
assert_eq!(r, 1);
43+
}
44+
45+
mod n {
46+
pub const OKAY : isize = 8;
47+
}
48+
49+
fn h() {
50+
use self::n::OKAY as not_okay;
51+
let r = match (0,0) {
52+
(0, not_okay) => 0, //~ ERROR should be upper case
53+
//| HELP convert the pattern to upper case
54+
//| SUGGESTION NOT_OKAY
55+
(x, y) => 1 + x + y,
56+
};
57+
assert_eq!(r, 1);
58+
}
2259

2360
pub const A : isize = 97;
2461

25-
fn f() {
62+
fn i() {
2663
let r = match (0,0) {
2764
(0, A) => 0,
2865
(x, y) => 1 + x + y,
@@ -35,12 +72,7 @@ fn f() {
3572
assert_eq!(r, 0);
3673
}
3774

38-
mod m {
39-
#[allow(non_upper_case_globals)]
40-
pub const aha : isize = 7;
41-
}
42-
43-
fn g() {
75+
fn j() {
4476
use self::m::aha as AHA;
4577
let r = match (0,0) {
4678
(0, AHA) => 0,
@@ -54,7 +86,7 @@ fn g() {
5486
assert_eq!(r, 0);
5587
}
5688

57-
fn h() {
89+
fn k() {
5890
let r = match (0,0) {
5991
(0, self::m::aha) => 0,
6092
(x, y) => 1 + x + y,
@@ -67,8 +99,4 @@ fn h() {
6799
assert_eq!(r, 0);
68100
}
69101

70-
pub fn main () {
71-
f();
72-
g();
73-
h();
74-
}
102+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
error: constant pattern `a` should be upper case
2+
--> $DIR/lint-misleading-constant-patterns.rs:21:13
3+
|
4+
LL | (0, a) => 0, //~ ERROR should be upper case
5+
| ^
6+
| |
7+
| looks like a binding
8+
| help: convert the pattern to upper case: `A`
9+
|
10+
note: lint level defined here
11+
--> $DIR/lint-misleading-constant-patterns.rs:13:9
12+
|
13+
LL | #![deny(misleading_constant_patterns)]
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15+
16+
error: constant pattern `aha` should be upper case
17+
--> $DIR/lint-misleading-constant-patterns.rs:37:13
18+
|
19+
LL | (0, aha) => 0, //~ ERROR should be upper case
20+
| ^^^
21+
| |
22+
| looks like a binding
23+
| help: convert the pattern to upper case: `AHA`
24+
25+
error: constant pattern `not_okay` should be upper case
26+
--> $DIR/lint-misleading-constant-patterns.rs:52:13
27+
|
28+
LL | (0, not_okay) => 0, //~ ERROR should be upper case
29+
| ^^^^^^^^
30+
| |
31+
| looks like a binding
32+
| help: convert the pattern to upper case: `NOT_OKAY`
33+
34+
error: aborting due to 3 previous errors
35+

src/test/ui/match/match-static-const-lc.rs

-61
This file was deleted.

src/test/ui/match/match-static-const-lc.stderr

-26
This file was deleted.

0 commit comments

Comments
 (0)