about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-05-02 16:51:50 -0700
committerbors <bors@rust-lang.org>2014-05-02 16:51:50 -0700
commite0d261e576817817bf3433deee6a1434cec47002 (patch)
treeb4fadad3eb542e939c54f5050495891fa7b9dd49
parentb5d6b07370b665df6b54fa20e971e61041a233b0 (diff)
parent6c26cbb6026194a280fa0f33c794d4397ad426da (diff)
downloadrust-e0d261e576817817bf3433deee6a1434cec47002.tar.gz
rust-e0d261e576817817bf3433deee6a1434cec47002.zip
auto merge of #13579 : hirschenberger/rust/lint_unsigned_negate, r=alexcrichton
See #11273 and #13318
-rw-r--r--src/libnative/io/timer_win32.rs6
-rw-r--r--src/librustc/middle/const_eval.rs1
-rw-r--r--src/librustc/middle/lint.rs31
-rw-r--r--src/librustc/middle/trans/adt.rs2
-rw-r--r--src/libstd/fmt/num.rs2
-rw-r--r--src/libstd/num/f32.rs1
-rw-r--r--src/libstd/num/u16.rs1
-rw-r--r--src/libstd/num/u32.rs1
-rw-r--r--src/libstd/num/u64.rs1
-rw-r--r--src/libstd/num/u8.rs1
-rw-r--r--src/libstd/num/uint.rs1
-rw-r--r--src/libstd/num/uint_macros.rs1
-rw-r--r--src/libstd/rt/thread.rs1
-rw-r--r--src/test/compile-fail/lint-type-limits.rs11
14 files changed, 58 insertions, 3 deletions
diff --git a/src/libnative/io/timer_win32.rs b/src/libnative/io/timer_win32.rs
index 588ec367d81..15e6e62421a 100644
--- a/src/libnative/io/timer_win32.rs
+++ b/src/libnative/io/timer_win32.rs
@@ -137,7 +137,7 @@ impl rtio::RtioTimer for Timer {
 
         // there are 10^6 nanoseconds in a millisecond, and the parameter is in
         // 100ns intervals, so we multiply by 10^4.
-        let due = -(msecs * 10000) as libc::LARGE_INTEGER;
+        let due = -(msecs as i64 * 10000) as libc::LARGE_INTEGER;
         assert_eq!(unsafe {
             imp::SetWaitableTimer(self.obj, &due, 0, ptr::null(),
                                   ptr::mut_null(), 0)
@@ -151,7 +151,7 @@ impl rtio::RtioTimer for Timer {
         let (tx, rx) = channel();
 
         // see above for the calculation
-        let due = -(msecs * 10000) as libc::LARGE_INTEGER;
+        let due = -(msecs as i64 * 10000) as libc::LARGE_INTEGER;
         assert_eq!(unsafe {
             imp::SetWaitableTimer(self.obj, &due, 0, ptr::null(),
                                   ptr::mut_null(), 0)
@@ -167,7 +167,7 @@ impl rtio::RtioTimer for Timer {
         let (tx, rx) = channel();
 
         // see above for the calculation
-        let due = -(msecs * 10000) as libc::LARGE_INTEGER;
+        let due = -(msecs as i64 * 10000) as libc::LARGE_INTEGER;
         assert_eq!(unsafe {
             imp::SetWaitableTimer(self.obj, &due, msecs as libc::LONG,
                                   ptr::null(), ptr::mut_null(), 0)
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs
index 56284984a24..7f083865d14 100644
--- a/src/librustc/middle/const_eval.rs
+++ b/src/librustc/middle/const_eval.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 #![allow(non_camel_case_types)]
+#![allow(unsigned_negate)]
 
 use metadata::csearch;
 use middle::astencode;
diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs
index ff84a7b0ca4..93e8c637f17 100644
--- a/src/librustc/middle/lint.rs
+++ b/src/librustc/middle/lint.rs
@@ -91,6 +91,7 @@ pub enum Lint {
     AttributeUsage,
     UnknownFeatures,
     UnknownCrateType,
+    UnsignedNegate,
 
     ManagedHeapMemory,
     OwnedHeapMemory,
@@ -390,6 +391,13 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[
         default: deny,
     }),
 
+    ("unsigned_negate",
+    LintSpec {
+        lint: UnsignedNegate,
+        desc: "using an unary minus operator on unsigned type",
+        default: warn
+    }),
+
     ("unused_must_use",
     LintSpec {
         lint: UnusedMustUse,
@@ -704,6 +712,29 @@ fn check_unused_casts(cx: &Context, e: &ast::Expr) {
 
 fn check_type_limits(cx: &Context, e: &ast::Expr) {
     return match e.node {
+        ast::ExprUnary(ast::UnNeg, ex) => {
+            match ex.node  {
+                ast::ExprLit(lit) => {
+                    match lit.node {
+                        ast::LitUint(..) => {
+                            cx.span_lint(UnsignedNegate, e.span,
+                                         "negation of unsigned int literal may be unintentional");
+                        },
+                        _ => ()
+                    }
+                },
+                _ => {
+                    let t = ty::expr_ty(cx.tcx, ex);
+                    match ty::get(t).sty {
+                        ty::ty_uint(_) => {
+                            cx.span_lint(UnsignedNegate, e.span,
+                                         "negation of unsigned int variable may be unintentional");
+                        },
+                        _ => ()
+                    }
+                }
+            }
+        },
         ast::ExprBinary(binop, l, r) => {
             if is_comparison(binop) && !check_limits(cx.tcx, binop, l, r) {
                 cx.span_lint(TypeLimits, e.span,
diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs
index 03fc85126a4..2791e79907f 100644
--- a/src/librustc/middle/trans/adt.rs
+++ b/src/librustc/middle/trans/adt.rs
@@ -43,6 +43,8 @@
  *   taken to it, implementing them for Rust seems difficult.
  */
 
+#![allow(unsigned_negate)]
+
 use std::container::Map;
 use libc::c_ulonglong;
 use std::num::{Bitwise};
diff --git a/src/libstd/fmt/num.rs b/src/libstd/fmt/num.rs
index 9000d2c8737..2032a2a6b58 100644
--- a/src/libstd/fmt/num.rs
+++ b/src/libstd/fmt/num.rs
@@ -12,6 +12,8 @@
 
 // FIXME: #6220 Implement floating point formatting
 
+#![allow(unsigned_negate)]
+
 use container::Container;
 use fmt;
 use iter::{Iterator, DoubleEndedIterator};
diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs
index 36e5728200b..672de0bf9e5 100644
--- a/src/libstd/num/f32.rs
+++ b/src/libstd/num/f32.rs
@@ -11,6 +11,7 @@
 //! Operations and constants for 32-bits floats (`f32` type)
 
 #![allow(missing_doc)]
+#![allow(unsigned_negate)]
 
 use prelude::*;
 
diff --git a/src/libstd/num/u16.rs b/src/libstd/num/u16.rs
index ca473e9517e..14a432905b4 100644
--- a/src/libstd/num/u16.rs
+++ b/src/libstd/num/u16.rs
@@ -11,6 +11,7 @@
 //! Operations and constants for unsigned 16-bits integers (`u16` type)
 
 #![allow(non_uppercase_statics)]
+#![allow(unsigned_negate)]
 
 use prelude::*;
 
diff --git a/src/libstd/num/u32.rs b/src/libstd/num/u32.rs
index 2a0b9aac667..87740dcb135 100644
--- a/src/libstd/num/u32.rs
+++ b/src/libstd/num/u32.rs
@@ -11,6 +11,7 @@
 //! Operations and constants for unsigned 32-bits integers (`u32` type)
 
 #![allow(non_uppercase_statics)]
+#![allow(unsigned_negate)]
 
 use prelude::*;
 
diff --git a/src/libstd/num/u64.rs b/src/libstd/num/u64.rs
index 2cfc5da95e8..15b2528e616 100644
--- a/src/libstd/num/u64.rs
+++ b/src/libstd/num/u64.rs
@@ -11,6 +11,7 @@
 //! Operations and constants for unsigned 64-bits integer (`u64` type)
 
 #![allow(non_uppercase_statics)]
+#![allow(unsigned_negate)]
 
 use prelude::*;
 
diff --git a/src/libstd/num/u8.rs b/src/libstd/num/u8.rs
index 30ed13a5952..f841a31ee13 100644
--- a/src/libstd/num/u8.rs
+++ b/src/libstd/num/u8.rs
@@ -11,6 +11,7 @@
 //! Operations and constants for unsigned 8-bits integers (`u8` type)
 
 #![allow(non_uppercase_statics)]
+#![allow(unsigned_negate)]
 
 use prelude::*;
 
diff --git a/src/libstd/num/uint.rs b/src/libstd/num/uint.rs
index 6751fdb5d25..46cb4f44887 100644
--- a/src/libstd/num/uint.rs
+++ b/src/libstd/num/uint.rs
@@ -11,6 +11,7 @@
 //! Operations and constants for architecture-sized unsigned integers (`uint` type)
 
 #![allow(non_uppercase_statics)]
+#![allow(unsigned_negate)]
 
 use prelude::*;
 
diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs
index 8acedb080c2..fac8736b929 100644
--- a/src/libstd/num/uint_macros.rs
+++ b/src/libstd/num/uint_macros.rs
@@ -10,6 +10,7 @@
 
 #![macro_escape]
 #![doc(hidden)]
+#![allow(unsigned_negate)]
 
 macro_rules! uint_module (($T:ty, $T_SIGNED:ty, $bits:expr) => (
 
diff --git a/src/libstd/rt/thread.rs b/src/libstd/rt/thread.rs
index 2d952b2a9db..9f5986e3dc6 100644
--- a/src/libstd/rt/thread.rs
+++ b/src/libstd/rt/thread.rs
@@ -15,6 +15,7 @@
 //! which are not used for scheduling in any way.
 
 #![allow(non_camel_case_types)]
+#![allow(unsigned_negate)]
 
 use cast;
 use kinds::Send;
diff --git a/src/test/compile-fail/lint-type-limits.rs b/src/test/compile-fail/lint-type-limits.rs
index 8cca39a7a25..1aaf68d7c1a 100644
--- a/src/test/compile-fail/lint-type-limits.rs
+++ b/src/test/compile-fail/lint-type-limits.rs
@@ -36,3 +36,14 @@ fn qux() {
         i += 1;
     }
 }
+
+fn quy() {
+    let i = -23u; //~ WARNING negation of unsigned int literal may be unintentional
+                  //~^ WARNING unused variable
+}
+
+fn quz() {
+    let i = 23u;
+    let j = -i;   //~ WARNING negation of unsigned int variable may be unintentional
+                  //~^ WARNING unused variable
+}