diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 49798288d40d0820b4343e4911b787be5176ab33..0ce21bdf18ef948d0218945056cb89d66a2f87c5 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 c9eded645fa2d84a45f8690285b1a71036fce532..573d2a529d4b2623c2ab8a9d46fe5d6eec7a2bdd 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -11,6 +11,7 @@ use middle::const_eval::{compare_const_vals, lookup_const_by_id}; use middle::const_eval::{eval_const_expr, const_val, const_bool, const_float}; +use middle::lint::non_uppercase_pattern_statics; use middle::pat_util::*; use middle::ty::*; use middle::ty; @@ -133,11 +134,30 @@ pub fn check_arms(cx: &MatchCheckCtxt, arms: &[Arm]) { _ => false } }; + + // Lint for constants that look like binding identifiers (#7526) + let pat_matches_non_uppercase_static: &fn(@Pat) = |p| { + let msg = "static constant in pattern should have an uppercase identifier"; + match (&p.node, cx.tcx.def_map.find(&p.id)) { + (&PatIdent(_, ref path, _), Some(&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.tcx.sess.add_lint(non_uppercase_pattern_statics, + p.id, path.span, msg.to_owned()); + } + } + _ => {} + } + }; + do walk_pat(*pat) |p| { if pat_matches_nan(p) { cx.tcx.sess.span_warn(p.span, "unmatchable NaN in pattern, \ use the is_nan method in a guard instead"); } + pat_matches_non_uppercase_static(p); true }; diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 3c6ebc9311db59c3da9e0fa99ab93e2a932a9d5d..340cf361a08d4d820bcec4eb3b07decf54d92274 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 @@ enum LintSource { default: allow }), + ("non_uppercase_pattern_statics", + LintSpec { + lint: non_uppercase_pattern_statics, + desc: "static constants in match patterns should be uppercased", + default: warn + }), + ("managed_heap_memory", LintSpec { lint: managed_heap_memory, diff --git a/src/librustc/middle/trans/cabi_arm.rs b/src/librustc/middle/trans/cabi_arm.rs index 19f0b9b78eb353baa4c4bd3d12ed7bf47ab1017c..2ffff5b58381be17f7750509c0fad96bdca88bc6 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 4577bf11b84de8b7a5c5b78efb22b3d5e7c9ca33..be4a6a6ec18f1cb06f85ffb2b26c282095cb4467 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 179366878418f0a879d0481a7454925480c613c5..7b666ea2448b4ae432d12945d989b1e6a214c742 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 d17773d3302f1f480c949520c06c39548e1c6509..0364251f520b17606c2e050406036f83521d22c8 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 0954302ba81f438cebfdc629de38db1d2bc37c66..6ccfd857126072fef522e63eea90af4d7c28cf6a 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 afa1acd08970ae3eedee9f0ad6b6e4adf1b8be79..be8aa369b4bedc4cc1a8ec0262e00f56f56a7249 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 5dbeb6c298f8f97fd42b5ffe1119bba3282f42d1..18d0037469d20192cbdf5986974f139d15125e10 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/match-static-const-lc.rs b/src/test/compile-fail/match-static-const-lc.rs new file mode 100644 index 0000000000000000000000000000000000000000..02be27b7ce2832c921664c3f944e900a55a444ef --- /dev/null +++ b/src/test/compile-fail/match-static-const-lc.rs @@ -0,0 +1,43 @@ +// 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 have an uppercase id + (x, y) => 1 + x + y, + }; + assert!(r == 1); +} + +mod m { + pub static aha : int = 7; +} + +fn g() { + use m::aha; + let r = match (0,0) { + (0, aha) => 0, + //~^ ERROR static constant in pattern should have an uppercase id + (x, y) => 1 + x + y, + }; + assert!(r == 1); +} + +fn main () { + f(); + g(); +} 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 0000000000000000000000000000000000000000..305a20b6642e2d3826a511420826a0b0aed69a22 --- /dev/null +++ b/src/test/run-pass/match-static-const-rename.rs @@ -0,0 +1,47 @@ +// 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 reanming 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); +} + +mod m { + pub static aha : int = 7; +} + +fn g() { + use AHA = m::aha; + let r = match (0,0) { + (0, AHA) => 0, + (x, y) => 1 + x + y, + }; + assert!(r == 1); +} + +fn main () { + f(); + g(); +}