Skip to content

Commit 95602a7

Browse files
committed
Add trivial cast lints.
This permits all coercions to be performed in casts, but adds lints to warn in those cases. Part of this patch moves cast checking to a later stage of type checking. We acquire obligations to check casts as part of type checking where we previously checked them. Once we have type checked a function or module, then we check any cast obligations which have been acquired. That means we have more type information available to check casts (this was crucial to making coercions work properly in place of some casts), but it means that casts cannot feed input into type inference. [breaking change] * Adds two new lints for trivial casts and trivial numeric casts, these are warn by default, but can cause errors if you build with warnings as errors. Previously, trivial numeric casts and casts to trait objects were allowed. * The unused casts lint has gone. * Interactions between casting and type inference have changed in subtle ways. Two ways this might manifest are: - You may need to 'direct' casts more with extra type information, for example, in some cases where `foo as _ as T` succeeded, you may now need to specify the type for `_` - Casts do not influence inference of integer types. E.g., the following used to type check: ``` let x = 42; let y = &x as *const u32; ``` Because the cast would inform inference that `x` must have type `u32`. This no longer applies and the compiler will fallback to `i32` for `x` and thus there will be a type error in the cast. The solution is to add more type information: ``` let x: u32 = 42; let y = &x as *const u32; ```
1 parent ed81038 commit 95602a7

File tree

90 files changed

+287
-449
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+287
-449
lines changed

src/libarena/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,8 @@ impl<T> TypedArenaChunk<T> {
429429
// Destroy the next chunk.
430430
let next = self.next;
431431
let size = calculate_size::<T>(self.capacity);
432-
deallocate(self as *mut TypedArenaChunk<T> as *mut u8, size,
432+
let self_ptr: *mut TypedArenaChunk<T> = self;
433+
deallocate(self_ptr as *mut u8, size,
433434
mem::min_align_of::<TypedArenaChunk<T>>());
434435
if !next.is_null() {
435436
let capacity = (*next).capacity;

src/libcollections/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
html_playground_url = "http://play.rust-lang.org/")]
2525
#![doc(test(no_crate_inject))]
2626

27+
#![allow(trivial_cast)]
28+
#![allow(trivial_numeric_cast)]
2729
#![feature(alloc)]
2830
#![feature(box_syntax)]
2931
#![feature(box_patterns)]

src/libcollections/vec.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,8 +1199,8 @@ impl<T: PartialEq> Vec<T> {
11991199

12001200
// Avoid bounds checks by using unsafe pointers.
12011201
let p = self.as_mut_ptr();
1202-
let mut r = 1;
1203-
let mut w = 1;
1202+
let mut r: usize = 1;
1203+
let mut w: usize = 1;
12041204

12051205
while r < ln {
12061206
let p_r = p.offset(r as isize);

src/libcore/cell.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,11 @@ impl<T> UnsafeCell<T> {
713713
/// ```
714714
#[inline]
715715
#[stable(feature = "rust1", since = "1.0.0")]
716-
pub fn get(&self) -> *mut T { &self.value as *const T as *mut T }
716+
pub fn get(&self) -> *mut T {
717+
// FIXME(#23542) Replace with type ascription.
718+
#![allow(trivial_cast)]
719+
&self.value as *const T as *mut T
720+
}
717721

718722
/// Unwraps the value
719723
///

src/libcore/fmt/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -833,20 +833,26 @@ impl<T> Pointer for *const T {
833833
#[stable(feature = "rust1", since = "1.0.0")]
834834
impl<T> Pointer for *mut T {
835835
fn fmt(&self, f: &mut Formatter) -> Result {
836+
// FIXME(#23542) Replace with type ascription.
837+
#![allow(trivial_cast)]
836838
Pointer::fmt(&(*self as *const T), f)
837839
}
838840
}
839841

840842
#[stable(feature = "rust1", since = "1.0.0")]
841843
impl<'a, T> Pointer for &'a T {
842844
fn fmt(&self, f: &mut Formatter) -> Result {
845+
// FIXME(#23542) Replace with type ascription.
846+
#![allow(trivial_cast)]
843847
Pointer::fmt(&(*self as *const T), f)
844848
}
845849
}
846850

847851
#[stable(feature = "rust1", since = "1.0.0")]
848852
impl<'a, T> Pointer for &'a mut T {
849853
fn fmt(&self, f: &mut Formatter) -> Result {
854+
// FIXME(#23542) Replace with type ascription.
855+
#![allow(trivial_cast)]
850856
Pointer::fmt(&(&**self as *const T), f)
851857
}
852858
}

src/libcore/fmt/num.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// FIXME: #6220 Implement floating point formatting
1414

1515
#![allow(unsigned_negation)]
16+
#![allow(trivial_numeric_cast)]
1617

1718
use fmt;
1819
use iter::IteratorExt;

src/libcore/hash/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,8 @@ mod impls {
182182
}
183183

184184
fn hash_slice<H: Hasher>(data: &[$ty], state: &mut H) {
185+
// FIXME(#23542) Replace with type ascription.
186+
#![allow(trivial_cast)]
185187
let newlen = data.len() * ::$ty::BYTES as usize;
186188
let ptr = data.as_ptr() as *const u8;
187189
state.write(unsafe { slice::from_raw_parts(ptr, newlen) })

src/libcore/mem.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,8 @@ pub fn drop<T>(_x: T) { }
313313
#[inline]
314314
#[stable(feature = "rust1", since = "1.0.0")]
315315
pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
316+
// FIXME(#23542) Replace with type ascription.
317+
#![allow(trivial_cast)]
316318
ptr::read(src as *const T as *const U)
317319
}
318320

src/libcore/num/i16.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@
1212
1313
#![stable(feature = "rust1", since = "1.0.0")]
1414
#![doc(primitive = "i16")]
15+
#![allow(trivial_numeric_cast)]
1516

1617
int_module! { i16, 16 }

src/libcore/num/i32.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@
1212
1313
#![stable(feature = "rust1", since = "1.0.0")]
1414
#![doc(primitive = "i32")]
15+
#![allow(trivial_numeric_cast)]
1516

1617
int_module! { i32, 32 }

src/libcore/num/i64.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@
1212
1313
#![stable(feature = "rust1", since = "1.0.0")]
1414
#![doc(primitive = "i64")]
15+
#![allow(trivial_numeric_cast)]
1516

1617
int_module! { i64, 64 }

src/libcore/num/i8.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@
1212
1313
#![stable(feature = "rust1", since = "1.0.0")]
1414
#![doc(primitive = "i8")]
15+
#![allow(trivial_numeric_cast)]
1516

1617
int_module! { i8, 8 }

src/libcore/num/int_macros.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// except according to those terms.
1010

1111
#![doc(hidden)]
12+
#![allow(trivial_numeric_cast)]
1213

1314
macro_rules! int_module { ($T:ty, $bits:expr) => (
1415

src/libcore/num/isize.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
1717
#![stable(feature = "rust1", since = "1.0.0")]
1818
#![doc(primitive = "isize")]
19+
#![allow(trivial_numeric_cast)]
1920

2021
#[cfg(target_pointer_width = "32")]
2122
int_module! { isize, 32 }

src/libcore/num/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
1515
#![stable(feature = "rust1", since = "1.0.0")]
1616
#![allow(missing_docs)]
17+
#![allow(trivial_numeric_cast)]
1718

1819
use self::wrapping::{OverflowingOps, WrappingOps};
1920

src/libcore/num/u16.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@
1212
1313
#![stable(feature = "rust1", since = "1.0.0")]
1414
#![doc(primitive = "u16")]
15+
#![allow(trivial_numeric_cast)]
1516

1617
uint_module! { u16, i16, 16 }

src/libcore/num/u32.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@
1212
1313
#![stable(feature = "rust1", since = "1.0.0")]
1414
#![doc(primitive = "u32")]
15+
#![allow(trivial_numeric_cast)]
1516

1617
uint_module! { u32, i32, 32 }

src/libcore/num/u64.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@
1212
1313
#![stable(feature = "rust1", since = "1.0.0")]
1414
#![doc(primitive = "u64")]
15+
#![allow(trivial_numeric_cast)]
1516

1617
uint_module! { u64, i64, 64 }

src/libcore/num/u8.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@
1212
1313
#![stable(feature = "rust1", since = "1.0.0")]
1414
#![doc(primitive = "u8")]
15+
#![allow(trivial_numeric_cast)]
1516

1617
uint_module! { u8, i8, 8 }

src/libcore/num/uint_macros.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// except according to those terms.
1010

1111
#![doc(hidden)]
12+
#![allow(trivial_numeric_cast)]
1213

1314
macro_rules! uint_module { ($T:ty, $T_SIGNED:ty, $bits:expr) => (
1415

src/libcore/num/usize.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,6 @@
1616
1717
#![stable(feature = "rust1", since = "1.0.0")]
1818
#![doc(primitive = "usize")]
19+
#![allow(trivial_numeric_cast)]
1920

2021
uint_module! { usize, isize, ::isize::BITS }

src/libcore/ptr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ impl<T: ?Sized> Unique<T> {
529529
/// Create a new `Unique`.
530530
#[unstable(feature = "unique")]
531531
pub unsafe fn new(ptr: *mut T) -> Unique<T> {
532-
Unique { pointer: NonZero::new(ptr as *const T), _marker: PhantomData }
532+
Unique { pointer: NonZero::new(ptr), _marker: PhantomData }
533533
}
534534

535535
/// Dereference the content.

src/libcore/str/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ pub unsafe fn from_utf8_unchecked<'a>(v: &'a [u8]) -> &'a str {
261261
reason = "use std::ffi::c_str_to_bytes + str::from_utf8")]
262262
pub unsafe fn from_c_str(s: *const i8) -> &'static str {
263263
let s = s as *const u8;
264-
let mut len = 0;
264+
let mut len: usize = 0;
265265
while *s.offset(len as isize) != 0 {
266266
len += 1;
267267
}

src/libcoretest/mem.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ fn test_transmute() {
9595
trait Foo { fn dummy(&self) { } }
9696
impl Foo for int {}
9797

98-
let a = box 100 as Box<Foo>;
98+
let a = box 100isize as Box<Foo>;
9999
unsafe {
100100
let x: ::core::raw::TraitObject = transmute(a);
101101
assert!(*(x.data as *const int) == 100);

src/libcoretest/ptr.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ fn test_as_ref() {
8484
assert_eq!(q.as_ref().unwrap(), &2);
8585

8686
// Lifetime inference
87-
let u = 2;
87+
let u = 2isize;
8888
{
89-
let p: *const int = &u as *const _;
89+
let p = &u as *const int;
9090
assert_eq!(p.as_ref().unwrap(), &2);
9191
}
9292
}
@@ -102,9 +102,9 @@ fn test_as_mut() {
102102
assert!(q.as_mut().unwrap() == &mut 2);
103103

104104
// Lifetime inference
105-
let mut u = 2;
105+
let mut u = 2isize;
106106
{
107-
let p: *mut int = &mut u as *mut _;
107+
let p = &mut u as *mut int;
108108
assert!(p.as_mut().unwrap() == &mut 2);
109109
}
110110
}
@@ -170,9 +170,9 @@ fn test_set_memory() {
170170

171171
#[test]
172172
fn test_unsized_unique() {
173-
let xs: &mut [_] = &mut [1, 2, 3];
174-
let ptr = unsafe { Unique::new(xs as *mut [_]) };
173+
let xs: &mut [i32] = &mut [1, 2, 3];
174+
let ptr = unsafe { Unique::new(xs as *mut [i32]) };
175175
let ys = unsafe { &mut **ptr };
176-
let zs: &mut [_] = &mut [1, 2, 3];
176+
let zs: &mut [i32] = &mut [1, 2, 3];
177177
assert!(ys == zs);
178178
}

src/liblog/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,10 +304,10 @@ pub fn log(level: u32, loc: &'static LogLocation, args: fmt::Arguments) {
304304
// Completely remove the local logger from TLS in case anyone attempts to
305305
// frob the slot while we're doing the logging. This will destroy any logger
306306
// set during logging.
307-
let mut logger = LOCAL_LOGGER.with(|s| {
307+
let mut logger: Box<Logger + Send> = LOCAL_LOGGER.with(|s| {
308308
s.borrow_mut().take()
309309
}).unwrap_or_else(|| {
310-
box DefaultLogger { handle: io::stderr() } as Box<Logger + Send>
310+
box DefaultLogger { handle: io::stderr() }
311311
});
312312
logger.log(&LogRecord {
313313
level: LogLevel(level),

src/librand/distributions/range.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
//! Generating numbers between two others.
1212
13+
#![allow(trivial_numeric_cast)]
14+
1315
// this is surprisingly complicated to be both generic & correct
1416

1517
use core::prelude::{PartialOrd};

src/librand/isaac.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,7 @@ impl Rng for Isaac64Rng {
447447

448448
#[inline]
449449
fn next_u64(&mut self) -> u64 {
450+
#![allow(trivial_numeric_cast)]
450451
if self.cnt == 0 {
451452
// make some more numbers
452453
self.isaac64();

src/librbml/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ pub mod reader {
353353
let (shift, mask) = SHIFT_MASK_TABLE[i];
354354
Ok(Res {
355355
val: ((val >> shift) & mask) as uint,
356-
next: start + (((32 - shift) >> 3) as uint)
356+
next: start + ((32 - shift) >> 3),
357357
})
358358
}
359359
}
@@ -573,7 +573,7 @@ pub mod reader {
573573
0 => doc_as_u8(r_doc) as u64,
574574
1 => doc_as_u16(r_doc) as u64,
575575
2 => doc_as_u32(r_doc) as u64,
576-
3 => doc_as_u64(r_doc) as u64,
576+
3 => doc_as_u64(r_doc),
577577
_ => unreachable!(),
578578
}
579579
} else {

src/librustc/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@
4747
#![feature(into_cow)]
4848
#![cfg_attr(test, feature(test))]
4949

50+
#![allow(trivial_cast)]
51+
#![allow(trivial_numeric_cast)]
52+
5053
extern crate arena;
5154
extern crate flate;
5255
extern crate fmt_macros;

src/librustc/lint/builtin.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,17 @@ declare_lint! {
100100
"detects transmutes of fat pointers"
101101
}
102102

103+
declare_lint! {
104+
pub TRIVIAL_CAST,
105+
Warn,
106+
"detects trivial casts which could be removed"
107+
}
108+
109+
declare_lint! {
110+
pub TRIVIAL_NUMERIC_CAST,
111+
Warn,
112+
"detects trivial casts of numeric types which could be removed"
113+
}
103114
/// Does nothing as a lint pass, but registers some `Lint`s
104115
/// which are used by other parts of the compiler.
105116
#[derive(Copy)]
@@ -121,7 +132,9 @@ impl LintPass for HardwiredLints {
121132
STABLE_FEATURES,
122133
UNKNOWN_CRATE_TYPES,
123134
VARIANT_SIZE_DIFFERENCES,
124-
FAT_PTR_TRANSMUTES
135+
FAT_PTR_TRANSMUTES,
136+
TRIVIAL_CAST,
137+
TRIVIAL_NUMERIC_CAST
125138
)
126139
}
127140
}

0 commit comments

Comments
 (0)