Skip to content

Commit 97cd495

Browse files
committed
auto merge of #9638 : pnkfelix/rust/fsk-issue7526-attempt-to-catch-nonuc-statics-in-match-patterns, r=alexcrichton
r? anyone Address scariest part of #7526 by adding a new more specific lint (that is set to warn by default, rather than allow).
2 parents 33a5928 + 2461b31 commit 97cd495

13 files changed

+172
-0
lines changed

src/librustc/lib/llvm.rs

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
// LLVM wrappers are intended to be called from trans,
1212
// which already runs in a #[fixed_stack_segment]
1313
#[allow(cstack)];
14+
#[allow(non_uppercase_pattern_statics)];
1415

1516
use std::c_str::ToCStr;
1617
use std::hashmap::HashMap;

src/librustc/middle/check_match.rs

+1
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ pub fn check_arms(cx: &MatchCheckCtxt, arms: &[Arm]) {
133133
_ => false
134134
}
135135
};
136+
136137
do walk_pat(*pat) |p| {
137138
if pat_matches_nan(p) {
138139
cx.tcx.sess.span_warn(p.span, "unmatchable NaN in pattern, \

src/librustc/middle/lint.rs

+29
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ pub enum lint {
8383
unrecognized_lint,
8484
non_camel_case_types,
8585
non_uppercase_statics,
86+
non_uppercase_pattern_statics,
8687
type_limits,
8788
unused_unsafe,
8889

@@ -209,6 +210,13 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[
209210
default: allow
210211
}),
211212

213+
("non_uppercase_pattern_statics",
214+
LintSpec {
215+
lint: non_uppercase_pattern_statics,
216+
desc: "static constants in match patterns should be all caps",
217+
default: warn
218+
}),
219+
212220
("managed_heap_memory",
213221
LintSpec {
214222
lint: managed_heap_memory,
@@ -1110,6 +1118,22 @@ fn check_item_non_uppercase_statics(cx: &Context, it: &ast::item) {
11101118
}
11111119
}
11121120

1121+
fn check_pat_non_uppercase_statics(cx: &Context, p: &ast::Pat) {
1122+
// Lint for constants that look like binding identifiers (#7526)
1123+
match (&p.node, cx.tcx.def_map.find(&p.id)) {
1124+
(&ast::PatIdent(_, ref path, _), Some(&ast::DefStatic(_, false))) => {
1125+
// last identifier alone is right choice for this lint.
1126+
let ident = path.segments.last().identifier;
1127+
let s = cx.tcx.sess.str_of(ident);
1128+
if s.iter().any(|c| c.is_lowercase()) {
1129+
cx.span_lint(non_uppercase_pattern_statics, path.span,
1130+
"static constant in pattern should be all caps");
1131+
}
1132+
}
1133+
_ => {}
1134+
}
1135+
}
1136+
11131137
struct UnusedUnsafeLintVisitor { stopping_on_items: bool }
11141138

11151139
impl SubitemStoppableVisitor for UnusedUnsafeLintVisitor {
@@ -1516,6 +1540,11 @@ struct LintCheckVisitor;
15161540

15171541
impl Visitor<@mut Context> for LintCheckVisitor {
15181542

1543+
fn visit_pat(&mut self, p:@ast::Pat, cx: @mut Context) {
1544+
check_pat_non_uppercase_statics(cx, p);
1545+
visit::walk_pat(self, p, cx);
1546+
}
1547+
15191548
fn visit_item(&mut self, it:@ast::item, cx: @mut Context) {
15201549

15211550
do cx.with_lint_attrs(it.attrs) {

src/librustc/middle/trans/cabi_arm.rs

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

11+
#[allow(non_uppercase_pattern_statics)];
12+
1113
use lib::llvm::{llvm, Integer, Pointer, Float, Double, Struct, Array};
1214
use lib::llvm::{Attribute, StructRetAttribute};
1315
use middle::trans::cabi::{FnType, LLVMType};

src/librustc/middle/trans/cabi_mips.rs

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

11+
#[allow(non_uppercase_pattern_statics)];
1112

1213
use std::libc::c_uint;
1314
use std::num;

src/librustc/middle/trans/cabi_x86_64.rs

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
// The classification code for the x86_64 ABI is taken from the clay language
1212
// https://github.com/jckarter/clay/blob/master/compiler/src/externals.cpp
1313

14+
#[allow(non_uppercase_pattern_statics)];
15+
1416
use lib::llvm::{llvm, Integer, Pointer, Float, Double};
1517
use lib::llvm::{Struct, Array, Attribute};
1618
use lib::llvm::{StructRetAttribute, ByValAttribute};

src/librustc/middle/trans/intrinsic.rs

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

11+
#[allow(non_uppercase_pattern_statics)];
12+
1113
use back::{abi};
1214
use lib::llvm::{SequentiallyConsistent, Acquire, Release, Xchg};
1315
use lib::llvm::{ValueRef, Pointer};

src/librustc/middle/trans/type_.rs

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

11+
#[allow(non_uppercase_pattern_statics)];
1112

1213
use lib::llvm::{llvm, TypeRef, Bool, False, True, TypeKind};
1314
use lib::llvm::{Float, Double, X86_FP80, PPC_FP128, FP128};

src/libstd/num/f32.rs

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//! Operations and constants for `f32`
1212
#[allow(missing_doc)];
1313
#[allow(non_uppercase_statics)];
14+
#[allow(non_uppercase_pattern_statics)];
1415

1516
use default::Default;
1617
use libc::c_int;

src/libstd/num/f64.rs

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
1313
#[allow(missing_doc)];
1414
#[allow(non_uppercase_statics)];
15+
#[allow(non_uppercase_pattern_statics)];
1516

1617
use default::Default;
1718
use libc::c_int;

src/test/compile-fail/issue-6804.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#[allow(non_uppercase_pattern_statics)];
2+
13
// Matching against NaN should result in a warning
24

35
use std::f64::NaN;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Issue #7526: lowercase static constants in patterns look like bindings
12+
13+
#[deny(non_uppercase_pattern_statics)];
14+
15+
pub static a : int = 97;
16+
17+
fn f() {
18+
let r = match (0,0) {
19+
(0, a) => 0,
20+
//~^ ERROR static constant in pattern should be all caps
21+
(x, y) => 1 + x + y,
22+
};
23+
assert!(r == 1);
24+
}
25+
26+
mod m {
27+
pub static aha : int = 7;
28+
}
29+
30+
fn g() {
31+
use self::m::aha;
32+
let r = match (0,0) {
33+
(0, aha) => 0,
34+
//~^ ERROR static constant in pattern should be all caps
35+
(x, y) => 1 + x + y,
36+
};
37+
assert!(r == 1);
38+
}
39+
40+
mod n {
41+
pub static OKAY : int = 8;
42+
}
43+
44+
fn h() {
45+
use not_okay = self::n::OKAY;
46+
let r = match (0,0) {
47+
(0, not_okay) => 0,
48+
//~^ ERROR static constant in pattern should be all caps
49+
(x, y) => 1 + x + y,
50+
};
51+
assert!(r == 1);
52+
}
53+
54+
fn main () {
55+
f();
56+
g();
57+
h();
58+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Issue #7526: lowercase static constants in patterns look like bindings
12+
13+
// This is similar to compile-fail/match-static-const-lc, except it
14+
// shows the expected usual workaround (choosing a different name for
15+
// the static definition) and also demonstrates that one can work
16+
// around this problem locally by renaming the constant in the `use`
17+
// form to an uppercase identifier that placates the lint.
18+
19+
#[deny(non_uppercase_pattern_statics)];
20+
21+
pub static A : int = 97;
22+
23+
fn f() {
24+
let r = match (0,0) {
25+
(0, A) => 0,
26+
(x, y) => 1 + x + y,
27+
};
28+
assert!(r == 1);
29+
let r = match (0,97) {
30+
(0, A) => 0,
31+
(x, y) => 1 + x + y,
32+
};
33+
assert!(r == 0);
34+
}
35+
36+
mod m {
37+
pub static aha : int = 7;
38+
}
39+
40+
fn g() {
41+
use AHA = self::m::aha;
42+
let r = match (0,0) {
43+
(0, AHA) => 0,
44+
(x, y) => 1 + x + y,
45+
};
46+
assert!(r == 1);
47+
let r = match (0,7) {
48+
(0, AHA) => 0,
49+
(x, y) => 1 + x + y,
50+
};
51+
assert!(r == 0);
52+
}
53+
54+
fn h() {
55+
let r = match (0,0) {
56+
(0, self::m::aha) => 0,
57+
(x, y) => 1 + x + y,
58+
};
59+
assert!(r == 1);
60+
let r = match (0,7) {
61+
(0, self::m::aha) => 0,
62+
(x, y) => 1 + x + y,
63+
};
64+
assert!(r == 0);
65+
}
66+
67+
pub fn main () {
68+
f();
69+
g();
70+
h();
71+
}

0 commit comments

Comments
 (0)