From d8e309320d55e08f5bbda2f18b20a3a64198061e Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 1 Apr 2015 01:32:41 +0200 Subject: added unary_negate feature gate. --- src/libsyntax/feature_gate.rs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/libsyntax') 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 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[ // #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 @@ impl 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 } -- cgit 1.4.1-3-g733a5 From 98dd376f9c3b2eb4a351d836bcb0be03686dcf97 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 1 Apr 2015 19:53:32 +0200 Subject: 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(-) (limited to 'src/libsyntax') 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 middle::astconv_util::ast_ty_to_prim_ty; 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 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>, 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 @@ impl<'tcx> LocalCrateContext<'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 const CRATE_NODE_ID: NodeId = 0; /// 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 { -- cgit 1.4.1-3-g733a5 From f86318d63c86568b312f39da20bea67e328c1fc5 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 1 Apr 2015 16:34:15 -0700 Subject: 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 + src/test/compile-fail/lint-exceeding-bitshifts.rs | 2 +- src/test/compile-fail/lint-type-limits.rs | 1 + 11 files changed, 19 insertions(+), 17 deletions(-) (limited to 'src/libsyntax') 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 consts { 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 @@ mod tests { } #[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 @@ mod tests { 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 @@ mod 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 @@ mod test { #[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() { } -- cgit 1.4.1-3-g733a5