Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove negate_unsigned feature gate #30538

Merged
merged 1 commit into from
Jan 12, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/librustc_lint/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#![feature(staged_api)]
#![feature(str_char)]

#[macro_use]
extern crate syntax;
#[macro_use]
extern crate rustc;
Expand Down Expand Up @@ -153,4 +154,5 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
store.register_renamed("unknown_features", "unused_features");

store.register_removed("unsigned_negation", "replaced by negate_unsigned feature gate");
store.register_removed("negate_unsigned", "cast a signed value instead");
}
84 changes: 51 additions & 33 deletions src/librustc_lint/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(non_snake_case)]

use middle::{infer};
use middle::def_id::DefId;
use middle::subst::Substs;
Expand All @@ -24,13 +26,39 @@ use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
use syntax::{abi, ast};
use syntax::attr::{self, AttrMetaMethods};
use syntax::codemap::{self, Span};
use syntax::feature_gate::{emit_feature_err, GateIssue};
use syntax::ast::{TyIs, TyUs, TyI8, TyU8, TyI16, TyU16, TyI32, TyU32, TyI64, TyU64};

use rustc_front::hir;
use rustc_front::intravisit::{self, Visitor};
use rustc_front::util::is_shift_binop;

register_long_diagnostics! {
E0519: r##"
It is not allowed to negate an unsigned integer.
You can negate a signed integer and cast it to an
unsigned integer or use the `!` operator.

```
let x: usize = -1isize as usize;
let y: usize = !0;
assert_eq!(x, y);
```

Alternatively you can use the `Wrapping` newtype
or the `wrapping_neg` operation that all
integral types support:

```
use std::num::Wrapping;
let x: Wrapping<usize> = -Wrapping(1);
let Wrapping(x) = x;
let y: usize = 1.wrapping_neg();
assert_eq!(x, y);
```

"##
}

declare_lint! {
UNUSED_COMPARISONS,
Warn,
Expand Down Expand Up @@ -73,30 +101,24 @@ impl LateLintPass for TypeLimits {
fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) {
match e.node {
hir::ExprUnary(hir::UnNeg, ref expr) => {
match expr.node {
hir::ExprLit(ref lit) => {
match lit.node {
ast::LitInt(_, ast::UnsignedIntLit(_)) => {
check_unsigned_negation_feature(cx, e.span);
},
ast::LitInt(_, ast::UnsuffixedIntLit(_)) => {
if let ty::TyUint(_) = cx.tcx.node_id_to_type(e.id).sty {
check_unsigned_negation_feature(cx, e.span);
}
},
_ => ()
}
},
_ => {
let t = cx.tcx.node_id_to_type(expr.id);
match t.sty {
ty::TyUint(_) => {
check_unsigned_negation_feature(cx, e.span);
},
_ => ()
}
if let hir::ExprLit(ref lit) = expr.node {
match lit.node {
ast::LitInt(_, ast::UnsignedIntLit(_)) => {
forbid_unsigned_negation(cx, e.span);
},
ast::LitInt(_, ast::UnsuffixedIntLit(_)) => {
if let ty::TyUint(_) = cx.tcx.node_id_to_type(e.id).sty {
forbid_unsigned_negation(cx, e.span);
}
},
_ => ()
}
};
} else {
let t = cx.tcx.node_id_to_type(expr.id);
if let ty::TyUint(_) = t.sty {
forbid_unsigned_negation(cx, e.span);
}
}
// propagate negation, if the negation itself isn't negated
if self.negated_expr_id != e.id {
self.negated_expr_id = expr.id;
Expand Down Expand Up @@ -322,15 +344,11 @@ impl LateLintPass for TypeLimits {
}
}

fn check_unsigned_negation_feature(cx: &LateContext, span: Span) {
if !cx.sess().features.borrow().negate_unsigned {
emit_feature_err(
&cx.sess().parse_sess.span_diagnostic,
"negate_unsigned",
span,
GateIssue::Language,
"unary negation of unsigned integers may be removed in the future");
}
fn forbid_unsigned_negation(cx: &LateContext, span: Span) {
cx.sess()
.struct_span_err_with_code(span, "unary negation of unsigned integer", "E0519")
.span_help(span, "use a cast or the `!` operator")
.emit();
}
}
}
Expand Down
5 changes: 1 addition & 4 deletions src/libsyntax/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Option<u32>, Status
("slice_patterns", "1.0.0", Some(23121), Active),

// Allows use of unary negate on unsigned integers, e.g. -e for e: u8
("negate_unsigned", "1.0.0", Some(29645), Active),
("negate_unsigned", "1.0.0", Some(29645), Removed),

// Allows the definition of associated constants in `trait` or `impl`
// blocks.
Expand Down Expand Up @@ -548,7 +548,6 @@ pub struct Features {
pub allow_pushpop_unsafe: 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<Span>,
/// #![feature] attrs for non-language (library) features
Expand Down Expand Up @@ -585,7 +584,6 @@ impl Features {
allow_pushpop_unsafe: false,
simd_ffi: false,
unmarked_api: false,
negate_unsigned: false,
declared_stable_lang_features: Vec::new(),
declared_lib_features: Vec::new(),
const_fn: false,
Expand Down Expand Up @@ -1174,7 +1172,6 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &Handler,
allow_pushpop_unsafe: cx.has_feature("pushpop_unsafe"),
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,
const_fn: cx.has_feature("const_fn"),
Expand Down
9 changes: 4 additions & 5 deletions src/test/compile-fail/const-eval-overflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
// except according to those terms.

#![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
Expand Down Expand Up @@ -65,7 +64,7 @@ const VALS_I64: (i64, i64, i64, i64) =
);

const VALS_U8: (u8, u8, u8, u8) =
(-u8::MIN,
(-(u8::MIN as i8) as u8,
u8::MIN - 1,
//~^ ERROR attempted to sub with overflow
u8::MAX + 1,
Expand All @@ -75,7 +74,7 @@ const VALS_U8: (u8, u8, u8, u8) =
);

const VALS_U16: (u16, u16, u16, u16) =
(-u16::MIN,
(-(u16::MIN as i16) as u16,
u16::MIN - 1,
//~^ ERROR attempted to sub with overflow
u16::MAX + 1,
Expand All @@ -85,7 +84,7 @@ const VALS_U16: (u16, u16, u16, u16) =
);

const VALS_U32: (u32, u32, u32, u32) =
(-u32::MIN,
(-(u32::MIN as i32) as u32,
u32::MIN - 1,
//~^ ERROR attempted to sub with overflow
u32::MAX + 1,
Expand All @@ -95,7 +94,7 @@ const VALS_U32: (u32, u32, u32, u32) =
);

const VALS_U64: (u64, u64, u64, u64) =
(-u64::MIN,
(-(u64::MIN as i64) as u64,
u64::MIN - 1,
//~^ ERROR attempted to sub with overflow
u64::MAX + 1,
Expand Down
100 changes: 100 additions & 0 deletions src/test/compile-fail/const-eval-overflow0.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Copyright 2015 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.

#![allow(unused_imports)]

// 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
// change this warn to a deny, then the compiler will exit before
// those errors are detected.

use std::fmt;
use std::{i8, i16, i32, i64, isize};
use std::{u8, u16, u32, u64, usize};

const VALS_I8: (i8, i8, i8, i8) =
(-i8::MIN,
i8::MIN - 1,
i8::MAX + 1,
i8::MIN * 2,
);

const VALS_I16: (i16, i16, i16, i16) =
(-i16::MIN,
i16::MIN - 1,
i16::MAX + 1,
i16::MIN * 2,
);

const VALS_I32: (i32, i32, i32, i32) =
(-i32::MIN,
i32::MIN - 1,
i32::MAX + 1,
i32::MIN * 2,
);

const VALS_I64: (i64, i64, i64, i64) =
(-i64::MIN,
i64::MIN - 1,
i64::MAX + 1,
i64::MAX * 2,
);

const VALS_U8: (u8, u8, u8, u8) =
(-u8::MIN,
//~^ ERROR unary negation of unsigned integer
//~| HELP use a cast or the `!` operator
u8::MIN - 1,
u8::MAX + 1,
u8::MAX * 2,
);

const VALS_U16: (u16, u16, u16, u16) =
(-u16::MIN,
//~^ ERROR unary negation of unsigned integer
//~| HELP use a cast or the `!` operator
u16::MIN - 1,
u16::MAX + 1,
u16::MAX * 2,
);

const VALS_U32: (u32, u32, u32, u32) =
(-u32::MIN,
//~^ ERROR unary negation of unsigned integer
//~| HELP use a cast or the `!` operator
u32::MIN - 1,
u32::MAX + 1,
u32::MAX * 2,
);

const VALS_U64: (u64, u64, u64, u64) =
(-u64::MIN,
//~^ ERROR unary negation of unsigned integer
//~| HELP use a cast or the `!` operator
u64::MIN - 1,
u64::MAX + 1,
u64::MAX * 2,
);

fn main() {
foo(VALS_I8);
foo(VALS_I16);
foo(VALS_I32);
foo(VALS_I64);

foo(VALS_U8);
foo(VALS_U16);
foo(VALS_U32);
foo(VALS_U64);
}

fn foo<T:fmt::Debug>(x: T) {
println!("{:?}", x);
}
1 change: 0 additions & 1 deletion src/test/compile-fail/enum-discrim-too-small.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
// 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 {
Expand Down
18 changes: 11 additions & 7 deletions src/test/compile-fail/feature-gate-negate-unsigned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Test that negating unsigned integers is gated by `negate_unsigned` feature
// gate
// Test that negating unsigned integers doesn't compile

struct S;
impl std::ops::Neg for S {
Expand All @@ -18,21 +17,26 @@ impl std::ops::Neg for S {
}

const _MAX: usize = -1;
//~^ ERROR unary negation of unsigned integers may be removed in the future
//~^ ERROR unary negation of unsigned integer
//~| HELP use a cast or the `!` operator

fn main() {
let a = -1;
//~^ ERROR unary negation of unsigned integers may be removed in the future
//~^ ERROR unary negation of unsigned integer
//~| HELP use a cast or the `!` operator
let _b : u8 = a; // for infering variable a to u8.

-a;
//~^ ERROR unary negation of unsigned integers may be removed in the future
//~^ ERROR unary negation of unsigned integer
//~| HELP use a cast or the `!` operator

let _d = -1u8;
//~^ ERROR unary negation of unsigned integers may be removed in the future
//~^ ERROR unary negation of unsigned integer
//~| HELP use a cast or the `!` operator

for _ in -10..10u8 {}
//~^ ERROR unary negation of unsigned integers may be removed in the future
//~^ ERROR unary negation of unsigned integer
//~| HELP use a cast or the `!` operator

-S; // should not trigger the gate; issue 26840
}
2 changes: 0 additions & 2 deletions src/test/compile-fail/lint-type-limits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(negate_unsigned)]
#![allow(dead_code)]
#![feature(negate_unsigned)]

// compile-flags: -D unused-comparisons
fn main() { }
Expand Down
6 changes: 2 additions & 4 deletions src/test/run-pass/bitwise.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,14 @@
// 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() {
assert_eq!(-1000 as usize >> 3_usize, 536870787_usize);
assert_eq!(-1000isize as usize >> 3_usize, 536870787_usize);
}

#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
fn target() {
assert_eq!(-1000 as usize >> 3_usize, 2305843009213693827_usize);
assert_eq!(-1000isize as usize >> 3_usize, 2305843009213693827_usize);
}

fn general() {
Expand Down
Loading