diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 49798288d40d0..0ce21bdf18ef9 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -11,6 +11,7 @@ // LLVM wrappers are intended to be called from trans, // which already runs in a #[fixed_stack_segment] #[allow(cstack)]; +#[allow(non_uppercase_pattern_statics)]; use std::c_str::ToCStr; use std::hashmap::HashMap; diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index c9eded645fa2d..c891e57ff39aa 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -133,6 +133,7 @@ pub fn check_arms(cx: &MatchCheckCtxt, arms: &[Arm]) { _ => false } }; + do walk_pat(*pat) |p| { if pat_matches_nan(p) { cx.tcx.sess.span_warn(p.span, "unmatchable NaN in pattern, \ diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 3c6ebc9311db5..b3d595c6efb72 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -83,6 +83,7 @@ pub enum lint { unrecognized_lint, non_camel_case_types, non_uppercase_statics, + non_uppercase_pattern_statics, type_limits, unused_unsafe, @@ -209,6 +210,13 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[ default: allow }), + ("non_uppercase_pattern_statics", + LintSpec { + lint: non_uppercase_pattern_statics, + desc: "static constants in match patterns should be all caps", + default: warn + }), + ("managed_heap_memory", LintSpec { lint: managed_heap_memory, @@ -1110,6 +1118,22 @@ fn check_item_non_uppercase_statics(cx: &Context, it: &ast::item) { } } +fn check_pat_non_uppercase_statics(cx: &Context, p: &ast::Pat) { + // Lint for constants that look like binding identifiers (#7526) + match (&p.node, cx.tcx.def_map.find(&p.id)) { + (&ast::PatIdent(_, ref path, _), Some(&ast::DefStatic(_, false))) => { + // last identifier alone is right choice for this lint. + let ident = path.segments.last().identifier; + let s = cx.tcx.sess.str_of(ident); + if s.iter().any(|c| c.is_lowercase()) { + cx.span_lint(non_uppercase_pattern_statics, path.span, + "static constant in pattern should be all caps"); + } + } + _ => {} + } +} + struct UnusedUnsafeLintVisitor { stopping_on_items: bool } impl SubitemStoppableVisitor for UnusedUnsafeLintVisitor { @@ -1516,6 +1540,11 @@ struct LintCheckVisitor; impl Visitor<@mut Context> for LintCheckVisitor { + fn visit_pat(&mut self, p:@ast::Pat, cx: @mut Context) { + check_pat_non_uppercase_statics(cx, p); + visit::walk_pat(self, p, cx); + } + fn visit_item(&mut self, it:@ast::item, cx: @mut Context) { do cx.with_lint_attrs(it.attrs) { diff --git a/src/librustc/middle/trans/cabi_arm.rs b/src/librustc/middle/trans/cabi_arm.rs index 19f0b9b78eb35..2ffff5b58381b 100644 --- a/src/librustc/middle/trans/cabi_arm.rs +++ b/src/librustc/middle/trans/cabi_arm.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[allow(non_uppercase_pattern_statics)]; + use lib::llvm::{llvm, Integer, Pointer, Float, Double, Struct, Array}; use lib::llvm::{Attribute, StructRetAttribute}; use middle::trans::cabi::{FnType, LLVMType}; diff --git a/src/librustc/middle/trans/cabi_mips.rs b/src/librustc/middle/trans/cabi_mips.rs index 4577bf11b84de..be4a6a6ec18f1 100644 --- a/src/librustc/middle/trans/cabi_mips.rs +++ b/src/librustc/middle/trans/cabi_mips.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[allow(non_uppercase_pattern_statics)]; use std::libc::c_uint; use std::num; diff --git a/src/librustc/middle/trans/cabi_x86_64.rs b/src/librustc/middle/trans/cabi_x86_64.rs index 179366878418f..7b666ea2448b4 100644 --- a/src/librustc/middle/trans/cabi_x86_64.rs +++ b/src/librustc/middle/trans/cabi_x86_64.rs @@ -11,6 +11,8 @@ // The classification code for the x86_64 ABI is taken from the clay language // https://github.com/jckarter/clay/blob/master/compiler/src/externals.cpp +#[allow(non_uppercase_pattern_statics)]; + use lib::llvm::{llvm, Integer, Pointer, Float, Double}; use lib::llvm::{Struct, Array, Attribute}; use lib::llvm::{StructRetAttribute, ByValAttribute}; diff --git a/src/librustc/middle/trans/intrinsic.rs b/src/librustc/middle/trans/intrinsic.rs index d17773d3302f1..0364251f520b1 100644 --- a/src/librustc/middle/trans/intrinsic.rs +++ b/src/librustc/middle/trans/intrinsic.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[allow(non_uppercase_pattern_statics)]; + use back::{abi}; use lib::llvm::{SequentiallyConsistent, Acquire, Release, Xchg}; use lib::llvm::{ValueRef, Pointer}; diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index 0954302ba81f4..6ccfd85712607 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[allow(non_uppercase_pattern_statics)]; use lib::llvm::{llvm, TypeRef, Bool, False, True, TypeKind}; use lib::llvm::{Float, Double, X86_FP80, PPC_FP128, FP128}; diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index afa1acd08970a..be8aa369b4bed 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -11,6 +11,7 @@ //! Operations and constants for `f32` #[allow(missing_doc)]; #[allow(non_uppercase_statics)]; +#[allow(non_uppercase_pattern_statics)]; use default::Default; use libc::c_int; diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index 5dbeb6c298f8f..18d0037469d20 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -12,6 +12,7 @@ #[allow(missing_doc)]; #[allow(non_uppercase_statics)]; +#[allow(non_uppercase_pattern_statics)]; use default::Default; use libc::c_int; diff --git a/src/test/compile-fail/issue-6804.rs b/src/test/compile-fail/issue-6804.rs index db72740f483c2..e239385fa5867 100644 --- a/src/test/compile-fail/issue-6804.rs +++ b/src/test/compile-fail/issue-6804.rs @@ -1,3 +1,5 @@ +#[allow(non_uppercase_pattern_statics)]; + // Matching against NaN should result in a warning use std::float::NaN; diff --git a/src/test/compile-fail/match-static-const-lc.rs b/src/test/compile-fail/match-static-const-lc.rs new file mode 100644 index 0000000000000..1cdceaca6b4b5 --- /dev/null +++ b/src/test/compile-fail/match-static-const-lc.rs @@ -0,0 +1,58 @@ +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Issue #7526: lowercase static constants in patterns look like bindings + +#[deny(non_uppercase_pattern_statics)]; + +pub static a : int = 97; + +fn f() { + let r = match (0,0) { + (0, a) => 0, + //~^ ERROR static constant in pattern should be all caps + (x, y) => 1 + x + y, + }; + assert!(r == 1); +} + +mod m { + pub static aha : int = 7; +} + +fn g() { + use self::m::aha; + let r = match (0,0) { + (0, aha) => 0, + //~^ ERROR static constant in pattern should be all caps + (x, y) => 1 + x + y, + }; + assert!(r == 1); +} + +mod n { + pub static OKAY : int = 8; +} + +fn h() { + use not_okay = self::n::OKAY; + let r = match (0,0) { + (0, not_okay) => 0, + //~^ ERROR static constant in pattern should be all caps + (x, y) => 1 + x + y, + }; + assert!(r == 1); +} + +fn main () { + f(); + g(); + h(); +} diff --git a/src/test/run-pass/match-static-const-rename.rs b/src/test/run-pass/match-static-const-rename.rs new file mode 100644 index 0000000000000..df62ba7298d29 --- /dev/null +++ b/src/test/run-pass/match-static-const-rename.rs @@ -0,0 +1,71 @@ +// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Issue #7526: lowercase static constants in patterns look like bindings + +// This is similar to compile-fail/match-static-const-lc, except it +// shows the expected usual workaround (choosing a different name for +// the static definition) and also demonstrates that one can work +// around this problem locally by renaming the constant in the `use` +// form to an uppercase identifier that placates the lint. + +#[deny(non_uppercase_pattern_statics)]; + +pub static A : int = 97; + +fn f() { + let r = match (0,0) { + (0, A) => 0, + (x, y) => 1 + x + y, + }; + assert!(r == 1); + let r = match (0,97) { + (0, A) => 0, + (x, y) => 1 + x + y, + }; + assert!(r == 0); +} + +mod m { + pub static aha : int = 7; +} + +fn g() { + use AHA = self::m::aha; + let r = match (0,0) { + (0, AHA) => 0, + (x, y) => 1 + x + y, + }; + assert!(r == 1); + let r = match (0,7) { + (0, AHA) => 0, + (x, y) => 1 + x + y, + }; + assert!(r == 0); +} + +fn h() { + let r = match (0,0) { + (0, self::m::aha) => 0, + (x, y) => 1 + x + y, + }; + assert!(r == 1); + let r = match (0,7) { + (0, self::m::aha) => 0, + (x, y) => 1 + x + y, + }; + assert!(r == 0); +} + +pub fn main () { + f(); + g(); + h(); +}