Skip to content

Commit 1855750

Browse files
committed
Auto merge of #27026 - nagisa:overflowing-unsigned, r=pnkfelix
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
2 parents 39d4faf + 0ca8e49 commit 1855750

File tree

16 files changed

+92
-90
lines changed

16 files changed

+92
-90
lines changed

src/libcore/fmt/num.rs

-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
1313
// FIXME: #6220 Implement floating point formatting
1414

15-
#![allow(unsigned_negation)]
16-
1715
use prelude::*;
1816

1917
use fmt;

src/libcore/ops.rs

-1
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,6 @@ pub trait Neg {
517517
macro_rules! neg_impl_core {
518518
($id:ident => $body:expr, $($t:ty)*) => ($(
519519
#[stable(feature = "rust1", since = "1.0.0")]
520-
#[allow(unsigned_negation)]
521520
impl Neg for $t {
522521
#[stable(feature = "rust1", since = "1.0.0")]
523522
type Output = $t;

src/libcoretest/fmt/num.rs

-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
10-
#![allow(unsigned_negation)]
11-
1210
use core::fmt::radix;
1311

1412
#[test]

src/librand/isaac.rs

-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ impl IsaacRng {
126126

127127
/// Refills the output buffer (`self.rsl`)
128128
#[inline]
129-
#[allow(unsigned_negation)]
130129
fn isaac(&mut self) {
131130
self.c = self.c + w(1);
132131
// abbreviations

src/librustc/lint/context.rs

+32-10
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,15 @@ enum TargetLint {
7575

7676
/// Temporary renaming, used for easing migration pain; see #16545
7777
Renamed(String, LintId),
78+
79+
/// Lint with this name existed previously, but has been removed/deprecated.
80+
/// The string argument is the reason for removal.
81+
Removed(String),
82+
}
83+
84+
enum FindLintError {
85+
NotFound,
86+
Removed
7887
}
7988

8089
impl LintStore {
@@ -166,30 +175,42 @@ impl LintStore {
166175
self.by_name.insert(old_name.to_string(), Renamed(new_name.to_string(), target));
167176
}
168177

178+
pub fn register_removed(&mut self, name: &str, reason: &str) {
179+
self.by_name.insert(name.into(), Removed(reason.into()));
180+
}
181+
169182
#[allow(unused_variables)]
170183
fn find_lint(&self, lint_name: &str, sess: &Session, span: Option<Span>)
171-
-> Option<LintId>
184+
-> Result<LintId, FindLintError>
172185
{
173186
match self.by_name.get(lint_name) {
174-
Some(&Id(lint_id)) => Some(lint_id),
187+
Some(&Id(lint_id)) => Ok(lint_id),
175188
Some(&Renamed(ref new_name, lint_id)) => {
176189
let warning = format!("lint {} has been renamed to {}",
177190
lint_name, new_name);
178191
match span {
179192
Some(span) => sess.span_warn(span, &warning[..]),
180193
None => sess.warn(&warning[..]),
181194
};
182-
Some(lint_id)
183-
}
184-
None => None
195+
Ok(lint_id)
196+
},
197+
Some(&Removed(ref reason)) => {
198+
let warning = format!("lint {} has been removed: {}", lint_name, reason);
199+
match span {
200+
Some(span) => sess.span_warn(span, &warning[..]),
201+
None => sess.warn(&warning[..])
202+
}
203+
Err(FindLintError::Removed)
204+
},
205+
None => Err(FindLintError::NotFound)
185206
}
186207
}
187208

188209
pub fn process_command_line(&mut self, sess: &Session) {
189210
for &(ref lint_name, level) in &sess.opts.lint_opts {
190211
match self.find_lint(&lint_name[..], sess, None) {
191-
Some(lint_id) => self.set_level(lint_id, (level, CommandLine)),
192-
None => {
212+
Ok(lint_id) => self.set_level(lint_id, (level, CommandLine)),
213+
Err(_) => {
193214
match self.lint_groups.iter().map(|(&x, pair)| (x, pair.0.clone()))
194215
.collect::<FnvHashMap<&'static str,
195216
Vec<LintId>>>()
@@ -398,8 +419,8 @@ impl<'a, 'tcx> Context<'a, 'tcx> {
398419
}
399420
Ok((lint_name, level, span)) => {
400421
match self.lints.find_lint(&lint_name, &self.tcx.sess, Some(span)) {
401-
Some(lint_id) => vec![(lint_id, level, span)],
402-
None => {
422+
Ok(lint_id) => vec![(lint_id, level, span)],
423+
Err(FindLintError::NotFound) => {
403424
match self.lints.lint_groups.get(&lint_name[..]) {
404425
Some(&(ref v, _)) => v.iter()
405426
.map(|lint_id: &LintId|
@@ -412,7 +433,8 @@ impl<'a, 'tcx> Context<'a, 'tcx> {
412433
continue;
413434
}
414435
}
415-
}
436+
},
437+
Err(FindLintError::Removed) => { continue; }
416438
}
417439
}
418440
};

src/librustc/middle/const_eval.rs

-9
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
// except according to those terms.
1010

1111
#![allow(non_camel_case_types)]
12-
#![allow(unsigned_negation)]
1312

1413
use self::ConstVal::*;
1514

@@ -27,7 +26,6 @@ use util::num::ToPrimitive;
2726
use syntax::ast::{self, Expr};
2827
use syntax::ast_util;
2928
use syntax::codemap::Span;
30-
use syntax::feature_gate;
3129
use syntax::parse::token::InternedString;
3230
use syntax::ptr::P;
3331
use syntax::{codemap, visit};
@@ -745,13 +743,6 @@ pub fn eval_const_expr_with_substs<'tcx, S>(tcx: &ty::ctxt<'tcx>,
745743
Float(f) => Float(-f),
746744
Int(n) => try!(const_int_checked_neg(n, e, expr_int_type)),
747745
Uint(i) => {
748-
if !tcx.sess.features.borrow().negate_unsigned {
749-
feature_gate::emit_feature_err(
750-
&tcx.sess.parse_sess.span_diagnostic,
751-
"negate_unsigned",
752-
e.span,
753-
"unary negation of unsigned integers may be removed in the future");
754-
}
755746
try!(const_uint_checked_neg(i, e, expr_uint_type))
756747
}
757748
Str(_) => signal!(e, NegateOnString),

src/librustc_lint/builtin.rs

+20-14
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,6 @@ impl LintPass for WhileTrue {
8888
}
8989
}
9090

91-
declare_lint! {
92-
UNSIGNED_NEGATION,
93-
Warn,
94-
"using an unary minus operator on unsigned type"
95-
}
96-
9791
declare_lint! {
9892
UNUSED_COMPARISONS,
9993
Warn,
@@ -128,8 +122,7 @@ impl TypeLimits {
128122

129123
impl LintPass for TypeLimits {
130124
fn get_lints(&self) -> LintArray {
131-
lint_array!(UNSIGNED_NEGATION, UNUSED_COMPARISONS, OVERFLOWING_LITERALS,
132-
EXCEEDING_BITSHIFTS)
125+
lint_array!(UNUSED_COMPARISONS, OVERFLOWING_LITERALS, EXCEEDING_BITSHIFTS)
133126
}
134127

135128
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
@@ -139,9 +132,12 @@ impl LintPass for TypeLimits {
139132
ast::ExprLit(ref lit) => {
140133
match lit.node {
141134
ast::LitInt(_, ast::UnsignedIntLit(_)) => {
142-
cx.span_lint(UNSIGNED_NEGATION, e.span,
143-
"negation of unsigned int literal may \
144-
be unintentional");
135+
check_unsigned_negation_feature(cx, e.span);
136+
},
137+
ast::LitInt(_, ast::UnsuffixedIntLit(_)) => {
138+
if let ty::TyUint(_) = cx.tcx.expr_ty(e).sty {
139+
check_unsigned_negation_feature(cx, e.span);
140+
}
145141
},
146142
_ => ()
147143
}
@@ -150,9 +146,7 @@ impl LintPass for TypeLimits {
150146
let t = cx.tcx.expr_ty(&**expr);
151147
match t.sty {
152148
ty::TyUint(_) => {
153-
cx.span_lint(UNSIGNED_NEGATION, e.span,
154-
"negation of unsigned int variable may \
155-
be unintentional");
149+
check_unsigned_negation_feature(cx, e.span);
156150
},
157151
_ => ()
158152
}
@@ -385,6 +379,18 @@ impl LintPass for TypeLimits {
385379
_ => false
386380
}
387381
}
382+
383+
fn check_unsigned_negation_feature(cx: &Context, span: Span) {
384+
if !cx.sess().features.borrow().negate_unsigned {
385+
// FIXME(#27141): change this to syntax::feature_gate::emit_feature_err…
386+
cx.sess().span_warn(span,
387+
"unary negation of unsigned integers will be feature gated in the future");
388+
// …and remove following two expressions.
389+
if option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some() { return; }
390+
cx.sess().fileline_help(span, "add #![feature(negate_unsigned)] to the \
391+
crate attributes to enable the gate in advance");
392+
}
393+
}
388394
}
389395
}
390396

src/librustc_lint/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -134,4 +134,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
134134
store.register_renamed("raw_pointer_deriving", "raw_pointer_derive");
135135

136136
store.register_renamed("unknown_features", "unused_features");
137+
138+
store.register_removed("unsigned_negation", "replaced by negate_unsigned feature gate");
137139
}

src/librustc_trans/trans/adt.rs

-2
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@
4141
//! used unboxed and any field can have pointers (including mutable)
4242
//! taken to it, implementing them for Rust seems difficult.
4343
44-
#![allow(unsigned_negation)]
45-
4644
pub use self::Repr::*;
4745

4846
use std::rc::Rc;

src/librustc_typeck/check/mod.rs

-10
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ use syntax::attr::AttrMetaMethods;
114114
use syntax::ast::{self, DefId, Visibility};
115115
use syntax::ast_util::{self, local_def};
116116
use syntax::codemap::{self, Span};
117-
use syntax::feature_gate;
118117
use syntax::owned_slice::OwnedSlice;
119118
use syntax::parse::token;
120119
use syntax::print::pprust;
@@ -3074,15 +3073,6 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
30743073
tcx.lang_items.neg_trait(),
30753074
expr, &**oprnd, oprnd_t, unop);
30763075
}
3077-
if let ty::TyUint(_) = oprnd_t.sty {
3078-
if !tcx.sess.features.borrow().negate_unsigned {
3079-
feature_gate::emit_feature_err(
3080-
&tcx.sess.parse_sess.span_diagnostic,
3081-
"negate_unsigned",
3082-
expr.span,
3083-
"unary negation of unsigned integers may be removed in the future");
3084-
}
3085-
}
30863076
}
30873077
}
30883078
}

src/libstd/num/f32.rs

-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
1313
#![stable(feature = "rust1", since = "1.0.0")]
1414
#![allow(missing_docs)]
15-
#![allow(unsigned_negation)]
1615
#![doc(primitive = "f32")]
1716

1817
use prelude::v1::*;

src/libstd/num/uint_macros.rs

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
// except according to those terms.
1010

1111
#![doc(hidden)]
12-
#![allow(unsigned_negation)]
1312

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

src/test/compile-fail/const-eval-overflow.rs

-9
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
// evaluation below (e.g. that performed by trans and llvm), so if you
1818
// change this warn to a deny, then the compiler will exit before
1919
// those errors are detected.
20-
#![warn(unsigned_negation)]
2120

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

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

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

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

10699
const VALS_U64: (u64, u64, u64, u64) =
107100
(-u64::MIN,
108-
//~^ WARNING negation of unsigned int variable may be unintentional
109-
// (The above is separately linted; unsigned negation is defined to be !x+1.)
110101
u64::MIN - 1,
111102
//~^ ERROR attempted to sub with overflow
112103
u64::MAX + 1,

src/test/compile-fail/feature-gate-negate-unsigned.rs

-17
This file was deleted.

src/test/compile-fail/lint-type-limits.rs

-11
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,3 @@ fn qux() {
5050
i += 1;
5151
}
5252
}
53-
54-
fn quy() {
55-
let i = -23_usize; //~ WARNING negation of unsigned int literal may be unintentional
56-
//~^ WARNING unused variable
57-
}
58-
59-
fn quz() {
60-
let i = 23_usize;
61-
let j = -i; //~ WARNING negation of unsigned int variable may be unintentional
62-
//~^ WARNING unused variable
63-
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test that negating unsigned integers is gated by `negate_unsigned` feature
12+
// gate
13+
14+
struct S;
15+
impl std::ops::Neg for S {
16+
type Output = u32;
17+
fn neg(self) -> u32 { 0 }
18+
}
19+
20+
const _MAX: usize = -1;
21+
//~^ WARN unary negation of unsigned integers will be feature gated in the future
22+
23+
fn main() {
24+
let a = -1;
25+
//~^ WARN unary negation of unsigned integers will be feature gated in the future
26+
let _b : u8 = a; // for infering variable a to u8.
27+
28+
-a;
29+
//~^ WARN unary negation of unsigned integers will be feature gated in the future
30+
31+
let _d = -1u8;
32+
//~^ WARN unary negation of unsigned integers will be feature gated in the future
33+
34+
for _ in -10..10u8 {}
35+
//~^ WARN unary negation of unsigned integers will be feature gated in the future
36+
37+
-S; // should not trigger the gate; issue 26840
38+
}

0 commit comments

Comments
 (0)