Skip to content

Commit

Permalink
Auto merge of #27026 - nagisa:overflowing-unsigned, r=pnkfelix
Browse files Browse the repository at this point in the history
This commit fixes the negate_unsigned feature gate to appropriately
account for inferred variables.

This is technically a [breaking-change], but I’d consider it a bug fix.

cc @brson for your relnotes.

Fixes #24676
Fixes #26840 
Fixes #25206
  • Loading branch information
bors committed Jul 20, 2015
2 parents 39d4faf + 0ca8e49 commit 1855750
Show file tree
Hide file tree
Showing 16 changed files with 92 additions and 90 deletions.
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
}

0 comments on commit 1855750

Please sign in to comment.