about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFelix S. Klock II <pnkfelix@pnkfx.org>2013-09-30 17:44:58 +0200
committerFelix S. Klock II <pnkfelix@pnkfx.org>2013-10-01 01:44:25 +0200
commita076fef2b647399f2fb0575830fb07320fb3b6f5 (patch)
tree714c1b311605131ae37b75c6248c93368d2be82c
parent8174618a05c44a9b90806aa7b848cb9b7ab62d25 (diff)
downloadrust-a076fef2b647399f2fb0575830fb07320fb3b6f5.tar.gz
rust-a076fef2b647399f2fb0575830fb07320fb3b6f5.zip
Add new lint: non_uppercase_pattern_statics, for #7526.
This tries to warn about code like:
    ```rust
    match (0,0) {
        (0, aha) => { ... },
        ...
    }
    ```
where `aha` is actually a static constant, not a binding.
-rw-r--r--src/librustc/lib/llvm.rs1
-rw-r--r--src/librustc/middle/check_match.rs20
-rw-r--r--src/librustc/middle/lint.rs8
-rw-r--r--src/librustc/middle/trans/cabi_arm.rs2
-rw-r--r--src/librustc/middle/trans/cabi_mips.rs1
-rw-r--r--src/librustc/middle/trans/cabi_x86_64.rs2
-rw-r--r--src/librustc/middle/trans/intrinsic.rs2
-rw-r--r--src/librustc/middle/trans/type_.rs1
-rw-r--r--src/libstd/num/f32.rs1
-rw-r--r--src/libstd/num/f64.rs1
-rw-r--r--src/test/compile-fail/match-static-const-lc.rs43
-rw-r--r--src/test/run-pass/match-static-const-rename.rs47
12 files changed, 129 insertions, 0 deletions
diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs
index 49798288d40..0ce21bdf18e 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 c9eded645fa..573d2a529d4 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 3c6ebc9311d..340cf361a08 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 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 19f0b9b78eb..2ffff5b5838 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 4577bf11b84..be4a6a6ec18 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 17936687841..7b666ea2448 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 d17773d3302..0364251f520 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 0954302ba81..6ccfd857126 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 afa1acd0897..be8aa369b4b 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 5dbeb6c298f..18d0037469d 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 00000000000..02be27b7ce2
--- /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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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 00000000000..305a20b6642
--- /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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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();
+}