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

Fix negate_unsigned feature gate check #27026

Merged
merged 3 commits into from
Jul 20, 2015
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: 0 additions & 2 deletions src/libcore/fmt/num.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@

// FIXME: #6220 Implement floating point formatting

#![allow(unsigned_negation)]

use prelude::*;

use fmt;
Expand Down
1 change: 0 additions & 1 deletion src/libcore/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,6 @@ pub trait Neg {
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 {
#[stable(feature = "rust1", since = "1.0.0")]
type Output = $t;
Expand Down
2 changes: 0 additions & 2 deletions src/libcoretest/fmt/num.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
// <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(unsigned_negation)]

use core::fmt::radix;

#[test]
Expand Down
1 change: 0 additions & 1 deletion src/librand/isaac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ impl IsaacRng {

/// Refills the output buffer (`self.rsl`)
#[inline]
#[allow(unsigned_negation)]
fn isaac(&mut self) {
self.c = self.c + w(1);
// abbreviations
Expand Down
42 changes: 32 additions & 10 deletions src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,15 @@ enum TargetLint {

/// Temporary renaming, used for easing migration pain; see #16545
Renamed(String, LintId),

/// Lint with this name existed previously, but has been removed/deprecated.
/// The string argument is the reason for removal.
Removed(String),
}

enum FindLintError {
NotFound,
Removed
}

impl LintStore {
Expand Down Expand Up @@ -166,30 +175,42 @@ impl LintStore {
self.by_name.insert(old_name.to_string(), Renamed(new_name.to_string(), target));
}

pub fn register_removed(&mut self, name: &str, reason: &str) {
self.by_name.insert(name.into(), Removed(reason.into()));
}

#[allow(unused_variables)]
fn find_lint(&self, lint_name: &str, sess: &Session, span: Option<Span>)
-> Option<LintId>
-> Result<LintId, FindLintError>
{
match self.by_name.get(lint_name) {
Some(&Id(lint_id)) => Some(lint_id),
Some(&Id(lint_id)) => Ok(lint_id),
Some(&Renamed(ref new_name, lint_id)) => {
let warning = format!("lint {} has been renamed to {}",
lint_name, new_name);
match span {
Some(span) => sess.span_warn(span, &warning[..]),
None => sess.warn(&warning[..]),
};
Some(lint_id)
}
None => None
Ok(lint_id)
},
Some(&Removed(ref reason)) => {
let warning = format!("lint {} has been removed: {}", lint_name, reason);
match span {
Some(span) => sess.span_warn(span, &warning[..]),
None => sess.warn(&warning[..])
}
Err(FindLintError::Removed)
},
None => Err(FindLintError::NotFound)
}
}

pub fn process_command_line(&mut self, sess: &Session) {
for &(ref lint_name, level) in &sess.opts.lint_opts {
match self.find_lint(&lint_name[..], sess, None) {
Some(lint_id) => self.set_level(lint_id, (level, CommandLine)),
None => {
Ok(lint_id) => self.set_level(lint_id, (level, CommandLine)),
Err(_) => {
match self.lint_groups.iter().map(|(&x, pair)| (x, pair.0.clone()))
.collect::<FnvHashMap<&'static str,
Vec<LintId>>>()
Expand Down Expand Up @@ -398,8 +419,8 @@ impl<'a, 'tcx> Context<'a, 'tcx> {
}
Ok((lint_name, level, span)) => {
match self.lints.find_lint(&lint_name, &self.tcx.sess, Some(span)) {
Some(lint_id) => vec![(lint_id, level, span)],
None => {
Ok(lint_id) => vec![(lint_id, level, span)],
Err(FindLintError::NotFound) => {
match self.lints.lint_groups.get(&lint_name[..]) {
Some(&(ref v, _)) => v.iter()
.map(|lint_id: &LintId|
Expand All @@ -412,7 +433,8 @@ impl<'a, 'tcx> Context<'a, 'tcx> {
continue;
}
}
}
},
Err(FindLintError::Removed) => { continue; }
}
}
};
Expand Down
9 changes: 0 additions & 9 deletions src/librustc/middle/const_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
// except according to those terms.

#![allow(non_camel_case_types)]
#![allow(unsigned_negation)]

use self::ConstVal::*;

Expand All @@ -27,7 +26,6 @@ use util::num::ToPrimitive;
use syntax::ast::{self, Expr};
use syntax::ast_util;
use syntax::codemap::Span;
use syntax::feature_gate;
use syntax::parse::token::InternedString;
use syntax::ptr::P;
use syntax::{codemap, visit};
Expand Down Expand Up @@ -745,13 +743,6 @@ pub fn eval_const_expr_with_substs<'tcx, S>(tcx: &ty::ctxt<'tcx>,
Float(f) => Float(-f),
Int(n) => try!(const_int_checked_neg(n, e, expr_int_type)),
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");
}
try!(const_uint_checked_neg(i, e, expr_uint_type))
}
Str(_) => signal!(e, NegateOnString),
Expand Down
34 changes: 20 additions & 14 deletions src/librustc_lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,6 @@ impl LintPass for WhileTrue {
}
}

declare_lint! {
UNSIGNED_NEGATION,
Warn,
"using an unary minus operator on unsigned type"
}

declare_lint! {
UNUSED_COMPARISONS,
Warn,
Expand Down Expand Up @@ -128,8 +122,7 @@ impl TypeLimits {

impl LintPass for TypeLimits {
fn get_lints(&self) -> LintArray {
lint_array!(UNSIGNED_NEGATION, UNUSED_COMPARISONS, OVERFLOWING_LITERALS,
EXCEEDING_BITSHIFTS)
lint_array!(UNUSED_COMPARISONS, OVERFLOWING_LITERALS, EXCEEDING_BITSHIFTS)
}

fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
Expand All @@ -139,9 +132,12 @@ impl LintPass for TypeLimits {
ast::ExprLit(ref lit) => {
match lit.node {
ast::LitInt(_, ast::UnsignedIntLit(_)) => {
cx.span_lint(UNSIGNED_NEGATION, e.span,
"negation of unsigned int literal may \
be unintentional");
check_unsigned_negation_feature(cx, e.span);
},
ast::LitInt(_, ast::UnsuffixedIntLit(_)) => {
if let ty::TyUint(_) = cx.tcx.expr_ty(e).sty {
check_unsigned_negation_feature(cx, e.span);
}
},
_ => ()
}
Expand All @@ -150,9 +146,7 @@ impl LintPass for TypeLimits {
let t = cx.tcx.expr_ty(&**expr);
match t.sty {
ty::TyUint(_) => {
cx.span_lint(UNSIGNED_NEGATION, e.span,
"negation of unsigned int variable may \
be unintentional");
check_unsigned_negation_feature(cx, e.span);
},
_ => ()
}
Expand Down Expand Up @@ -385,6 +379,18 @@ impl LintPass for TypeLimits {
_ => false
}
}

fn check_unsigned_negation_feature(cx: &Context, span: Span) {
if !cx.sess().features.borrow().negate_unsigned {
// FIXME(#27141): change this to syntax::feature_gate::emit_feature_err…
cx.sess().span_warn(span,
"unary negation of unsigned integers will be feature gated in the future");
// …and remove following two expressions.
if option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some() { return; }
cx.sess().fileline_help(span, "add #![feature(negate_unsigned)] to the \
crate attributes to enable the gate in advance");
}
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/librustc_lint/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
store.register_renamed("raw_pointer_deriving", "raw_pointer_derive");

store.register_renamed("unknown_features", "unused_features");

store.register_removed("unsigned_negation", "replaced by negate_unsigned feature gate");
}
2 changes: 0 additions & 2 deletions src/librustc_trans/trans/adt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@
//! used unboxed and any field can have pointers (including mutable)
//! taken to it, implementing them for Rust seems difficult.

#![allow(unsigned_negation)]

pub use self::Repr::*;

use std::rc::Rc;
Expand Down
10 changes: 0 additions & 10 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ use syntax::attr::AttrMetaMethods;
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;
Expand Down Expand Up @@ -3074,15 +3073,6 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
tcx.lang_items.neg_trait(),
expr, &**oprnd, oprnd_t, unop);
}
if let ty::TyUint(_) = 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");
}
}
}
}
}
Expand Down
1 change: 0 additions & 1 deletion src/libstd/num/f32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

#![stable(feature = "rust1", since = "1.0.0")]
#![allow(missing_docs)]
#![allow(unsigned_negation)]
#![doc(primitive = "f32")]

use prelude::v1::*;
Expand Down
1 change: 0 additions & 1 deletion src/libstd/num/uint_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
// except according to those terms.

#![doc(hidden)]
#![allow(unsigned_negation)]

macro_rules! uint_module { ($T:ident) => (

Expand Down
9 changes: 0 additions & 9 deletions src/test/compile-fail/const-eval-overflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
// 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.
#![warn(unsigned_negation)]

use std::fmt;
use std::{i8, i16, i32, i64, isize};
Expand Down Expand Up @@ -69,8 +68,6 @@ const VALS_I64: (i64, i64, i64, i64) =

const VALS_U8: (u8, u8, u8, u8) =
(-u8::MIN,
//~^ WARNING negation of unsigned int variable may be unintentional
// (The above is separately linted; unsigned negation is defined to be !x+1.)
u8::MIN - 1,
//~^ ERROR attempted to sub with overflow
u8::MAX + 1,
Expand All @@ -81,8 +78,6 @@ const VALS_U8: (u8, u8, u8, u8) =

const VALS_U16: (u16, u16, u16, u16) =
(-u16::MIN,
//~^ WARNING negation of unsigned int variable may be unintentional
// (The above is separately linted; unsigned negation is defined to be !x+1.)
u16::MIN - 1,
//~^ ERROR attempted to sub with overflow
u16::MAX + 1,
Expand All @@ -93,8 +88,6 @@ const VALS_U16: (u16, u16, u16, u16) =

const VALS_U32: (u32, u32, u32, u32) =
(-u32::MIN,
//~^ WARNING negation of unsigned int variable may be unintentional
// (The above is separately linted; unsigned negation is defined to be !x+1.)
u32::MIN - 1,
//~^ ERROR attempted to sub with overflow
u32::MAX + 1,
Expand All @@ -105,8 +98,6 @@ const VALS_U32: (u32, u32, u32, u32) =

const VALS_U64: (u64, u64, u64, u64) =
(-u64::MIN,
//~^ WARNING negation of unsigned int variable may be unintentional
// (The above is separately linted; unsigned negation is defined to be !x+1.)
u64::MIN - 1,
//~^ ERROR attempted to sub with overflow
u64::MAX + 1,
Expand Down
17 changes: 0 additions & 17 deletions src/test/compile-fail/feature-gate-negate-unsigned.rs

This file was deleted.

11 changes: 0 additions & 11 deletions src/test/compile-fail/lint-type-limits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,3 @@ fn qux() {
i += 1;
}
}

fn quy() {
let i = -23_usize; //~ WARNING negation of unsigned int literal may be unintentional
//~^ WARNING unused variable
}

fn quz() {
let i = 23_usize;
let j = -i; //~ WARNING negation of unsigned int variable may be unintentional
//~^ WARNING unused variable
}
38 changes: 38 additions & 0 deletions src/test/run-pass/feature-gate-negate-unsigned.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// 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.

// Test that negating unsigned integers is gated by `negate_unsigned` feature
// gate

struct S;
impl std::ops::Neg for S {
type Output = u32;
fn neg(self) -> u32 { 0 }
}

const _MAX: usize = -1;
//~^ WARN unary negation of unsigned integers will be feature gated in the future

fn main() {
let a = -1;
//~^ WARN unary negation of unsigned integers will be feature gated in the future
let _b : u8 = a; // for infering variable a to u8.

-a;
//~^ WARN unary negation of unsigned integers will be feature gated in the future

let _d = -1u8;
//~^ WARN unary negation of unsigned integers will be feature gated in the future

for _ in -10..10u8 {}
//~^ WARN unary negation of unsigned integers will be feature gated in the future

-S; // should not trigger the gate; issue 26840
}