From d8e309320d55e08f5bbda2f18b20a3a64198061e Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 1 Apr 2015 01:32:41 +0200 Subject: [PATCH 1/9] added unary_negate feature gate. --- src/librustc_typeck/check/mod.rs | 10 ++++++++++ src/libsyntax/feature_gate.rs | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index fbff4e84788..d6b14e84d91 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -120,6 +120,7 @@ use syntax::ast::{self, DefId, Visibility}; use syntax::ast_util::{self, local_def}; use syntax::codemap::{self, Span}; +use syntax::feature_gate; use syntax::owned_slice::OwnedSlice; use syntax::parse::token; use syntax::print::pprust; @@ -3258,6 +3259,15 @@ fn check_struct_fields_on_error<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, tcx.lang_items.neg_trait(), expr, &**oprnd, oprnd_t, unop); } + if let ty::ty_uint(_) = oprnd_t.sty { + if !tcx.sess.features.borrow().negate_unsigned { + feature_gate::emit_feature_err( + &tcx.sess.parse_sess.span_diagnostic, + "negate_unsigned", + expr.span, + "unary negation of unsigned integers may be removed in the future"); + } + } } } } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index f88381fb36f..adcef07e190 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -150,6 +150,9 @@ // #23121. Array patterns have some hazards yet. ("slice_patterns", "1.0.0", Active), + + // Allows use of unary negate on unsigned integers, e.g. -e for e: u8 + ("negate_unsigned", "1.0.0", Active), ]; // (changing above list without updating src/doc/reference.md makes @cmr sad) @@ -319,6 +322,7 @@ pub struct Features { pub allow_custom_derive: bool, pub simd_ffi: bool, pub unmarked_api: bool, + pub negate_unsigned: bool, /// spans of #![feature] attrs for stable language features. for error reporting pub declared_stable_lang_features: Vec, /// #![feature] attrs for non-language (library) features @@ -340,6 +344,7 @@ pub fn new() -> Features { allow_custom_derive: false, simd_ffi: false, unmarked_api: false, + negate_unsigned: false, declared_stable_lang_features: Vec::new(), declared_lib_features: Vec::new() } @@ -712,6 +717,7 @@ fn check_crate_inner(cm: &CodeMap, span_handler: &SpanHandler, allow_custom_derive: cx.has_feature("custom_derive"), simd_ffi: cx.has_feature("simd_ffi"), unmarked_api: cx.has_feature("unmarked_api"), + negate_unsigned: cx.has_feature("negate_unsigned"), declared_stable_lang_features: accepted_features, declared_lib_features: unknown_features } From 3225b04c7d335b8f6e224c7d90ab95717ed84cc3 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 1 Apr 2015 12:36:37 +0200 Subject: [PATCH 2/9] fallout from feature-gating unary negation on unsigned integers. --- src/libcollections/slice.rs | 2 +- src/libcore/atomic.rs | 2 +- src/libcore/cell.rs | 2 +- src/libcore/num/mod.rs | 2 +- src/libcore/ops.rs | 24 ++++++++++++++++++++---- src/libcore/str/mod.rs | 2 +- src/liblibc/lib.rs | 2 +- src/libstd/rt/mod.rs | 2 +- 8 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 4599aff000d..29301bfd6fe 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -1123,7 +1123,7 @@ impl Iterator for ElementSwaps { // #[inline] fn next(&mut self) -> Option<(usize, usize)> { fn new_pos_wrapping(i: usize, s: Direction) -> usize { - i.wrapping_add(match s { Pos => 1, Neg => -1 }) + i.wrapping_add(match s { Pos => 1, Neg => !0 /* aka -1 */ }) } fn new_pos(i: usize, s: Direction) -> usize { diff --git a/src/libcore/atomic.rs b/src/libcore/atomic.rs index 8c396a4e7fb..d738ff947c4 100644 --- a/src/libcore/atomic.rs +++ b/src/libcore/atomic.rs @@ -161,7 +161,7 @@ pub enum Ordering { AtomicUsize { v: UnsafeCell { value: 0, } }; // NB: Needs to be -1 (0b11111111...) to make fetch_nand work correctly -const UINT_TRUE: usize = -1; +const UINT_TRUE: usize = !0; impl AtomicBool { /// Creates a new `AtomicBool`. diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 906c87f3ffd..76e09eedbdf 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -287,7 +287,7 @@ pub enum BorrowState { // (will not outgrow its range since `usize` is the size of the address space) type BorrowFlag = usize; const UNUSED: BorrowFlag = 0; -const WRITING: BorrowFlag = -1; +const WRITING: BorrowFlag = !0; impl RefCell { /// Creates a new `RefCell` containing `value`. diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index a4829ed96b3..13f168b3fdb 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -517,7 +517,7 @@ fn one() -> $T { 1 } fn min_value() -> $T { 0 } #[inline] - fn max_value() -> $T { -1 } + fn max_value() -> $T { !0 } #[inline] fn count_ones(self) -> u32 { diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 862eb16d0bf..e1a9efd69ad 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -482,8 +482,10 @@ pub trait Neg { fn neg(self) -> Self::Output; } -macro_rules! neg_impl { - ($($t:ty)*) => ($( + + +macro_rules! neg_impl_core { + ($id:ident => $body:expr, $($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] #[allow(unsigned_negation)] impl Neg for $t { @@ -492,14 +494,28 @@ impl Neg for $t { #[inline] #[stable(feature = "rust1", since = "1.0.0")] - fn neg(self) -> $t { -self } + fn neg(self) -> $t { let $id = self; $body } } forward_ref_unop! { impl Neg, neg for $t } )*) } -neg_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 } +macro_rules! neg_impl_numeric { + ($($t:ty)*) => { neg_impl_core!{ x => -x, $($t)*} } +} + +macro_rules! neg_impl_unsigned { + ($($t:ty)*) => { + neg_impl_core!{ x => { + #[cfg(stage0)] + use ::num::wrapping::WrappingOps; + !x.wrapping_add(1) + }, $($t)*} } +} + +neg_impl_unsigned! { usize u8 u16 u32 u64 } +neg_impl_numeric! { isize i8 i16 i32 i64 f32 f64 } /// The `Not` trait is used to specify the functionality of unary `!`. /// diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 934c4515614..c78fa803361 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -873,7 +873,7 @@ fn next(&mut self, haystack: &[u8], needle: &[u8], long_period: bool) #[allow(dead_code)] #[allow(deprecated)] fn maximal_suffix(arr: &[u8], reversed: bool) -> (usize, usize) { - let mut left: usize = -1; // Corresponds to i in the paper + let mut left: usize = !0; // Corresponds to i in the paper let mut right = 0; // Corresponds to j in the paper let mut offset = 1; // Corresponds to k in the paper let mut period = 1; // Corresponds to p in the paper diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index b7162c4a177..77e18be298b 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -4696,7 +4696,7 @@ pub mod posix88 { pub const MAP_FIXED : c_int = 0x0010; pub const MAP_ANON : c_int = 0x1000; - pub const MAP_FAILED : *mut c_void = -1 as *mut c_void; + pub const MAP_FAILED : *mut c_void = !0 as *mut c_void; pub const MCL_CURRENT : c_int = 0x0001; pub const MCL_FUTURE : c_int = 0x0002; diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index 696c7960c3e..7ea77a79619 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -117,7 +117,7 @@ fn lang_start(main: *const u8, argc: isize, argv: *const *const u8) -> isize { use libc; use libc::funcs::posix01::signal::signal; unsafe { - assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != -1); + assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != !0); } } ignore_sigpipe(); From 98dd376f9c3b2eb4a351d836bcb0be03686dcf97 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 1 Apr 2015 19:53:32 +0200 Subject: [PATCH 3/9] fallout when bootstrapping `rustc`. --- src/librustc/middle/const_eval.rs | 12 +++++++++++- src/librustc_lint/builtin.rs | 2 +- src/librustc_trans/trans/adt.rs | 2 +- src/librustc_trans/trans/base.rs | 4 ++-- src/librustc_trans/trans/context.rs | 2 +- src/libsyntax/ast.rs | 2 +- src/libsyntax/codemap.rs | 4 ++-- 7 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index e3e5efc53c7..214ea163232 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -23,6 +23,7 @@ use syntax::ast::{self, Expr}; use syntax::codemap::Span; +use syntax::feature_gate; use syntax::parse::token::InternedString; use syntax::ptr::P; use syntax::{ast_map, ast_util, codemap}; @@ -594,7 +595,16 @@ fn fromb(b: bool) -> const_val { const_int(b as i64) } match try!(eval_const_expr_partial(tcx, &**inner, ety)) { const_float(f) => const_float(-f), const_int(n) => try!(const_int_checked_neg(n, e, expr_int_type)), - const_uint(n) => try!(const_uint_checked_neg(n, e, expr_uint_type)), + const_uint(i) => { + if !tcx.sess.features.borrow().negate_unsigned { + feature_gate::emit_feature_err( + &tcx.sess.parse_sess.span_diagnostic, + "negate_unsigned", + e.span, + "unary negation of unsigned integers may be removed in the future"); + } + const_uint(n) => try!(const_uint_checked_neg(n, e, expr_uint_type)), + } const_str(_) => signal!(e, NegateOnString), const_bool(_) => signal!(e, NegateOnBoolean), const_binary(_) => signal!(e, NegateOnBinary), diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index e7443af3013..cc22f8ff809 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -116,7 +116,7 @@ pub struct TypeLimits { impl TypeLimits { pub fn new() -> TypeLimits { TypeLimits { - negated_expr_id: -1, + negated_expr_id: !0, } } } diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs index e32d8e2b9cf..fd1fff308df 100644 --- a/src/librustc_trans/trans/adt.rs +++ b/src/librustc_trans/trans/adt.rs @@ -830,7 +830,7 @@ fn load_discr(bcx: Block, ity: IntType, ptr: ValueRef, min: Disr, max: Disr) let bits = machine::llbitsize_of_real(bcx.ccx(), llty); assert!(bits <= 64); let bits = bits as usize; - let mask = (-1u64 >> (64 - bits)) as Disr; + let mask = (!0u64 >> (64 - bits)) as Disr; // For a (max) discr of -1, max will be `-1 as usize`, which overflows. // However, that is fine here (it would still represent the full range), if (max.wrapping_add(1)) & mask == min & mask { diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 20677ab93fc..51db1430ae2 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -868,7 +868,7 @@ pub fn fail_if_zero_or_overflows<'blk, 'tcx>( _ => unreachable!(), }; let minus_one = ICmp(bcx, llvm::IntEQ, rhs, - C_integral(llty, -1, false), debug_loc); + C_integral(llty, !0, false), debug_loc); with_cond(bcx, minus_one, |bcx| { let is_min = ICmp(bcx, llvm::IntEQ, lhs, C_integral(llty, min, true), debug_loc); @@ -1388,7 +1388,7 @@ pub fn new_fn_ctxt<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>, common::validate_substs(param_substs); debug!("new_fn_ctxt(path={}, id={}, param_substs={})", - if id == -1 { + if id == !0 { "".to_string() } else { ccx.tcx().map.path_to_string(id).to_string() diff --git a/src/librustc_trans/trans/context.rs b/src/librustc_trans/trans/context.rs index 3542bcd081f..8919a386a45 100644 --- a/src/librustc_trans/trans/context.rs +++ b/src/librustc_trans/trans/context.rs @@ -459,7 +459,7 @@ fn dummy_ccx<'a>(&'a self, shared: &'a SharedCrateContext<'tcx>) CrateContext { shared: shared, local: self, - index: -1 as usize, + index: !0 as usize, } } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index ce1539c62f8..40390765dde 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -388,7 +388,7 @@ pub fn local_id(&self) -> NodeId { /// When parsing and doing expansions, we initially give all AST nodes this AST /// node value. Then later, in the renumber pass, we renumber them to have /// small, positive ids. -pub const DUMMY_NODE_ID: NodeId = -1; +pub const DUMMY_NODE_ID: NodeId = !0; /// The AST represents all type param bounds as types. /// typeck::collect::compute_bounds matches these against diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 6a00fff1860..c2f2c51ed2c 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -278,9 +278,9 @@ pub struct ExpnInfo { #[derive(PartialEq, Eq, Clone, Debug, Hash, RustcEncodable, RustcDecodable, Copy)] pub struct ExpnId(u32); -pub const NO_EXPANSION: ExpnId = ExpnId(-1); +pub const NO_EXPANSION: ExpnId = ExpnId(!0); // For code appearing from the command line -pub const COMMAND_LINE_EXPN: ExpnId = ExpnId(-2); +pub const COMMAND_LINE_EXPN: ExpnId = ExpnId(!1); impl ExpnId { pub fn from_llvm_cookie(cookie: c_uint) -> ExpnId { From a98e4713bff40f006d48d195c5af387b93d9c907 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 1 Apr 2015 22:33:37 +0200 Subject: [PATCH 4/9] removed impls of `Neg` for `u{8,16,32,64,size}`. --- src/libcore/ops.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index e1a9efd69ad..277f7db8fd4 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -514,7 +514,7 @@ macro_rules! neg_impl_unsigned { }, $($t)*} } } -neg_impl_unsigned! { usize u8 u16 u32 u64 } +// neg_impl_unsigned! { usize u8 u16 u32 u64 } neg_impl_numeric! { isize i8 i16 i32 i64 f32 f64 } /// The `Not` trait is used to specify the functionality of unary `!`. From 1c11748a54027dc5f89185dcbb39ff8996d71515 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 1 Apr 2015 22:52:37 +0200 Subject: [PATCH 5/9] fix typo. --- src/librustc/middle/const_eval.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 214ea163232..fb742b6737f 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -603,7 +603,7 @@ fn fromb(b: bool) -> const_val { const_int(b as i64) } e.span, "unary negation of unsigned integers may be removed in the future"); } - const_uint(n) => try!(const_uint_checked_neg(n, e, expr_uint_type)), + try!(const_uint_checked_neg(i, e, expr_uint_type)) } const_str(_) => signal!(e, NegateOnString), const_bool(_) => signal!(e, NegateOnBoolean), From b85c4d16d52c7f0a3fec5d4ce4d686f0a70fa512 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 1 Apr 2015 23:47:19 +0200 Subject: [PATCH 6/9] Fix bug in `OverflowOps` impl for unsigned integers. Namely, the special case treatment for `div`/`rem` is only applicable to signed integer values. Clearly RFC 1027 would have saved us here! ;) --- src/libcore/num/wrapping.rs | 52 ++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/src/libcore/num/wrapping.rs b/src/libcore/num/wrapping.rs index a78eed8ae5f..28276d0bf01 100644 --- a/src/libcore/num/wrapping.rs +++ b/src/libcore/num/wrapping.rs @@ -30,7 +30,7 @@ use intrinsics::{i32_mul_with_overflow, u32_mul_with_overflow}; use intrinsics::{i64_mul_with_overflow, u64_mul_with_overflow}; -use ::{i8,i16,i32,i64,u8,u16,u32,u64}; +use ::{i8,i16,i32,i64}; #[unstable(feature = "core", reason = "may be removed, renamed, or relocated")] #[deprecated(since = "1.0.0", reason = "moved to inherent methods")] @@ -206,7 +206,7 @@ mod shift_max { pub const u64: u32 = i64; } -macro_rules! overflowing_impl { +macro_rules! signed_overflowing_impl { ($($t:ident)*) => ($( impl OverflowingOps for $t { #[inline(always)] @@ -259,7 +259,53 @@ fn overflowing_shr(self, rhs: u32) -> ($t, bool) { )*) } -overflowing_impl! { u8 u16 u32 u64 i8 i16 i32 i64 } +macro_rules! unsigned_overflowing_impl { + ($($t:ident)*) => ($( + impl OverflowingOps for $t { + #[inline(always)] + fn overflowing_add(self, rhs: $t) -> ($t, bool) { + unsafe { + concat_idents!($t, _add_with_overflow)(self, rhs) + } + } + #[inline(always)] + fn overflowing_sub(self, rhs: $t) -> ($t, bool) { + unsafe { + concat_idents!($t, _sub_with_overflow)(self, rhs) + } + } + #[inline(always)] + fn overflowing_mul(self, rhs: $t) -> ($t, bool) { + unsafe { + concat_idents!($t, _mul_with_overflow)(self, rhs) + } + } + + #[inline(always)] + fn overflowing_div(self, rhs: $t) -> ($t, bool) { + (self/rhs, false) + } + #[inline(always)] + fn overflowing_rem(self, rhs: $t) -> ($t, bool) { + (self % rhs, false) + } + + #[inline(always)] + fn overflowing_shl(self, rhs: u32) -> ($t, bool) { + (self << (rhs & self::shift_max::$t), + (rhs > self::shift_max::$t)) + } + #[inline(always)] + fn overflowing_shr(self, rhs: u32) -> ($t, bool) { + (self >> (rhs & self::shift_max::$t), + (rhs > self::shift_max::$t)) + } + } + )*) +} + +signed_overflowing_impl! { i8 i16 i32 i64 } +unsigned_overflowing_impl! { u8 u16 u32 u64 } #[cfg(target_pointer_width = "64")] impl OverflowingOps for usize { From c8bf5f5d9742ea94a8a024ff1d9776090718c61d Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Thu, 2 Apr 2015 01:09:05 +0200 Subject: [PATCH 7/9] partial set of fixes for fallout in tests/run-pass --- src/test/run-pass/big-literals.rs | 8 ++++---- src/test/run-pass/bitwise.rs | 1 + src/test/run-pass/intrinsics-integer.rs | 1 + src/test/run-pass/issue-17074.rs | 8 ++++---- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/test/run-pass/big-literals.rs b/src/test/run-pass/big-literals.rs index b73eac0c714..ab9d892ce2b 100644 --- a/src/test/run-pass/big-literals.rs +++ b/src/test/run-pass/big-literals.rs @@ -16,10 +16,10 @@ #![deny(overflowing_literals)] pub fn main() { - assert_eq!(0xffffffff, (-1 as u32)); - assert_eq!(4294967295, (-1 as u32)); - assert_eq!(0xffffffffffffffff, (-1 as u64)); - assert_eq!(18446744073709551615, (-1 as u64)); + assert_eq!(0xffffffff, (!0 as u32)); + assert_eq!(4294967295, (!0 as u32)); + assert_eq!(0xffffffffffffffff, (!0 as u64)); + assert_eq!(18446744073709551615, (!0 as u64)); assert_eq!((-2147483648i32).wrapping_sub(1), 2147483647); } diff --git a/src/test/run-pass/bitwise.rs b/src/test/run-pass/bitwise.rs index d6117a04e35..a9f19c12b02 100644 --- a/src/test/run-pass/bitwise.rs +++ b/src/test/run-pass/bitwise.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(negate_unsigned)] #[cfg(any(target_arch = "x86", target_arch = "arm"))] fn target() { diff --git a/src/test/run-pass/intrinsics-integer.rs b/src/test/run-pass/intrinsics-integer.rs index a4661410ad6..15dbe796ef5 100644 --- a/src/test/run-pass/intrinsics-integer.rs +++ b/src/test/run-pass/intrinsics-integer.rs @@ -10,6 +10,7 @@ // pretty-expanded FIXME #23616 +#![feature(negate_unsigned)] #![feature(intrinsics)] mod rusti { diff --git a/src/test/run-pass/issue-17074.rs b/src/test/run-pass/issue-17074.rs index 31f6a4209de..08c313ab0a4 100644 --- a/src/test/run-pass/issue-17074.rs +++ b/src/test/run-pass/issue-17074.rs @@ -10,10 +10,10 @@ // pretty-expanded FIXME #23616 -static X2: u64 = -1 as u16 as u64; -static Y2: u64 = -1 as u32 as u64; -const X: u64 = -1 as u16 as u64; -const Y: u64 = -1 as u32 as u64; +static X2: u64 = !0 as u16 as u64; +static Y2: u64 = !0 as u32 as u64; +const X: u64 = !0 as u16 as u64; +const Y: u64 = !0 as u32 as u64; fn main() { assert_eq!(match 1 { From 07ff8ab8855b4d5ce0d547cfe3b1bf03e5f427eb Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Thu, 2 Apr 2015 01:43:54 +0200 Subject: [PATCH 8/9] fixes for fallout in tests/compile-fail --- src/test/compile-fail/const-eval-overflow.rs | 2 ++ src/test/compile-fail/enum-discrim-too-small.rs | 2 ++ src/test/compile-fail/lint-exceeding-bitshifts.rs | 1 + src/test/compile-fail/lint-type-limits.rs | 1 + 4 files changed, 6 insertions(+) diff --git a/src/test/compile-fail/const-eval-overflow.rs b/src/test/compile-fail/const-eval-overflow.rs index f647c43e137..fb8726f900d 100644 --- a/src/test/compile-fail/const-eval-overflow.rs +++ b/src/test/compile-fail/const-eval-overflow.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(negate_unsigned)] + #![allow(unused_imports)] // Note: the relevant lint pass here runs before some of the constant diff --git a/src/test/compile-fail/enum-discrim-too-small.rs b/src/test/compile-fail/enum-discrim-too-small.rs index 1d7794336a0..cdf7d026d5e 100644 --- a/src/test/compile-fail/enum-discrim-too-small.rs +++ b/src/test/compile-fail/enum-discrim-too-small.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(negate_unsigned)] + #[repr(u8)] //~ NOTE discriminant type specified here enum Eu8 { Au8 = 23, diff --git a/src/test/compile-fail/lint-exceeding-bitshifts.rs b/src/test/compile-fail/lint-exceeding-bitshifts.rs index 171dedd5b2e..1894064fd84 100644 --- a/src/test/compile-fail/lint-exceeding-bitshifts.rs +++ b/src/test/compile-fail/lint-exceeding-bitshifts.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(negate_unsigned)] #![deny(exceeding_bitshifts)] #![allow(unused_variables)] #![allow(dead_code)] diff --git a/src/test/compile-fail/lint-type-limits.rs b/src/test/compile-fail/lint-type-limits.rs index f36c726c875..2ccfb5cd520 100644 --- a/src/test/compile-fail/lint-type-limits.rs +++ b/src/test/compile-fail/lint-type-limits.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(negate_unsigned)] #![allow(dead_code)] // compile-flags: -D unused-comparisons From f86318d63c86568b312f39da20bea67e328c1fc5 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 1 Apr 2015 16:34:15 -0700 Subject: [PATCH 9/9] Test fixes and rebase conflicts, round 2 Conflicts: src/libcore/num/mod.rs --- src/libcollectionstest/slice.rs | 4 ++-- src/libcoretest/fmt/num.rs | 16 ++++++++-------- src/liblibc/lib.rs | 2 +- src/librand/distributions/mod.rs | 2 +- src/librustc/middle/const_eval.rs | 2 +- src/libstd/fs.rs | 2 +- src/libstd/old_io/fs.rs | 2 +- src/libsyntax/print/pprust.rs | 2 +- src/test/compile-fail/const-eval-overflow.rs | 1 + .../compile-fail/lint-exceeding-bitshifts.rs | 2 +- src/test/compile-fail/lint-type-limits.rs | 1 + 11 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/libcollectionstest/slice.rs b/src/libcollectionstest/slice.rs index 041d9fba57c..dab5da10db4 100644 --- a/src/libcollectionstest/slice.rs +++ b/src/libcollectionstest/slice.rs @@ -1088,7 +1088,7 @@ fn test_bytes_set_memory() { #[should_panic] fn test_overflow_does_not_cause_segfault() { let mut v = vec![]; - v.reserve_exact(-1); + v.reserve_exact(!0); v.push(1); v.push(2); } @@ -1097,7 +1097,7 @@ fn test_overflow_does_not_cause_segfault() { #[should_panic] fn test_overflow_does_not_cause_segfault_managed() { let mut v = vec![Rc::new(1)]; - v.reserve_exact(-1); + v.reserve_exact(!0); v.push(Rc::new(2)); } diff --git a/src/libcoretest/fmt/num.rs b/src/libcoretest/fmt/num.rs index 7db8db444ff..ba12ff306e9 100644 --- a/src/libcoretest/fmt/num.rs +++ b/src/libcoretest/fmt/num.rs @@ -125,14 +125,14 @@ fn test_format_int_flags() { assert!(format!("{:>8x}", 10) == " a"); assert!(format!("{:#08x}", 10) == "0x00000a"); assert!(format!("{:08}", -10) == "-0000010"); - assert!(format!("{:x}", -1u8) == "ff"); - assert!(format!("{:X}", -1u8) == "FF"); - assert!(format!("{:b}", -1u8) == "11111111"); - assert!(format!("{:o}", -1u8) == "377"); - assert!(format!("{:#x}", -1u8) == "0xff"); - assert!(format!("{:#X}", -1u8) == "0xFF"); - assert!(format!("{:#b}", -1u8) == "0b11111111"); - assert!(format!("{:#o}", -1u8) == "0o377"); + assert!(format!("{:x}", !0u8) == "ff"); + assert!(format!("{:X}", !0u8) == "FF"); + assert!(format!("{:b}", !0u8) == "11111111"); + assert!(format!("{:o}", !0u8) == "377"); + assert!(format!("{:#x}", !0u8) == "0xff"); + assert!(format!("{:#X}", !0u8) == "0xFF"); + assert!(format!("{:#b}", !0u8) == "0b11111111"); + assert!(format!("{:#o}", !0u8) == "0o377"); } #[test] diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index 77e18be298b..bfc657f8784 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -2865,7 +2865,7 @@ pub mod posix88 { pub const MAP_FIXED : c_int = 0x0010; pub const MAP_ANON : c_int = 0x0020; - pub const MAP_FAILED : *mut c_void = -1 as *mut c_void; + pub const MAP_FAILED : *mut c_void = !0 as *mut c_void; pub const MCL_CURRENT : c_int = 0x0001; pub const MCL_FUTURE : c_int = 0x0002; diff --git a/src/librand/distributions/mod.rs b/src/librand/distributions/mod.rs index 62189e721e5..432081063c5 100644 --- a/src/librand/distributions/mod.rs +++ b/src/librand/distributions/mod.rs @@ -361,7 +361,7 @@ fn test_weighted_choice_zero_weight() { } #[test] #[should_panic] fn test_weighted_choice_weight_overflows() { - let x = (-1) as usize / 2; // x + x + 2 is the overflow + let x = (!0) as usize / 2; // x + x + 2 is the overflow WeightedChoice::new(&mut [Weighted { weight: x, item: 0 }, Weighted { weight: 1, item: 1 }, Weighted { weight: x, item: 2 }, diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index fb742b6737f..367bcbbe1d8 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -396,7 +396,7 @@ pub fn const_int_checked_neg<'a>( pub fn const_uint_checked_neg<'a>( a: u64, _e: &'a Expr, _opt_ety: Option) -> EvalResult { // This always succeeds, and by definition, returns `(!a)+1`. - Ok(const_uint(-a)) + Ok(const_uint((!a).wrapping_add(1))) } macro_rules! overflow_checking_body { diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 4f97ae8f69b..eabc51beb12 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -946,7 +946,7 @@ fn file_test_io_smoke_test() { let mut read_stream = check!(File::open(filename)); let mut read_buf = [0; 1028]; let read_str = match check!(read_stream.read(&mut read_buf)) { - -1|0 => panic!("shouldn't happen"), + 0 => panic!("shouldn't happen"), n => str::from_utf8(&read_buf[..n]).unwrap().to_string() }; assert_eq!(read_str, message); diff --git a/src/libstd/old_io/fs.rs b/src/libstd/old_io/fs.rs index bef6ea53e50..509daa46ef3 100644 --- a/src/libstd/old_io/fs.rs +++ b/src/libstd/old_io/fs.rs @@ -970,7 +970,7 @@ fn file_test_io_smoke_test() { let mut read_stream = File::open_mode(filename, Open, Read); let mut read_buf = [0; 1028]; let read_str = match check!(read_stream.read(&mut read_buf)) { - -1|0 => panic!("shouldn't happen"), + 0 => panic!("shouldn't happen"), n => str::from_utf8(&read_buf[..n]).unwrap().to_string() }; assert_eq!(read_str, message); diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index da1b7a7bdde..3a41b74fb79 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -3048,7 +3048,7 @@ fn test_variant_to_string() { #[test] fn test_signed_int_to_string() { let pos_int = ast::LitInt(42, ast::SignedIntLit(ast::TyI32, ast::Plus)); - let neg_int = ast::LitInt((-42) as u64, ast::SignedIntLit(ast::TyI32, ast::Minus)); + let neg_int = ast::LitInt((!42 + 1) as u64, ast::SignedIntLit(ast::TyI32, ast::Minus)); assert_eq!(format!("-{}", lit_to_string(&codemap::dummy_spanned(pos_int))), lit_to_string(&codemap::dummy_spanned(neg_int))); } diff --git a/src/test/compile-fail/const-eval-overflow.rs b/src/test/compile-fail/const-eval-overflow.rs index fb8726f900d..19b5f9b094c 100644 --- a/src/test/compile-fail/const-eval-overflow.rs +++ b/src/test/compile-fail/const-eval-overflow.rs @@ -11,6 +11,7 @@ #![feature(negate_unsigned)] #![allow(unused_imports)] +#![feature(negate_unsigned)] // Note: the relevant lint pass here runs before some of the constant // evaluation below (e.g. that performed by trans and llvm), so if you diff --git a/src/test/compile-fail/lint-exceeding-bitshifts.rs b/src/test/compile-fail/lint-exceeding-bitshifts.rs index 1894064fd84..1f70828e411 100644 --- a/src/test/compile-fail/lint-exceeding-bitshifts.rs +++ b/src/test/compile-fail/lint-exceeding-bitshifts.rs @@ -12,7 +12,7 @@ #![deny(exceeding_bitshifts)] #![allow(unused_variables)] #![allow(dead_code)] -#![feature(core)] +#![feature(core, negate_unsigned)] fn main() { let n = 1u8 << 7; diff --git a/src/test/compile-fail/lint-type-limits.rs b/src/test/compile-fail/lint-type-limits.rs index 2ccfb5cd520..798dc112b0a 100644 --- a/src/test/compile-fail/lint-type-limits.rs +++ b/src/test/compile-fail/lint-type-limits.rs @@ -10,6 +10,7 @@ #![feature(negate_unsigned)] #![allow(dead_code)] +#![feature(negate_unsigned)] // compile-flags: -D unused-comparisons fn main() { }