From 1ec9adcfc0da7b1cdfe8d42f7eedcbd727c6861c Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 21 Mar 2015 11:08:15 -0700 Subject: std: Tweak rt::at_exit behavior There have been some recent panics on the bots and this commit is an attempt to appease them. Previously it was considered invalid to run `rt::at_exit` after the handlers had already started running. Due to the multithreaded nature of applications, however, it is not always possible to guarantee this. For example [this program][ex] will show off the abort. [ex]: https://gist.github.com/alexcrichton/56300b87af6fa554e52d The semantics of the `rt::at_exit` function have been modified as such: * It is now legal to call `rt::at_exit` at any time. The return value now indicates whether the closure was successfully registered or not. Callers must now decide what to do with this information. * The `rt::at_exit` handlers will now be run for a fixed number of iterations. Common cases (such as the example shown) may end up registering a new handler while others are running perhaps once or twice, so this common condition is covered by re-running the handlers a fixed number of times, after which new registrations are forbidden. Some usage of `rt::at_exit` was updated to handle these new semantics, but deprecated or unstable libraries calling `rt::at_exit` were not updated. --- src/libstd/io/lazy.rs | 24 +++++++++----- src/libstd/old_io/stdio.rs | 2 +- src/libstd/rt/at_exit_imp.rs | 59 +++++++++++++++++++++------------- src/libstd/rt/mod.rs | 22 ++++++------- src/libstd/sys/common/helper_thread.rs | 2 +- 5 files changed, 64 insertions(+), 45 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/io/lazy.rs b/src/libstd/io/lazy.rs index c9b105f72a5..df280dab37d 100644 --- a/src/libstd/io/lazy.rs +++ b/src/libstd/io/lazy.rs @@ -35,25 +35,33 @@ impl Lazy { pub fn get(&'static self) -> Option> { let _g = self.lock.lock(); unsafe { - let mut ptr = *self.ptr.get(); + let ptr = *self.ptr.get(); if ptr.is_null() { - ptr = boxed::into_raw(self.init()); - *self.ptr.get() = ptr; + Some(self.init()) } else if ptr as usize == 1 { - return None + None + } else { + Some((*ptr).clone()) } - Some((*ptr).clone()) } } - fn init(&'static self) -> Box> { - rt::at_exit(move || unsafe { + unsafe fn init(&'static self) -> Arc { + // If we successfully register an at exit handler, then we cache the + // `Arc` allocation in our own internal box (it will get deallocated by + // the at exit handler). Otherwise we just return the freshly allocated + // `Arc`. + let registered = rt::at_exit(move || { let g = self.lock.lock(); let ptr = *self.ptr.get(); *self.ptr.get() = 1 as *mut _; drop(g); drop(Box::from_raw(ptr)) }); - Box::new((self.init)()) + let ret = (self.init)(); + if registered.is_ok() { + *self.ptr.get() = boxed::into_raw(Box::new(ret.clone())); + } + return ret } } diff --git a/src/libstd/old_io/stdio.rs b/src/libstd/old_io/stdio.rs index a1c8630e0ec..a48758366f3 100644 --- a/src/libstd/old_io/stdio.rs +++ b/src/libstd/old_io/stdio.rs @@ -238,7 +238,7 @@ pub fn stdin() -> StdinReader { STDIN = boxed::into_raw(box stdin); // Make sure to free it at exit - rt::at_exit(|| { + let _ = rt::at_exit(|| { Box::from_raw(STDIN); STDIN = ptr::null_mut(); }); diff --git a/src/libstd/rt/at_exit_imp.rs b/src/libstd/rt/at_exit_imp.rs index 9fa12b1ef30..9079c0aaffb 100644 --- a/src/libstd/rt/at_exit_imp.rs +++ b/src/libstd/rt/at_exit_imp.rs @@ -12,6 +12,10 @@ //! //! Documentation can be found on the `rt::at_exit` function. +// FIXME: switch this to use atexit. Currently this +// segfaults (the queue's memory is mysteriously gone), so +// instead the cleanup is tied to the `std::rt` entry point. + use boxed; use boxed::Box; use vec::Vec; @@ -27,47 +31,56 @@ type Queue = Vec>; static LOCK: Mutex = MUTEX_INIT; static mut QUEUE: *mut Queue = 0 as *mut Queue; -unsafe fn init() { +// The maximum number of times the cleanup routines will be run. While running +// the at_exit closures new ones may be registered, and this count is the number +// of times the new closures will be allowed to register successfully. After +// this number of iterations all new registrations will return `false`. +const ITERS: usize = 10; + +unsafe fn init() -> bool { if QUEUE.is_null() { let state: Box = box Vec::new(); QUEUE = boxed::into_raw(state); - } else { + } else if QUEUE as usize == 1 { // can't re-init after a cleanup - rtassert!(QUEUE as uint != 1); + return false } - // FIXME: switch this to use atexit as below. Currently this - // segfaults (the queue's memory is mysteriously gone), so - // instead the cleanup is tied to the `std::rt` entry point. - // - // ::libc::atexit(cleanup); + return true } pub fn cleanup() { - unsafe { - LOCK.lock(); - let queue = QUEUE; - QUEUE = 1 as *mut _; - LOCK.unlock(); + for i in 0..ITERS { + unsafe { + LOCK.lock(); + let queue = QUEUE; + QUEUE = if i == ITERS - 1 {1} else {0} as *mut _; + LOCK.unlock(); - // make sure we're not recursively cleaning up - rtassert!(queue as uint != 1); + // make sure we're not recursively cleaning up + rtassert!(queue as usize != 1); - // If we never called init, not need to cleanup! - if queue as uint != 0 { - let queue: Box = Box::from_raw(queue); - for to_run in *queue { - to_run.invoke(()); + // If we never called init, not need to cleanup! + if queue as usize != 0 { + let queue: Box = Box::from_raw(queue); + for to_run in *queue { + to_run.invoke(()); + } } } } } -pub fn push(f: Thunk<'static>) { +pub fn push(f: Thunk<'static>) -> bool { + let mut ret = true; unsafe { LOCK.lock(); - init(); - (*QUEUE).push(f); + if init() { + (*QUEUE).push(f); + } else { + ret = false; + } LOCK.unlock(); } + return ret } diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index e52e68dad23..43aa4155629 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -17,14 +17,9 @@ //! time being. #![unstable(feature = "std_misc")] - -// FIXME: this should not be here. #![allow(missing_docs)] -#![allow(dead_code)] - -use marker::Send; -use ops::FnOnce; +use prelude::v1::*; use sys; use thunk::Thunk; use usize; @@ -149,13 +144,16 @@ fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int { /// Enqueues a procedure to run when the main thread exits. /// -/// It is forbidden for procedures to register more `at_exit` handlers when they -/// are running, and doing so will lead to a process abort. +/// Currently these closures are only run once the main *Rust* thread exits. +/// Once the `at_exit` handlers begin running, more may be enqueued, but not +/// infinitely so. Eventually a handler registration will be forced to fail. /// -/// Note that other threads may still be running when `at_exit` routines start -/// running. -pub fn at_exit(f: F) { - at_exit_imp::push(Thunk::new(f)); +/// Returns `Ok` if the handler was successfully registered, meaning that the +/// closure will be run once the main thread exits. Returns `Err` to indicate +/// that the closure could not be registered, meaning that it is not scheduled +/// to be rune. +pub fn at_exit(f: F) -> Result<(), ()> { + if at_exit_imp::push(Thunk::new(f)) {Ok(())} else {Err(())} } /// One-time runtime cleanup. diff --git a/src/libstd/sys/common/helper_thread.rs b/src/libstd/sys/common/helper_thread.rs index 2a852fbcd57..53f18a57325 100644 --- a/src/libstd/sys/common/helper_thread.rs +++ b/src/libstd/sys/common/helper_thread.rs @@ -112,7 +112,7 @@ impl Helper { self.cond.notify_one() }); - rt::at_exit(move || { self.shutdown() }); + let _ = rt::at_exit(move || { self.shutdown() }); *self.initialized.get() = true; } else if *self.chan.get() as uint == 1 { panic!("cannot continue usage after shutdown"); -- cgit 1.4.1-3-g733a5 From a34e87f3ab29f6643679d2e430f21724cdcc26b6 Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Mon, 23 Mar 2015 15:40:43 -0400 Subject: Add Examples for File This is pretty basic, but it's nice to have something. --- src/libstd/fs/mod.rs | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/fs/mod.rs b/src/libstd/fs/mod.rs index 7df6d6887a2..72f4fbb116c 100644 --- a/src/libstd/fs/mod.rs +++ b/src/libstd/fs/mod.rs @@ -128,6 +128,17 @@ impl File { /// /// This function will return an error if `path` does not already exist. /// Other errors may also be returned according to `OpenOptions::open`. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs::File; + /// + /// # fn foo() -> std::io::Result<()> { + /// let mut f = try!(File::open("foo.txt")); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn open(path: P) -> io::Result { OpenOptions::new().read(true).open(path) @@ -139,6 +150,17 @@ impl File { /// and will truncate it if it does. /// /// See the `OpenOptions::open` function for more details. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs::File; + /// + /// # fn foo() -> std::io::Result<()> { + /// let mut f = try!(File::create("foo.txt")); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn create(path: P) -> io::Result { OpenOptions::new().write(true).create(true).truncate(true).open(path) @@ -156,6 +178,20 @@ impl File { /// /// This function will attempt to ensure that all in-core data reaches the /// filesystem before returning. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs::File; + /// + /// # fn foo() -> std::io::Result<()> { + /// let mut f = try!(File::create("foo.txt")); + /// try!(f.write_all(b"Hello, world!")); + /// + /// try!(f.sync_all()); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn sync_all(&self) -> io::Result<()> { self.inner.fsync() @@ -170,6 +206,20 @@ impl File { /// /// Note that some platforms may simply implement this in terms of /// `sync_all`. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs::File; + /// + /// # fn foo() -> std::io::Result<()> { + /// let mut f = try!(File::create("foo.txt")); + /// try!(f.write_all(b"Hello, world!")); + /// + /// try!(f.sync_data()); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn sync_data(&self) -> io::Result<()> { self.inner.datasync() @@ -182,12 +232,36 @@ impl File { /// be shrunk. If it is greater than the current file's size, then the file /// will be extended to `size` and have all of the intermediate data filled /// in with 0s. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs::File; + /// + /// # fn foo() -> std::io::Result<()> { + /// let mut f = try!(File::open("foo.txt")); + /// try!(f.set_len(0)); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn set_len(&self, size: u64) -> io::Result<()> { self.inner.truncate(size) } /// Queries metadata about the underlying file. + /// + /// # Examples + /// + /// ```no_run + /// use std::fs::File; + /// + /// # fn foo() -> std::io::Result<()> { + /// let mut f = try!(File::open("foo.txt")); + /// let metadata = try!(f.metadata()); + /// # Ok(()) + /// # } + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn metadata(&self) -> io::Result { self.inner.file_attr().map(Metadata) -- cgit 1.4.1-3-g733a5 From 4ccf374b4a2ef24862d365783b70217bbfbf3bc7 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 24 Mar 2015 11:14:35 -0700 Subject: std: Zero memory when calling `read_to_end()` This commit alters the behavior of the `Read::read_to_end()` method to zero all memory instead of passing an uninitialized buffer to `read`. This change is motivated by the [discussion on the internals forum][discuss] where the conclusion has been that the standard library will not expose uninitialized memory. [discuss]: http://internals.rust-lang.org/t/uninitialized-memory/1652 Closes #20314 --- src/libstd/io/mod.rs | 44 ++++++++++++++------------------------------ 1 file changed, 14 insertions(+), 30 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 237435d6dfb..33c4156fc0c 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -16,13 +16,12 @@ use cmp; use unicode::str as core_str; use error as std_error; use fmt; -use iter::Iterator; +use iter::{self, Iterator, IteratorExt, Extend}; use marker::Sized; use ops::{Drop, FnOnce}; use option::Option::{self, Some, None}; use result::Result::{Ok, Err}; use result; -use slice; use string::String; use str; use vec::Vec; @@ -50,41 +49,26 @@ mod stdio; const DEFAULT_BUF_SIZE: usize = 64 * 1024; // Acquires a slice of the vector `v` from its length to its capacity -// (uninitialized data), reads into it, and then updates the length. +// (after initializing the data), reads into it, and then updates the length. // // This function is leveraged to efficiently read some bytes into a destination // vector without extra copying and taking advantage of the space that's already // in `v`. -// -// The buffer we're passing down, however, is pointing at uninitialized data -// (the end of a `Vec`), and many operations will be *much* faster if we don't -// have to zero it out. In order to prevent LLVM from generating an `undef` -// value when reads happen from this uninitialized memory, we force LLVM to -// think it's initialized by sending it through a black box. This should prevent -// actual undefined behavior after optimizations. fn with_end_to_cap(v: &mut Vec, f: F) -> Result where F: FnOnce(&mut [u8]) -> Result { - unsafe { - let n = try!(f({ - let base = v.as_mut_ptr().offset(v.len() as isize); - black_box(slice::from_raw_parts_mut(base, - v.capacity() - v.len())) - })); - - // If the closure (typically a `read` implementation) reported that it - // read a larger number of bytes than the vector actually has, we need - // to be sure to clamp the vector to at most its capacity. - let new_len = cmp::min(v.capacity(), v.len() + n); - v.set_len(new_len); - return Ok(n); - } - - // Semi-hack used to prevent LLVM from retaining any assumptions about - // `dummy` over this function call - unsafe fn black_box(mut dummy: T) -> T { - asm!("" :: "r"(&mut dummy) : "memory"); - dummy + let len = v.len(); + let new_area = v.capacity() - len; + v.extend(iter::repeat(0).take(new_area)); + match f(&mut v[len..]) { + Ok(n) => { + v.truncate(len + n); + Ok(n) + } + Err(e) => { + v.truncate(len); + Err(e) + } } } -- cgit 1.4.1-3-g733a5 From 95602a759d9190cad92279aa5929d30166f2255c Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Fri, 20 Mar 2015 17:15:27 +1300 Subject: 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; ``` --- src/libarena/lib.rs | 3 +- src/libcollections/lib.rs | 2 + src/libcollections/vec.rs | 4 +- src/libcore/cell.rs | 6 +- src/libcore/fmt/mod.rs | 6 + src/libcore/fmt/num.rs | 1 + src/libcore/hash/mod.rs | 2 + src/libcore/mem.rs | 2 + src/libcore/num/i16.rs | 1 + src/libcore/num/i32.rs | 1 + src/libcore/num/i64.rs | 1 + src/libcore/num/i8.rs | 1 + src/libcore/num/int_macros.rs | 1 + src/libcore/num/isize.rs | 1 + src/libcore/num/mod.rs | 1 + src/libcore/num/u16.rs | 1 + src/libcore/num/u32.rs | 1 + src/libcore/num/u64.rs | 1 + src/libcore/num/u8.rs | 1 + src/libcore/num/uint_macros.rs | 1 + src/libcore/num/usize.rs | 1 + src/libcore/ptr.rs | 2 +- src/libcore/str/mod.rs | 2 +- src/libcoretest/mem.rs | 2 +- src/libcoretest/ptr.rs | 14 +- src/liblog/lib.rs | 4 +- src/librand/distributions/range.rs | 2 + src/librand/isaac.rs | 1 + src/librbml/lib.rs | 4 +- src/librustc/lib.rs | 3 + src/librustc/lint/builtin.rs | 15 ++- src/librustc/middle/ty.rs | 33 +---- src/librustc_lint/builtin.rs | 3 + src/librustc_lint/lib.rs | 8 +- src/librustc_llvm/lib.rs | 2 + src/librustc_trans/lib.rs | 3 + src/librustc_trans/trans/datum.rs | 9 -- src/librustc_trans/trans/expr.rs | 24 +--- src/librustc_trans/trans/meth.rs | 40 +----- src/librustc_typeck/check/coercion.rs | 12 +- src/librustc_typeck/check/demand.rs | 8 +- src/librustc_typeck/check/mod.rs | 150 ++++++++++++--------- src/librustc_typeck/check/vtable.rs | 78 ----------- src/librustdoc/html/markdown.rs | 14 +- src/libserialize/json.rs | 10 +- src/libstd/lib.rs | 2 + src/libstd/old_io/stdio.rs | 4 +- src/libstd/rt/mod.rs | 2 +- src/libsyntax/codemap.rs | 6 +- src/libsyntax/ext/base.rs | 6 +- src/libsyntax/ext/quote.rs | 1 + src/libsyntax/ext/tt/macro_rules.rs | 2 +- src/libsyntax/parse/lexer/mod.rs | 4 +- src/libsyntax/parse/parser.rs | 2 +- src/libsyntax/print/pprust.rs | 2 +- src/libterm/lib.rs | 12 +- src/libterm/terminfo/mod.rs | 4 +- src/libterm/terminfo/parser/compiled.rs | 2 +- src/libtest/lib.rs | 2 +- src/rustbook/subcommand.rs | 10 +- src/test/auxiliary/issue-11224.rs | 2 +- src/test/compile-fail/issue-14845.rs | 4 +- src/test/compile-fail/issue-16538.rs | 3 +- src/test/compile-fail/issue-5543.rs | 19 --- src/test/compile-fail/kindck-impl-type-params.rs | 1 + src/test/compile-fail/lint-dead-code-3.rs | 2 +- src/test/compile-fail/lint-unnecessary-casts.rs | 24 ---- src/test/compile-fail/liveness-unused.rs | 2 +- .../compile-fail/object-safety-by-value-self.rs | 1 + .../regions-close-object-into-object-5.rs | 1 + .../regions-close-over-type-parameter-1.rs | 2 + ...pe-parameter-defaults-referencing-Self-ppaux.rs | 2 +- src/test/compile-fail/vector-cast-weirdness.rs | 6 +- src/test/debuginfo/type-names.rs | 12 +- src/test/pretty/path-type-bounds.rs | 2 +- src/test/run-make/symbols-are-reasonable/lib.rs | 2 +- src/test/run-pass/autoderef-method-on-trait.rs | 2 +- src/test/run-pass/cast-region-to-uint.rs | 2 +- .../run-pass/infer-container-across-object-cast.rs | 61 --------- src/test/run-pass/issue-15763.rs | 8 +- src/test/run-pass/issue-5708.rs | 2 +- src/test/run-pass/issue-9719.rs | 6 +- ...od-two-traits-distinguished-via-where-clause.rs | 2 +- src/test/run-pass/object-one-type-two-traits.rs | 2 +- .../run-pass/objects-coerce-freeze-borrored.rs | 2 +- .../run-pass/regions-early-bound-trait-param.rs | 5 +- src/test/run-pass/stable-addr-of.rs | 2 +- src/test/run-pass/task-spawn-move-and-copy.rs | 2 +- src/test/run-pass/typeck_type_placeholder_1.rs | 10 +- src/test/run-pass/zero_sized_subslice_match.rs | 2 +- 90 files changed, 287 insertions(+), 449 deletions(-) delete mode 100644 src/test/compile-fail/issue-5543.rs delete mode 100644 src/test/compile-fail/lint-unnecessary-casts.rs delete mode 100644 src/test/run-pass/infer-container-across-object-cast.rs (limited to 'src/libstd') diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 1b0356b88b0..7843be0b483 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -429,7 +429,8 @@ impl TypedArenaChunk { // Destroy the next chunk. let next = self.next; let size = calculate_size::(self.capacity); - deallocate(self as *mut TypedArenaChunk as *mut u8, size, + let self_ptr: *mut TypedArenaChunk = self; + deallocate(self_ptr as *mut u8, size, mem::min_align_of::>()); if !next.is_null() { let capacity = (*next).capacity; diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index da2c61b6fd3..0a61eeb6e1c 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -24,6 +24,8 @@ html_playground_url = "http://play.rust-lang.org/")] #![doc(test(no_crate_inject))] +#![allow(trivial_cast)] +#![allow(trivial_numeric_cast)] #![feature(alloc)] #![feature(box_syntax)] #![feature(box_patterns)] diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 59819d01bc6..af2daabc2d0 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -1199,8 +1199,8 @@ impl Vec { // Avoid bounds checks by using unsafe pointers. let p = self.as_mut_ptr(); - let mut r = 1; - let mut w = 1; + let mut r: usize = 1; + let mut w: usize = 1; while r < ln { let p_r = p.offset(r as isize); diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index a9c5de23d94..f5db3e63c7a 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -713,7 +713,11 @@ impl UnsafeCell { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn get(&self) -> *mut T { &self.value as *const T as *mut T } + pub fn get(&self) -> *mut T { + // FIXME(#23542) Replace with type ascription. + #![allow(trivial_cast)] + &self.value as *const T as *mut T + } /// Unwraps the value /// diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index cf427c16588..e00cdc9de88 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -833,6 +833,8 @@ impl Pointer for *const T { #[stable(feature = "rust1", since = "1.0.0")] impl Pointer for *mut T { fn fmt(&self, f: &mut Formatter) -> Result { + // FIXME(#23542) Replace with type ascription. + #![allow(trivial_cast)] Pointer::fmt(&(*self as *const T), f) } } @@ -840,6 +842,8 @@ impl Pointer for *mut T { #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> Pointer for &'a T { fn fmt(&self, f: &mut Formatter) -> Result { + // FIXME(#23542) Replace with type ascription. + #![allow(trivial_cast)] Pointer::fmt(&(*self as *const T), f) } } @@ -847,6 +851,8 @@ impl<'a, T> Pointer for &'a T { #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> Pointer for &'a mut T { fn fmt(&self, f: &mut Formatter) -> Result { + // FIXME(#23542) Replace with type ascription. + #![allow(trivial_cast)] Pointer::fmt(&(&**self as *const T), f) } } diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index 49da99b97cb..d01d240e5b5 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -13,6 +13,7 @@ // FIXME: #6220 Implement floating point formatting #![allow(unsigned_negation)] +#![allow(trivial_numeric_cast)] use fmt; use iter::IteratorExt; diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs index 1d5e174a8dc..ccc1d32eab3 100644 --- a/src/libcore/hash/mod.rs +++ b/src/libcore/hash/mod.rs @@ -182,6 +182,8 @@ mod impls { } fn hash_slice(data: &[$ty], state: &mut H) { + // FIXME(#23542) Replace with type ascription. + #![allow(trivial_cast)] let newlen = data.len() * ::$ty::BYTES as usize; let ptr = data.as_ptr() as *const u8; state.write(unsafe { slice::from_raw_parts(ptr, newlen) }) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 551f97ead12..0bc41eb2c6e 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -313,6 +313,8 @@ pub fn drop(_x: T) { } #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn transmute_copy(src: &T) -> U { + // FIXME(#23542) Replace with type ascription. + #![allow(trivial_cast)] ptr::read(src as *const T as *const U) } diff --git a/src/libcore/num/i16.rs b/src/libcore/num/i16.rs index 5ea60d0d96d..1557434a28a 100644 --- a/src/libcore/num/i16.rs +++ b/src/libcore/num/i16.rs @@ -12,5 +12,6 @@ #![stable(feature = "rust1", since = "1.0.0")] #![doc(primitive = "i16")] +#![allow(trivial_numeric_cast)] int_module! { i16, 16 } diff --git a/src/libcore/num/i32.rs b/src/libcore/num/i32.rs index 7d9faa998c1..bdccab4cb9a 100644 --- a/src/libcore/num/i32.rs +++ b/src/libcore/num/i32.rs @@ -12,5 +12,6 @@ #![stable(feature = "rust1", since = "1.0.0")] #![doc(primitive = "i32")] +#![allow(trivial_numeric_cast)] int_module! { i32, 32 } diff --git a/src/libcore/num/i64.rs b/src/libcore/num/i64.rs index 5a70911387b..d8f5aa6e548 100644 --- a/src/libcore/num/i64.rs +++ b/src/libcore/num/i64.rs @@ -12,5 +12,6 @@ #![stable(feature = "rust1", since = "1.0.0")] #![doc(primitive = "i64")] +#![allow(trivial_numeric_cast)] int_module! { i64, 64 } diff --git a/src/libcore/num/i8.rs b/src/libcore/num/i8.rs index 1d7d78ffa6c..da2410a04cf 100644 --- a/src/libcore/num/i8.rs +++ b/src/libcore/num/i8.rs @@ -12,5 +12,6 @@ #![stable(feature = "rust1", since = "1.0.0")] #![doc(primitive = "i8")] +#![allow(trivial_numeric_cast)] int_module! { i8, 8 } diff --git a/src/libcore/num/int_macros.rs b/src/libcore/num/int_macros.rs index fe0d6d13c4c..5f697e02a99 100644 --- a/src/libcore/num/int_macros.rs +++ b/src/libcore/num/int_macros.rs @@ -9,6 +9,7 @@ // except according to those terms. #![doc(hidden)] +#![allow(trivial_numeric_cast)] macro_rules! int_module { ($T:ty, $bits:expr) => ( diff --git a/src/libcore/num/isize.rs b/src/libcore/num/isize.rs index 0fd0d90b125..838caa59e47 100644 --- a/src/libcore/num/isize.rs +++ b/src/libcore/num/isize.rs @@ -16,6 +16,7 @@ #![stable(feature = "rust1", since = "1.0.0")] #![doc(primitive = "isize")] +#![allow(trivial_numeric_cast)] #[cfg(target_pointer_width = "32")] int_module! { isize, 32 } diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 9ca7b48fbe5..7686a990acc 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -14,6 +14,7 @@ #![stable(feature = "rust1", since = "1.0.0")] #![allow(missing_docs)] +#![allow(trivial_numeric_cast)] use self::wrapping::{OverflowingOps, WrappingOps}; diff --git a/src/libcore/num/u16.rs b/src/libcore/num/u16.rs index 21635799a77..9d91bbc7f90 100644 --- a/src/libcore/num/u16.rs +++ b/src/libcore/num/u16.rs @@ -12,5 +12,6 @@ #![stable(feature = "rust1", since = "1.0.0")] #![doc(primitive = "u16")] +#![allow(trivial_numeric_cast)] uint_module! { u16, i16, 16 } diff --git a/src/libcore/num/u32.rs b/src/libcore/num/u32.rs index 7d520770503..2d5f163e093 100644 --- a/src/libcore/num/u32.rs +++ b/src/libcore/num/u32.rs @@ -12,5 +12,6 @@ #![stable(feature = "rust1", since = "1.0.0")] #![doc(primitive = "u32")] +#![allow(trivial_numeric_cast)] uint_module! { u32, i32, 32 } diff --git a/src/libcore/num/u64.rs b/src/libcore/num/u64.rs index f10822077dc..26813aa281c 100644 --- a/src/libcore/num/u64.rs +++ b/src/libcore/num/u64.rs @@ -12,5 +12,6 @@ #![stable(feature = "rust1", since = "1.0.0")] #![doc(primitive = "u64")] +#![allow(trivial_numeric_cast)] uint_module! { u64, i64, 64 } diff --git a/src/libcore/num/u8.rs b/src/libcore/num/u8.rs index 3d6922b07b1..7fb28f27d62 100644 --- a/src/libcore/num/u8.rs +++ b/src/libcore/num/u8.rs @@ -12,5 +12,6 @@ #![stable(feature = "rust1", since = "1.0.0")] #![doc(primitive = "u8")] +#![allow(trivial_numeric_cast)] uint_module! { u8, i8, 8 } diff --git a/src/libcore/num/uint_macros.rs b/src/libcore/num/uint_macros.rs index d0c4885ad00..9f502e3ea43 100644 --- a/src/libcore/num/uint_macros.rs +++ b/src/libcore/num/uint_macros.rs @@ -9,6 +9,7 @@ // except according to those terms. #![doc(hidden)] +#![allow(trivial_numeric_cast)] macro_rules! uint_module { ($T:ty, $T_SIGNED:ty, $bits:expr) => ( diff --git a/src/libcore/num/usize.rs b/src/libcore/num/usize.rs index 602ef4fe45e..be5acaac92a 100644 --- a/src/libcore/num/usize.rs +++ b/src/libcore/num/usize.rs @@ -16,5 +16,6 @@ #![stable(feature = "rust1", since = "1.0.0")] #![doc(primitive = "usize")] +#![allow(trivial_numeric_cast)] uint_module! { usize, isize, ::isize::BITS } diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index d92622eeb70..9b3ee3ef5e0 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -529,7 +529,7 @@ impl Unique { /// Create a new `Unique`. #[unstable(feature = "unique")] pub unsafe fn new(ptr: *mut T) -> Unique { - Unique { pointer: NonZero::new(ptr as *const T), _marker: PhantomData } + Unique { pointer: NonZero::new(ptr), _marker: PhantomData } } /// Dereference the content. diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index b7285d30a73..035d070cd6d 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -261,7 +261,7 @@ pub unsafe fn from_utf8_unchecked<'a>(v: &'a [u8]) -> &'a str { reason = "use std::ffi::c_str_to_bytes + str::from_utf8")] pub unsafe fn from_c_str(s: *const i8) -> &'static str { let s = s as *const u8; - let mut len = 0; + let mut len: usize = 0; while *s.offset(len as isize) != 0 { len += 1; } diff --git a/src/libcoretest/mem.rs b/src/libcoretest/mem.rs index bf3e1cf03cb..17d6b684c50 100644 --- a/src/libcoretest/mem.rs +++ b/src/libcoretest/mem.rs @@ -95,7 +95,7 @@ fn test_transmute() { trait Foo { fn dummy(&self) { } } impl Foo for int {} - let a = box 100 as Box; + let a = box 100isize as Box; unsafe { let x: ::core::raw::TraitObject = transmute(a); assert!(*(x.data as *const int) == 100); diff --git a/src/libcoretest/ptr.rs b/src/libcoretest/ptr.rs index adc15b9fbc2..4f5f269d437 100644 --- a/src/libcoretest/ptr.rs +++ b/src/libcoretest/ptr.rs @@ -84,9 +84,9 @@ fn test_as_ref() { assert_eq!(q.as_ref().unwrap(), &2); // Lifetime inference - let u = 2; + let u = 2isize; { - let p: *const int = &u as *const _; + let p = &u as *const int; assert_eq!(p.as_ref().unwrap(), &2); } } @@ -102,9 +102,9 @@ fn test_as_mut() { assert!(q.as_mut().unwrap() == &mut 2); // Lifetime inference - let mut u = 2; + let mut u = 2isize; { - let p: *mut int = &mut u as *mut _; + let p = &mut u as *mut int; assert!(p.as_mut().unwrap() == &mut 2); } } @@ -170,9 +170,9 @@ fn test_set_memory() { #[test] fn test_unsized_unique() { - let xs: &mut [_] = &mut [1, 2, 3]; - let ptr = unsafe { Unique::new(xs as *mut [_]) }; + let xs: &mut [i32] = &mut [1, 2, 3]; + let ptr = unsafe { Unique::new(xs as *mut [i32]) }; let ys = unsafe { &mut **ptr }; - let zs: &mut [_] = &mut [1, 2, 3]; + let zs: &mut [i32] = &mut [1, 2, 3]; assert!(ys == zs); } diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs index 4537fc763c9..2c431e1e050 100644 --- a/src/liblog/lib.rs +++ b/src/liblog/lib.rs @@ -304,10 +304,10 @@ pub fn log(level: u32, loc: &'static LogLocation, args: fmt::Arguments) { // Completely remove the local logger from TLS in case anyone attempts to // frob the slot while we're doing the logging. This will destroy any logger // set during logging. - let mut logger = LOCAL_LOGGER.with(|s| { + let mut logger: Box = LOCAL_LOGGER.with(|s| { s.borrow_mut().take() }).unwrap_or_else(|| { - box DefaultLogger { handle: io::stderr() } as Box + box DefaultLogger { handle: io::stderr() } }); logger.log(&LogRecord { level: LogLevel(level), diff --git a/src/librand/distributions/range.rs b/src/librand/distributions/range.rs index e6f27a28ffa..0001cb6e0ca 100644 --- a/src/librand/distributions/range.rs +++ b/src/librand/distributions/range.rs @@ -10,6 +10,8 @@ //! Generating numbers between two others. +#![allow(trivial_numeric_cast)] + // this is surprisingly complicated to be both generic & correct use core::prelude::{PartialOrd}; diff --git a/src/librand/isaac.rs b/src/librand/isaac.rs index 7ea62b7fd3f..673246fe30d 100644 --- a/src/librand/isaac.rs +++ b/src/librand/isaac.rs @@ -447,6 +447,7 @@ impl Rng for Isaac64Rng { #[inline] fn next_u64(&mut self) -> u64 { + #![allow(trivial_numeric_cast)] if self.cnt == 0 { // make some more numbers self.isaac64(); diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs index 1a794f56f80..182b05acbb6 100644 --- a/src/librbml/lib.rs +++ b/src/librbml/lib.rs @@ -353,7 +353,7 @@ pub mod reader { let (shift, mask) = SHIFT_MASK_TABLE[i]; Ok(Res { val: ((val >> shift) & mask) as uint, - next: start + (((32 - shift) >> 3) as uint) + next: start + ((32 - shift) >> 3), }) } } @@ -573,7 +573,7 @@ pub mod reader { 0 => doc_as_u8(r_doc) as u64, 1 => doc_as_u16(r_doc) as u64, 2 => doc_as_u32(r_doc) as u64, - 3 => doc_as_u64(r_doc) as u64, + 3 => doc_as_u64(r_doc), _ => unreachable!(), } } else { diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 793eff6a9da..dd5f3cccea5 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -47,6 +47,9 @@ #![feature(into_cow)] #![cfg_attr(test, feature(test))] +#![allow(trivial_cast)] +#![allow(trivial_numeric_cast)] + extern crate arena; extern crate flate; extern crate fmt_macros; diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 44718d1c525..4f56f2441dc 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -100,6 +100,17 @@ declare_lint! { "detects transmutes of fat pointers" } +declare_lint! { + pub TRIVIAL_CAST, + Warn, + "detects trivial casts which could be removed" +} + +declare_lint! { + pub TRIVIAL_NUMERIC_CAST, + Warn, + "detects trivial casts of numeric types which could be removed" +} /// Does nothing as a lint pass, but registers some `Lint`s /// which are used by other parts of the compiler. #[derive(Copy)] @@ -121,7 +132,9 @@ impl LintPass for HardwiredLints { STABLE_FEATURES, UNKNOWN_CRATE_TYPES, VARIANT_SIZE_DIFFERENCES, - FAT_PTR_TRANSMUTES + FAT_PTR_TRANSMUTES, + TRIVIAL_CAST, + TRIVIAL_NUMERIC_CAST ) } } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index e5e89c3fbd4..38a20c61d2e 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -968,7 +968,7 @@ impl<'tcx> Eq for TyS<'tcx> {} impl<'tcx> Hash for TyS<'tcx> { fn hash(&self, s: &mut H) { - (self as *const _).hash(s) + (self as *const TyS).hash(s) } } @@ -2721,7 +2721,7 @@ fn intern_ty<'tcx>(type_arena: &'tcx TypedArena>, }; debug!("Interned type: {:?} Pointer: {:?}", - ty, ty as *const _); + ty, ty as *const TyS); interner.insert(InternedTy { ty: ty }, ty); @@ -4806,32 +4806,6 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind { RvalueDpsExpr } - ast::ExprCast(..) => { - match tcx.node_types.borrow().get(&expr.id) { - Some(&ty) => { - if type_is_trait(ty) { - RvalueDpsExpr - } else { - RvalueDatumExpr - } - } - None => { - // Technically, it should not happen that the expr is not - // present within the table. However, it DOES happen - // during type check, because the final types from the - // expressions are not yet recorded in the tcx. At that - // time, though, we are only interested in knowing lvalue - // vs rvalue. It would be better to base this decision on - // the AST type in cast node---but (at the time of this - // writing) it's not easy to distinguish casts to traits - // from other casts based on the AST. This should be - // easier in the future, when casts to traits - // would like @Foo, Box, or &Foo. - RvalueDatumExpr - } - } - } - ast::ExprBreak(..) | ast::ExprAgain(..) | ast::ExprRet(..) | @@ -4847,7 +4821,8 @@ pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind { ast::ExprUnary(..) | ast::ExprBox(None, _) | ast::ExprAddrOf(..) | - ast::ExprBinary(..) => { + ast::ExprBinary(..) | + ast::ExprCast(..) => { RvalueDatumExpr } diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index e65fe904dd2..ef82a465ef4 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1804,6 +1804,9 @@ impl LintPass for UnconditionalRecursion { fn check_fn(&mut self, cx: &Context, fn_kind: visit::FnKind, _: &ast::FnDecl, blk: &ast::Block, sp: Span, id: ast::NodeId) { + // FIXME(#23542) Replace with type ascription. + #![allow(trivial_cast)] + type F = for<'tcx> fn(&ty::ctxt<'tcx>, ast::NodeId, ast::NodeId, ast::Ident, ast::NodeId) -> bool; diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index ef65acf8b13..f2d2db18da4 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -56,7 +56,7 @@ pub use rustc::session as session; pub use rustc::util as util; use session::Session; -use lint::{LintPassObject, LintId}; +use lint::LintId; mod builtin; @@ -67,7 +67,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { macro_rules! add_builtin { ($sess:ident, $($name:ident),*,) => ( {$( - store.register_pass($sess, false, box builtin::$name as LintPassObject); + store.register_pass($sess, false, box builtin::$name); )*} ) } @@ -75,7 +75,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { macro_rules! add_builtin_with_new { ($sess:ident, $($name:ident),*,) => ( {$( - store.register_pass($sess, false, box builtin::$name::new() as LintPassObject); + store.register_pass($sess, false, box builtin::$name::new()); )*} ) } @@ -129,7 +129,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { UNUSED_UNSAFE, PATH_STATEMENTS); // We have one lint pass defined specially - store.register_pass(sess, false, box lint::GatherNodeLevels as LintPassObject); + store.register_pass(sess, false, box lint::GatherNodeLevels); // Insert temporary renamings for a one-time deprecation store.register_renamed("raw_pointer_deriving", "raw_pointer_derive"); diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 506bf4a058f..4d821df72a6 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -14,6 +14,8 @@ #![allow(non_camel_case_types)] #![allow(non_snake_case)] #![allow(dead_code)] +#![allow(trivial_cast)] +#![allow(trivial_numeric_cast)] #![crate_name = "rustc_llvm"] #![unstable(feature = "rustc_private")] diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index b9ec22b86f0..ef43b9c0de4 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -43,6 +43,9 @@ #![feature(convert)] #![feature(path_relative_from)] +#![allow(trivial_cast)] +#![allow(trivial_numeric_cast)] + extern crate arena; extern crate flate; extern crate getopts; diff --git a/src/librustc_trans/trans/datum.rs b/src/librustc_trans/trans/datum.rs index e181df545e6..15738d1e61a 100644 --- a/src/librustc_trans/trans/datum.rs +++ b/src/librustc_trans/trans/datum.rs @@ -471,15 +471,6 @@ impl<'tcx> Datum<'tcx, Expr> { }) } - /// Ensures that `self` will get cleaned up, if it is not an lvalue already. - pub fn clean<'blk>(self, - bcx: Block<'blk, 'tcx>, - name: &'static str, - expr_id: ast::NodeId) - -> Block<'blk, 'tcx> { - self.to_lvalue_datum(bcx, name, expr_id).bcx - } - pub fn to_lvalue_datum<'blk>(self, bcx: Block<'blk, 'tcx>, name: &str, diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index ceb9a29efa8..4d7431a20b7 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -1227,22 +1227,9 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, trans_overloaded_op(bcx, expr, MethodCall::expr(expr.id), base, vec![(idx_datum, idx.id)], Some(dest), true).bcx } - ast::ExprCast(ref val, _) => { - // DPS output mode means this is a trait cast: - if ty::type_is_trait(node_id_type(bcx, expr.id)) { - let trait_ref = - bcx.tcx().object_cast_map.borrow() - .get(&expr.id) - .cloned() - .unwrap(); - let trait_ref = bcx.monomorphize(&trait_ref); - let datum = unpack_datum!(bcx, trans(bcx, &**val)); - meth::trans_trait_cast(bcx, datum, expr.id, - trait_ref, dest) - } else { - bcx.tcx().sess.span_bug(expr.span, - "expr_cast of non-trait"); - } + ast::ExprCast(..) => { + // Trait casts used to come this way, now they should be coercions. + bcx.tcx().sess.span_bug(expr.span, "DPS expr_cast (residual trait cast?)") } ast::ExprAssignOp(op, ref dst, ref src) => { trans_assign_op(bcx, expr, op, &**dst, &**src) @@ -2091,7 +2078,7 @@ fn trans_imm_cast<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let mut bcx = bcx; let ccx = bcx.ccx(); - let t_in = expr_ty(bcx, expr); + let t_in = expr_ty_adjusted(bcx, expr); let t_out = node_id_type(bcx, id); let k_in = cast_type_kind(bcx.tcx(), t_in); let k_out = cast_type_kind(bcx.tcx(), t_out); @@ -2103,7 +2090,8 @@ fn trans_imm_cast<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // by-value as appropriate given its type: let mut datum = unpack_datum!(bcx, trans(bcx, expr)); - if cast_is_noop(datum.ty, t_out) { + let datum_ty = monomorphize_type(bcx, datum.ty); + if cast_is_noop(datum_ty, t_out) { datum.ty = t_out; return DatumBlock::new(bcx, datum); } diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs index 4da17972c55..d13076df637 100644 --- a/src/librustc_trans/trans/meth.rs +++ b/src/librustc_trans/trans/meth.rs @@ -26,7 +26,7 @@ use trans::common::*; use trans::consts; use trans::datum::*; use trans::debuginfo::DebugLoc; -use trans::expr::{SaveIn, Ignore}; +use trans::expr::SaveIn; use trans::expr; use trans::glue; use trans::machine; @@ -861,44 +861,6 @@ fn emit_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, .collect() } -/// Generates the code to convert from a pointer (`Box`, `&T`, etc) into an object -/// (`Box`, `&Trait`, etc). This means creating a pair where the first word is the vtable -/// and the second word is the pointer. -pub fn trans_trait_cast<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, - datum: Datum<'tcx, Expr>, - id: ast::NodeId, - trait_ref: ty::PolyTraitRef<'tcx>, - dest: expr::Dest) - -> Block<'blk, 'tcx> { - let mut bcx = bcx; - let _icx = push_ctxt("meth::trans_trait_cast"); - - let lldest = match dest { - Ignore => { - return datum.clean(bcx, "trait_trait_cast", id); - } - SaveIn(dest) => dest - }; - - debug!("trans_trait_cast: trait_ref={}", - trait_ref.repr(bcx.tcx())); - - let llty = type_of(bcx.ccx(), datum.ty); - - // Store the pointer into the first half of pair. - let llboxdest = GEPi(bcx, lldest, &[0, abi::FAT_PTR_ADDR]); - let llboxdest = PointerCast(bcx, llboxdest, llty.ptr_to()); - bcx = datum.store_to(bcx, llboxdest); - - // Store the vtable into the second half of pair. - let vtable = get_vtable(bcx.ccx(), trait_ref, bcx.fcx.param_substs); - let llvtabledest = GEPi(bcx, lldest, &[0, abi::FAT_PTR_EXTRA]); - let llvtabledest = PointerCast(bcx, llvtabledest, val_ty(vtable).ptr_to()); - Store(bcx, vtable, llvtabledest); - - bcx -} - /// Replace the self type (&Self or Box) with an opaque pointer. pub fn opaque_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>, method_ty: &ty::BareFnTy<'tcx>) -> &'tcx ty::BareFnTy<'tcx> { diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index f731507ba90..920154bc916 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -332,14 +332,14 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // E.g., `[T, ..n]` -> `([T], UnsizeLength(n))` fn unsize_ty(&self, ty_a: Ty<'tcx>, - a: Ty<'tcx>, + a: Ty<'tcx>, // TODO unwrap ty_a here, not in the caller ty_b: Ty<'tcx>) - -> Option<(Ty<'tcx>, ty::UnsizeKind<'tcx>)> { - debug!("unsize_ty(a={:?}, ty_b={})", a, ty_b.repr(self.tcx())); - + -> Option<(Ty<'tcx>, ty::UnsizeKind<'tcx>)> + { let tcx = self.tcx(); - self.unpack_actual_value(ty_b, |b| + self.unpack_actual_value(ty_b, |b| { + debug!("unsize_ty(a={}, b={})", a.repr(self.tcx()), b.repr(self.tcx())); match (&a.sty, &b.sty) { (&ty::ty_vec(t_a, Some(len)), &ty::ty_vec(_, None)) => { let ty = ty::mk_vec(tcx, t_a, None); @@ -438,7 +438,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { } _ => None } - ) + }) } fn coerce_from_fn_pointer(&self, diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 6f2d0cb3667..cd6a1226e00 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -53,9 +53,11 @@ pub fn eqtype<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span, } } -// Checks that the type `actual` can be coerced to `expected`. -pub fn coerce<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span, - expected: Ty<'tcx>, expr: &ast::Expr) { +// Checks that the type of `expr` can be coerced to `expected`. +pub fn coerce<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, + sp: Span, + expected: Ty<'tcx>, + expr: &ast::Expr) { let expr_ty = fcx.expr_ty(expr); debug!("demand::coerce(expected = {}, expr_ty = {})", expected.repr(fcx.ccx.tcx), diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index c3f4937d26b..4eddf8ae97a 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -184,6 +184,8 @@ pub struct Inherited<'a, 'tcx: 'a> { // def-id of the closure, so that once we decide, we can easily go // back and process them. deferred_call_resolutions: RefCell>>>, + + deferred_cast_checks: RefCell>>, } trait DeferredCallResolution<'tcx> { @@ -192,6 +194,15 @@ trait DeferredCallResolution<'tcx> { type DeferredCallResolutionHandler<'tcx> = Box+'tcx>; +/// Reifies a cast check to be checked once we have full type information for +/// a function context. +struct CastCheck<'tcx> { + expr: ast::Expr, + expr_ty: Ty<'tcx>, + cast_ty: Ty<'tcx>, + span: Span, +} + /// When type-checking an expression, we propagate downward /// whatever type hint we are able in the form of an `Expectation`. #[derive(Copy)] @@ -399,6 +410,7 @@ impl<'a, 'tcx> Inherited<'a, 'tcx> { fn_sig_map: RefCell::new(NodeMap()), fulfillment_cx: RefCell::new(traits::FulfillmentContext::new()), deferred_call_resolutions: RefCell::new(DefIdMap()), + deferred_cast_checks: RefCell::new(Vec::new()), } } @@ -508,6 +520,7 @@ fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, vtable::select_all_fcx_obligations_and_apply_defaults(&fcx); upvar::closure_analyze_fn(&fcx, fn_id, decl, body); vtable::select_all_fcx_obligations_or_error(&fcx); + fcx.check_casts(); regionck::regionck_fn(&fcx, fn_id, fn_span, decl, body); writeback::resolve_type_vars_in_fn(&fcx, decl, body); } @@ -1053,11 +1066,7 @@ fn report_cast_to_unsized_type<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, } -fn check_cast_inner<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, - span: Span, - t_1: Ty<'tcx>, - t_e: Ty<'tcx>, - e: &ast::Expr) { +fn check_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, cast: &CastCheck<'tcx>) { fn cast_through_integer_err<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, span: Span, t_1: Ty<'tcx>, @@ -1070,6 +1079,33 @@ fn check_cast_inner<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, }, t_e, None); } + let span = cast.span; + let e = &cast.expr; + let t_e = structurally_resolved_type(fcx, span, cast.expr_ty); + let t_1 = structurally_resolved_type(fcx, span, cast.cast_ty); + + // Check for trivial casts. + if !ty::type_has_ty_infer(t_1) { + if let Ok(()) = coercion::mk_assignty(fcx, e, t_e, t_1) { + if ty::type_is_numeric(t_1) && ty::type_is_numeric(t_e) { + fcx.tcx().sess.add_lint(lint::builtin::TRIVIAL_NUMERIC_CAST, + e.id, + span, + format!("trivial numeric cast: {} as {}", + fcx.infcx().ty_to_string(t_e), + fcx.infcx().ty_to_string(t_1))); + } else { + fcx.tcx().sess.add_lint(lint::builtin::TRIVIAL_CAST, + e.id, + span, + format!("trivial cast: {} as {}", + fcx.infcx().ty_to_string(t_e), + fcx.infcx().ty_to_string(t_1))); + } + return; + } + } + let t_e_is_bare_fn_item = ty::type_is_bare_fn_item(t_e); let t_e_is_scalar = ty::type_is_scalar(t_e); let t_e_is_integral = ty::type_is_integral(t_e); @@ -1085,18 +1121,17 @@ fn check_cast_inner<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, let t_1_is_trivial = t_1_is_scalar && !t_1_is_char && !t_1_is_bare_fn; if t_e_is_bare_fn_item && t_1_is_bare_fn { - demand::coerce(fcx, e.span, t_1, &*e); + demand::coerce(fcx, e.span, t_1, &e); } else if t_1_is_char { let t_e = fcx.infcx().shallow_resolve(t_e); if t_e.sty != ty::ty_uint(ast::TyU8) { fcx.type_error_message(span, |actual| { - format!("only `u8` can be cast as \ - `char`, not `{}`", actual) + format!("only `u8` can be cast as `char`, not `{}`", actual) }, t_e, None); } } else if t_1.sty == ty::ty_bool { span_err!(fcx.tcx().sess, span, E0054, - "cannot cast as `bool`, compare with zero instead"); + "cannot cast as `bool`, compare with zero instead"); } else if t_1_is_float && (t_e_is_scalar || t_e_is_c_enum) && !( t_e_is_integral || t_e_is_float || t_e.sty == ty::ty_bool) { // Casts to float must go through an integer or boolean @@ -1145,7 +1180,7 @@ fn check_cast_inner<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, /* this case is allowed */ } _ => { - demand::coerce(fcx, e.span, t_1, &*e); + demand::coerce(fcx, e.span, t_1, &e); } } } else if !(t_e_is_scalar && t_1_is_trivial) { @@ -1162,49 +1197,6 @@ fn check_cast_inner<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, } } -fn check_cast<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, - cast_expr: &ast::Expr, - e: &'tcx ast::Expr, - t: &ast::Ty) { - let id = cast_expr.id; - let span = cast_expr.span; - - // Find the type of `e`. Supply hints based on the type we are casting to, - // if appropriate. - let t_1 = fcx.to_ty(t); - let t_1 = structurally_resolved_type(fcx, span, t_1); - - check_expr_with_expectation(fcx, e, ExpectCastableToType(t_1)); - - let t_e = fcx.expr_ty(e); - - debug!("t_1={}", fcx.infcx().ty_to_string(t_1)); - debug!("t_e={}", fcx.infcx().ty_to_string(t_e)); - - if ty::type_is_error(t_e) { - fcx.write_error(id); - return - } - - if !fcx.type_is_known_to_be_sized(t_1, cast_expr.span) { - report_cast_to_unsized_type(fcx, span, t.span, e.span, t_1, t_e, id); - return - } - - if ty::type_is_trait(t_1) { - // This will be looked up later on. - vtable::check_object_cast(fcx, cast_expr, e, t_1); - fcx.write_ty(id, t_1); - return - } - - let t_1 = structurally_resolved_type(fcx, span, t_1); - let t_e = structurally_resolved_type(fcx, span, t_e); - - check_cast_inner(fcx, span, t_1, t_e, e); - fcx.write_ty(id, t_1); -} - impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { fn tcx(&self) -> &ty::ctxt<'tcx> { self.ccx.tcx } @@ -1372,7 +1364,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } pub fn tag(&self) -> String { - format!("{:?}", self as *const FnCtxt) + let self_ptr: *const FnCtxt = self; + format!("{:?}", self_ptr) } pub fn local_ty(&self, span: Span, nid: ast::NodeId) -> Ty<'tcx> { @@ -1416,14 +1409,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.inh.node_types.borrow_mut().insert(node_id, ty); } - pub fn write_object_cast(&self, - key: ast::NodeId, - trait_ref: ty::PolyTraitRef<'tcx>) { - debug!("write_object_cast key={} trait_ref={}", - key, trait_ref.repr(self.tcx())); - self.inh.object_cast_map.borrow_mut().insert(key, trait_ref); - } - pub fn write_substs(&self, node_id: ast::NodeId, substs: ty::ItemSubsts<'tcx>) { if !substs.substs.is_noop() { debug!("write_substs({}, {}) in fcx {}", @@ -1923,6 +1908,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { o_field.map(|f| ty::lookup_field_type(self.tcx(), class_id, f.id, substs)) .map(|t| self.normalize_associated_types_in(span, &t)) } + + fn check_casts(&self) { + let mut deferred_cast_checks = self.inh.deferred_cast_checks.borrow_mut(); + for check in deferred_cast_checks.iter() { + check_cast(self, check); + } + + deferred_cast_checks.clear(); + } } impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> { @@ -3828,7 +3822,33 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>, if let ast::TyFixedLengthVec(_, ref count_expr) = t.node { check_expr_with_hint(fcx, &**count_expr, tcx.types.uint); } - check_cast(fcx, expr, &**e, &**t); + + // Find the type of `e`. Supply hints based on the type we are casting to, + // if appropriate. + let t_1 = fcx.to_ty(t); + let t_1 = structurally_resolved_type(fcx, expr.span, t_1); + check_expr_with_expectation(fcx, e, ExpectCastableToType(t_1)); + let t_e = fcx.expr_ty(e); + + // Eagerly check for some obvious errors. + if ty::type_is_error(t_e) { + fcx.write_error(id); + } else if !fcx.type_is_known_to_be_sized(t_1, expr.span) { + report_cast_to_unsized_type(fcx, expr.span, t.span, e.span, t_1, t_e, id); + } else { + // Write a type for the whole expression, assuming everything is going + // to work out Ok. + fcx.write_ty(id, t_1); + + // Defer other checks until we're done type checking. + let mut deferred_cast_checks = fcx.inh.deferred_cast_checks.borrow_mut(); + deferred_cast_checks.push(CastCheck { + expr: (**e).clone(), + expr_ty: t_e, + cast_ty: t_1, + span: expr.span, + }); + } } ast::ExprVec(ref args) => { let uty = expected.to_option(fcx).and_then(|uty| { @@ -4461,6 +4481,7 @@ fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, check_expr_with_hint(fcx, e, declty); demand::coerce(fcx, e.span, declty, e); vtable::select_all_fcx_obligations_or_error(fcx); + fcx.check_casts(); regionck::regionck_expr(fcx, e); writeback::resolve_type_vars_in_expr(fcx, e); } @@ -4560,6 +4581,8 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, ty: attr::IntType, disr: ty::Disr) -> bool { fn uint_in_range(ccx: &CrateCtxt, ty: ast::UintTy, disr: ty::Disr) -> bool { + #![allow(trivial_numeric_cast)] + match ty { ast::TyU8 => disr as u8 as Disr == disr, ast::TyU16 => disr as u16 as Disr == disr, @@ -4588,6 +4611,7 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, id: ast::NodeId, hint: attr::ReprAttr) -> Vec>> { + #![allow(trivial_numeric_cast)] use std::num::Int; let rty = ty::node_id_to_type(ccx.tcx, id); diff --git a/src/librustc_typeck/check/vtable.rs b/src/librustc_typeck/check/vtable.rs index 963be9aa2e2..2858dc9b569 100644 --- a/src/librustc_typeck/check/vtable.rs +++ b/src/librustc_typeck/check/vtable.rs @@ -9,7 +9,6 @@ // except according to those terms. use check::{FnCtxt}; -use check::demand; use middle::traits::{self, ObjectSafetyViolation, MethodViolationCode}; use middle::traits::{Obligation, ObligationCause}; use middle::traits::report_fulfillment_errors; @@ -19,83 +18,6 @@ use syntax::codemap::Span; use util::nodemap::FnvHashSet; use util::ppaux::{Repr, UserString}; -pub fn check_object_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, - cast_expr: &ast::Expr, - source_expr: &ast::Expr, - target_object_ty: Ty<'tcx>) -{ - let tcx = fcx.tcx(); - debug!("check_object_cast(cast_expr={}, target_object_ty={})", - cast_expr.repr(tcx), - target_object_ty.repr(tcx)); - - // Look up vtables for the type we're casting to, - // passing in the source and target type. The source - // must be a pointer type suitable to the object sigil, - // e.g.: `&x as &Trait` or `box x as Box` - - // First, construct a fresh type that we can feed into `` - // within ` as ` to inform type inference (e.g. to - // tell it that we are expecting a `Box<_>` or an `&_`). - let fresh_ty = fcx.infcx().next_ty_var(); - let (object_trait_ty, source_expected_ty) = match target_object_ty.sty { - ty::ty_uniq(object_trait_ty) => { - (object_trait_ty, ty::mk_uniq(fcx.tcx(), fresh_ty)) - } - ty::ty_rptr(target_region, ty::mt { ty: object_trait_ty, - mutbl: target_mutbl }) => { - (object_trait_ty, - ty::mk_rptr(fcx.tcx(), - target_region, ty::mt { ty: fresh_ty, - mutbl: target_mutbl })) - } - _ => { - fcx.tcx().sess.span_bug(source_expr.span, "expected object type"); - } - }; - - let source_ty = fcx.expr_ty(source_expr); - debug!("check_object_cast pre unify source_ty={}", source_ty.repr(tcx)); - - // This ensures that the source_ty <: source_expected_ty, which - // will ensure e.g. that &'a T <: &'b T when doing `&'a T as &'b Trait` - // - // FIXME (pnkfelix): do we need to use suptype_with_fn in order to - // override the error message emitted when the types do not work - // out in the manner desired? - demand::suptype(fcx, source_expr.span, source_expected_ty, source_ty); - - debug!("check_object_cast postunify source_ty={}", source_ty.repr(tcx)); - - let object_trait = object_trait(&object_trait_ty); - - // Ensure that if Ptr is cast to Ptr, then T : Trait. - push_cast_obligation(fcx, cast_expr, object_trait, fresh_ty); - check_object_safety(tcx, object_trait, source_expr.span); - - fn object_trait<'a, 'tcx>(t: &'a Ty<'tcx>) -> &'a ty::TyTrait<'tcx> { - match t.sty { - ty::ty_trait(ref ty_trait) => &**ty_trait, - _ => panic!("expected ty_trait") - } - } - - fn push_cast_obligation<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, - cast_expr: &ast::Expr, - object_trait: &ty::TyTrait<'tcx>, - referent_ty: Ty<'tcx>) { - let object_trait_ref = - register_object_cast_obligations(fcx, - cast_expr.span, - object_trait, - referent_ty); - - // Finally record the object_trait_ref for use during trans - // (it would prob be better not to do this, but it's just kind - // of a pain to have to reconstruct it). - fcx.write_object_cast(cast_expr.id, object_trait_ref); - } -} // Check that a trait is 'object-safe'. This should be checked whenever a trait object // is created (by casting or coercion, etc.). A trait is object-safe if all its diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index cdd8457687a..cfa84de5ca7 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -308,8 +308,8 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result { }; (*((*renderer).opaque as *mut hoedown_html_renderer_state)).opaque = &mut opaque as *mut _ as *mut libc::c_void; - (*renderer).blockcode = Some(block as blockcodefn); - (*renderer).header = Some(header as headerfn); + (*renderer).blockcode = Some(block); + (*renderer).header = Some(header); let document = hoedown_document_new(renderer, HOEDOWN_EXTENSIONS, 16); hoedown_document_render(document, ob, s.as_ptr(), @@ -380,8 +380,8 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) { unsafe { let ob = hoedown_buffer_new(DEF_OUNIT); let renderer = hoedown_html_renderer_new(0, 0); - (*renderer).blockcode = Some(block as blockcodefn); - (*renderer).header = Some(header as headerfn); + (*renderer).blockcode = Some(block); + (*renderer).header = Some(header); (*((*renderer).opaque as *mut hoedown_html_renderer_state)).opaque = tests as *mut _ as *mut libc::c_void; @@ -501,10 +501,10 @@ pub fn plain_summary_line(md: &str) -> String { unsafe { let ob = hoedown_buffer_new(DEF_OUNIT); let mut plain_renderer: hoedown_renderer = ::std::mem::zeroed(); - let renderer = &mut plain_renderer as *mut hoedown_renderer; + let renderer: *mut hoedown_renderer = &mut plain_renderer; (*renderer).opaque = ob as *mut libc::c_void; - (*renderer).link = Some(link as linkfn); - (*renderer).normal_text = Some(normal_text as normaltextfn); + (*renderer).link = Some(link); + (*renderer).normal_text = Some(normal_text); let document = hoedown_document_new(renderer, HOEDOWN_EXTENSIONS, 16); hoedown_document_render(document, ob, md.as_ptr(), diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index abbfc82319f..17c41448540 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -2429,7 +2429,10 @@ pub trait ToJson { macro_rules! to_json_impl_i64 { ($($t:ty), +) => ( $(impl ToJson for $t { - fn to_json(&self) -> Json { Json::I64(*self as i64) } + fn to_json(&self) -> Json { + #![allow(trivial_numeric_cast)] + Json::I64(*self as i64) + } })+ ) } @@ -2439,7 +2442,10 @@ to_json_impl_i64! { int, i8, i16, i32, i64 } macro_rules! to_json_impl_u64 { ($($t:ty), +) => ( $(impl ToJson for $t { - fn to_json(&self) -> Json { Json::U64(*self as u64) } + fn to_json(&self) -> Json { + #![allow(trivial_numeric_cast)] + Json::U64(*self as u64) + } })+ ) } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 90eca6168f2..228b885b653 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -135,6 +135,8 @@ #![feature(no_std)] #![no_std] +#![allow(trivial_cast)] +#![allow(trivial_numeric_cast)] #![deny(missing_docs)] #[cfg(test)] extern crate test; diff --git a/src/libstd/old_io/stdio.rs b/src/libstd/old_io/stdio.rs index ef811f832b3..b77c8d50997 100644 --- a/src/libstd/old_io/stdio.rs +++ b/src/libstd/old_io/stdio.rs @@ -337,10 +337,10 @@ pub fn set_stderr(_stderr: Box) -> Option> { // }) // }) fn with_task_stdout(f: F) where F: FnOnce(&mut Writer) -> IoResult<()> { - let mut my_stdout = LOCAL_STDOUT.with(|slot| { + let mut my_stdout: Box = LOCAL_STDOUT.with(|slot| { slot.borrow_mut().take() }).unwrap_or_else(|| { - box stdout() as Box + box stdout() }); let result = f(&mut *my_stdout); let mut var = Some(my_stdout); diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index e52e68dad23..86b1d031f68 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -73,7 +73,7 @@ fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int { use thread::Thread; let something_around_the_top_of_the_stack = 1; - let addr = &something_around_the_top_of_the_stack as *const int; + let addr = &something_around_the_top_of_the_stack as *const _ as *const int; let my_stack_top = addr as uint; // FIXME #11359 we just assume that this thread has a stack of a diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 1abe8d0a3c1..6a00fff1860 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -284,7 +284,7 @@ pub const COMMAND_LINE_EXPN: ExpnId = ExpnId(-2); impl ExpnId { pub fn from_llvm_cookie(cookie: c_uint) -> ExpnId { - ExpnId(cookie as u32) + ExpnId(cookie) } pub fn to_llvm_cookie(self) -> i32 { @@ -376,7 +376,7 @@ impl Encodable for FileMap { match bytes_per_diff { 1 => for diff in diff_iter { try! { (diff.0 as u8).encode(s) } }, 2 => for diff in diff_iter { try! { (diff.0 as u16).encode(s) } }, - 4 => for diff in diff_iter { try! { (diff.0 as u32).encode(s) } }, + 4 => for diff in diff_iter { try! { diff.0.encode(s) } }, _ => unreachable!() } } @@ -650,7 +650,7 @@ impl CodeMap { let lo = self.lookup_char_pos(sp.lo); let hi = self.lookup_char_pos(sp.hi); let mut lines = Vec::new(); - for i in lo.line - 1..hi.line as usize { + for i in lo.line - 1..hi.line { lines.push(i); }; FileLines {file: lo.file, lines: lines} diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 35449bde0b2..b679456b353 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -264,7 +264,7 @@ macro_rules! make_MacEager { box MacEager { $fld: Some(v), ..Default::default() - } as Box + } } )* } @@ -330,7 +330,7 @@ impl DummyResult { /// Use this as a return value after hitting any errors and /// calling `span_err`. pub fn any(sp: Span) -> Box { - box DummyResult { expr_only: false, span: sp } as Box + box DummyResult { expr_only: false, span: sp } } /// Create a default MacResult that can only be an expression. @@ -339,7 +339,7 @@ impl DummyResult { /// if an error is encountered internally, the user will receive /// an error that they also used it in the wrong place. pub fn expr(sp: Span) -> Box { - box DummyResult { expr_only: true, span: sp } as Box + box DummyResult { expr_only: true, span: sp } } /// A plain dummy expression. diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index c11ffe66e6c..1aceec310e1 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -262,6 +262,7 @@ pub mod rt { (unsigned, $t:ty, $tag:expr) => ( impl ToSource for $t { fn to_source(&self) -> String { + #![allow(trivial_numeric_cast)] let lit = ast::LitInt(*self as u64, ast::UnsignedIntLit($tag)); pprust::lit_to_string(&dummy_spanned(lit)) } diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 5940b791843..1e53db60301 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -169,7 +169,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt, // Weird, but useful for X-macros. return box ParserAnyMacro { parser: RefCell::new(p), - } as Box + } } Failure(sp, ref msg) => if sp.lo >= best_fail_spot.lo { best_fail_spot = sp; diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index e0953a8ace6..0843713681b 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -758,7 +758,7 @@ impl<'a> StringReader<'a> { self.err_span_char(self.last_pos, self.pos, "illegal character in numeric character escape", c); 0 - }) as u32; + }); self.bump(); } @@ -887,7 +887,7 @@ impl<'a> StringReader<'a> { self.fatal_span_char(self.last_pos, self.pos, "illegal character in unicode escape", c); } - }) as u32; + }); self.bump(); count += 1; } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 4ae5e0faa31..44097ffeb20 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -865,7 +865,7 @@ impl<'a> Parser<'a> { } else { // Avoid token copies with `replace`. let buffer_start = self.buffer_start as usize; - let next_index = (buffer_start + 1) & 3 as usize; + let next_index = (buffer_start + 1) & 3; self.buffer_start = next_index as isize; let placeholder = TokenAndSpan { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 828d085fd43..5941f044a07 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -2831,7 +2831,7 @@ impl<'a> State<'a> { ast::LitBinary(ref v) => { let mut escaped: String = String::new(); for &ch in &**v { - escaped.extend(ascii::escape_default(ch as u8) + escaped.extend(ascii::escape_default(ch) .map(|c| c as char)); } word(&mut self.s, &format!("b\"{}\"", escaped)) diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs index c907b87bc3c..41e066cc94a 100644 --- a/src/libterm/lib.rs +++ b/src/libterm/lib.rs @@ -103,7 +103,7 @@ impl Write for WriterWrapper { /// opened. pub fn stdout() -> Option + Send>> { TerminfoTerminal::new(WriterWrapper { - wrapped: box std::io::stdout() as Box, + wrapped: box std::io::stdout(), }) } @@ -112,14 +112,14 @@ pub fn stdout() -> Option + Send>> { /// opened. pub fn stdout() -> Option + Send>> { let ti = TerminfoTerminal::new(WriterWrapper { - wrapped: box std::io::stdout() as Box, + wrapped: box std::io::stdout(), }); match ti { Some(t) => Some(t), None => { WinConsole::new(WriterWrapper { - wrapped: box std::io::stdout() as Box, + wrapped: box std::io::stdout(), }) } } @@ -130,7 +130,7 @@ pub fn stdout() -> Option + Send>> { /// opened. pub fn stderr() -> Option + Send>> { TerminfoTerminal::new(WriterWrapper { - wrapped: box std::io::stderr() as Box, + wrapped: box std::io::stderr(), }) } @@ -139,14 +139,14 @@ pub fn stderr() -> Option + Send>> { /// opened. pub fn stderr() -> Option + Send>> { let ti = TerminfoTerminal::new(WriterWrapper { - wrapped: box std::io::stderr() as Box, + wrapped: box std::io::stderr(), }); match ti { Some(t) => Some(t), None => { WinConsole::new(WriterWrapper { - wrapped: box std::io::stderr() as Box, + wrapped: box std::io::stderr(), }) } } diff --git a/src/libterm/terminfo/mod.rs b/src/libterm/terminfo/mod.rs index 309320b52ff..1d6657d5932 100644 --- a/src/libterm/terminfo/mod.rs +++ b/src/libterm/terminfo/mod.rs @@ -190,7 +190,7 @@ impl TerminfoTerminal { out: out, ti: msys_terminfo(), num_colors: 8, - } as Box+Send>) + }) }, _ => { debug!("error finding terminfo entry: {:?}", err); @@ -213,7 +213,7 @@ impl TerminfoTerminal { return Some(box TerminfoTerminal {out: out, ti: inf, - num_colors: nc} as Box+Send>); + num_colors: nc}); } fn dim_if_necessary(&self, color: color::Color) -> color::Color { diff --git a/src/libterm/terminfo/parser/compiled.rs b/src/libterm/terminfo/parser/compiled.rs index cc9a2880b5d..8d0a9e6e971 100644 --- a/src/libterm/terminfo/parser/compiled.rs +++ b/src/libterm/terminfo/parser/compiled.rs @@ -186,7 +186,7 @@ pub fn parse(file: &mut Read, longnames: bool) let magic = try!(read_le_u16(file)); if magic != 0x011A { return Err(format!("invalid magic number: expected {:x}, found {:x}", - 0x011A as usize, magic as usize)); + 0x011A_usize, magic as usize)); } let names_bytes = try!(read_le_u16(file)) as int; diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 402774321bf..c48c7e413d0 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -1021,7 +1021,7 @@ impl MetricMap { let MetricMap(ref mm) = *self; let v : Vec = mm.iter() .map(|(k,v)| format!("{}: {} (+/- {})", *k, - v.value as f64, v.noise as f64)) + v.value, v.noise)) .collect(); v.connect(", ") } diff --git a/src/rustbook/subcommand.rs b/src/rustbook/subcommand.rs index 473739c919d..44af43be787 100644 --- a/src/rustbook/subcommand.rs +++ b/src/rustbook/subcommand.rs @@ -32,11 +32,11 @@ pub trait Subcommand { /// Create a Subcommand object based on its name. pub fn parse_name(name: &str) -> Option> { - for parser in [ - help::parse_cmd as fn(&str) -> Option>, - build::parse_cmd as fn(&str) -> Option>, - serve::parse_cmd as fn(&str) -> Option>, - test::parse_cmd as fn(&str) -> Option>].iter() { + let cmds: [fn(&str) -> Option>; 4] = [help::parse_cmd, + build::parse_cmd, + serve::parse_cmd, + test::parse_cmd]; + for parser in cmds.iter() { let parsed = (*parser)(name); if parsed.is_some() { return parsed } } diff --git a/src/test/auxiliary/issue-11224.rs b/src/test/auxiliary/issue-11224.rs index 560844332a1..d66cfe9bf63 100644 --- a/src/test/auxiliary/issue-11224.rs +++ b/src/test/auxiliary/issue-11224.rs @@ -21,6 +21,6 @@ mod inner { } pub fn foo() { - let a = &1 as &inner::Trait; + let a = &1i as &inner::Trait; a.f(); } diff --git a/src/test/compile-fail/issue-14845.rs b/src/test/compile-fail/issue-14845.rs index d7bb806999c..3f994102a17 100644 --- a/src/test/compile-fail/issue-14845.rs +++ b/src/test/compile-fail/issue-14845.rs @@ -22,11 +22,11 @@ fn main() { //~| expected u8 //~| found array of 1 elements - let local = [0]; + let local: [u8; 1] = [0]; let _v = &local as *mut u8; //~^ ERROR mismatched types //~| expected `*mut u8` - //~| found `&[_; 1]` + //~| found `&[u8; 1]` //~| expected u8, //~| found array of 1 elements } diff --git a/src/test/compile-fail/issue-16538.rs b/src/test/compile-fail/issue-16538.rs index 6d2cfcab04e..a4e0f69b63b 100644 --- a/src/test/compile-fail/issue-16538.rs +++ b/src/test/compile-fail/issue-16538.rs @@ -19,8 +19,7 @@ mod Y { } static foo: *const Y::X = Y::foo(Y::x as *const Y::X); -//~^ ERROR cannot refer to other statics by value -//~| ERROR the trait `core::marker::Sync` is not implemented for the type +//~^ ERROR the trait `core::marker::Sync` is not implemented for the type //~| ERROR function calls in statics are limited to struct and enum constructors fn main() {} diff --git a/src/test/compile-fail/issue-5543.rs b/src/test/compile-fail/issue-5543.rs deleted file mode 100644 index c27362eea3e..00000000000 --- a/src/test/compile-fail/issue-5543.rs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2014 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -trait Foo { fn foo(&self) {} } -impl Foo for u8 {} - -fn main() { - // FIXME (#22405): Replace `Box::new` with `box` here when/if possible. - let r: Box = Box::new(5); - let _m: Box = r as Box; - //~^ ERROR `core::marker::Sized` is not implemented for the type `Foo` -} diff --git a/src/test/compile-fail/kindck-impl-type-params.rs b/src/test/compile-fail/kindck-impl-type-params.rs index dffc8fa2abd..71494fd5f38 100644 --- a/src/test/compile-fail/kindck-impl-type-params.rs +++ b/src/test/compile-fail/kindck-impl-type-params.rs @@ -28,6 +28,7 @@ fn f(val: T) { let a = &t as &Gettable; //~^ ERROR the trait `core::marker::Send` is not implemented //~^^ ERROR the trait `core::marker::Copy` is not implemented + //~^^^ ERROR the parameter type `T` may not live long enough } fn g(val: T) { diff --git a/src/test/compile-fail/lint-dead-code-3.rs b/src/test/compile-fail/lint-dead-code-3.rs index 13ee3f16361..ba1b7f03b0f 100644 --- a/src/test/compile-fail/lint-dead-code-3.rs +++ b/src/test/compile-fail/lint-dead-code-3.rs @@ -86,6 +86,6 @@ mod inner { } pub fn foo() { - let a = &1 as &inner::Trait; + let a: &inner::Trait = &1_isize; a.f(); } diff --git a/src/test/compile-fail/lint-unnecessary-casts.rs b/src/test/compile-fail/lint-unnecessary-casts.rs deleted file mode 100644 index b3cf8257b8f..00000000000 --- a/src/test/compile-fail/lint-unnecessary-casts.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2013 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![forbid(unused_typecasts)] - -fn foo_i32(_: i32) {} - -fn foo_u64(a: u64) { - let b: i32 = a as i32; - foo_i32(b as i32); //~ ERROR: unnecessary type cast -} - -fn main() { - let x: u64 = 1; - let y: u64 = x as u64; //~ ERROR: unnecessary type cast - foo_u64(y as u64); //~ ERROR: unnecessary type cast -} diff --git a/src/test/compile-fail/liveness-unused.rs b/src/test/compile-fail/liveness-unused.rs index ac4b8a5f309..addeba03ab8 100644 --- a/src/test/compile-fail/liveness-unused.rs +++ b/src/test/compile-fail/liveness-unused.rs @@ -10,7 +10,7 @@ #![deny(unused_variables)] #![deny(unused_assignments)] -#![allow(dead_code, non_camel_case_types)] +#![allow(dead_code, non_camel_case_types, trivial_numeric_cast)] fn f1(x: isize) { //~^ ERROR unused variable: `x` diff --git a/src/test/compile-fail/object-safety-by-value-self.rs b/src/test/compile-fail/object-safety-by-value-self.rs index 976717249e8..3b0e5786f3d 100644 --- a/src/test/compile-fail/object-safety-by-value-self.rs +++ b/src/test/compile-fail/object-safety-by-value-self.rs @@ -12,6 +12,7 @@ #![feature(rustc_attrs)] #![allow(dead_code)] +#![allow(trivial_cast)] trait Bar { fn bar(self); diff --git a/src/test/compile-fail/regions-close-object-into-object-5.rs b/src/test/compile-fail/regions-close-object-into-object-5.rs index f3b5ccabe79..253132e5f07 100644 --- a/src/test/compile-fail/regions-close-object-into-object-5.rs +++ b/src/test/compile-fail/regions-close-object-into-object-5.rs @@ -24,6 +24,7 @@ impl<'a, T> X for B<'a, T> {} fn f<'a, T, U>(v: Box+'static>) -> Box { box B(&*v) as Box //~ ERROR the parameter type `T` may not live long enough + //~^ ERROR the parameter type `T` may not live long enough } fn main() {} diff --git a/src/test/compile-fail/regions-close-over-type-parameter-1.rs b/src/test/compile-fail/regions-close-over-type-parameter-1.rs index fc18095fc83..924044647d8 100644 --- a/src/test/compile-fail/regions-close-over-type-parameter-1.rs +++ b/src/test/compile-fail/regions-close-over-type-parameter-1.rs @@ -19,6 +19,7 @@ trait SomeTrait { fn get(&self) -> isize; } fn make_object1(v: A) -> Box { box v as Box //~^ ERROR the parameter type `A` may not live long enough + //~^^ ERROR the parameter type `A` may not live long enough } fn make_object2<'a,A:SomeTrait+'a>(v: A) -> Box { @@ -28,6 +29,7 @@ fn make_object2<'a,A:SomeTrait+'a>(v: A) -> Box { fn make_object3<'a,'b,A:SomeTrait+'a>(v: A) -> Box { box v as Box //~^ ERROR the parameter type `A` may not live long enough + //~^^ ERROR the parameter type `A` may not live long enough } fn main() { } diff --git a/src/test/compile-fail/type-parameter-defaults-referencing-Self-ppaux.rs b/src/test/compile-fail/type-parameter-defaults-referencing-Self-ppaux.rs index 8ff514e04e3..8cc531625d1 100644 --- a/src/test/compile-fail/type-parameter-defaults-referencing-Self-ppaux.rs +++ b/src/test/compile-fail/type-parameter-defaults-referencing-Self-ppaux.rs @@ -20,7 +20,7 @@ impl MyAdd for i32 { } fn main() { - let x = 5; + let x: i32 = 5; let y = x as MyAdd; //~^ ERROR as `MyAdd` } diff --git a/src/test/compile-fail/vector-cast-weirdness.rs b/src/test/compile-fail/vector-cast-weirdness.rs index 97e67cd2eae..cac52306d6a 100644 --- a/src/test/compile-fail/vector-cast-weirdness.rs +++ b/src/test/compile-fail/vector-cast-weirdness.rs @@ -10,6 +10,8 @@ // Issue #14893. Tests that casts from vectors don't behave strangely in the // presence of the `_` type shorthand notation. +// Update: after a change to the way casts are done, we have more type information +// around and so the errors here are no longer exactly the same. struct X { y: [u8; 2], @@ -18,12 +20,14 @@ struct X { fn main() { let x1 = X { y: [0, 0] }; - let p1: *const u8 = &x1.y as *const _; //~ ERROR mismatched types + // No longer a type mismatch - the `_` can be fully resolved by type inference. + let p1: *const u8 = &x1.y as *const _; let t1: *const [u8; 2] = &x1.y as *const _; let h1: *const [u8; 2] = &x1.y as *const [u8; 2]; let mut x1 = X { y: [0, 0] }; + // This is still an error since we don't allow casts from &mut [T; n] to *mut T. let p1: *mut u8 = &mut x1.y as *mut _; //~ ERROR mismatched types let t1: *mut [u8; 2] = &mut x1.y as *mut _; let h1: *mut [u8; 2] = &mut x1.y as *mut [u8; 2]; diff --git a/src/test/debuginfo/type-names.rs b/src/test/debuginfo/type-names.rs index bf26fc23d3c..d4cbd255e34 100644 --- a/src/test/debuginfo/type-names.rs +++ b/src/test/debuginfo/type-names.rs @@ -291,15 +291,15 @@ fn main() { let slice2 = &*vec2; // Trait Objects - let box_trait = (box 0) as Box; - let ref_trait = &0 as &Trait1; - let mut mut_int1 = 0; + let box_trait = (box 0_isize) as Box; + let ref_trait = &0_isize as &Trait1; + let mut mut_int1 = 0_isize; let mut_ref_trait = (&mut mut_int1) as &mut Trait1; - let generic_box_trait = (box 0) as Box>; - let generic_ref_trait = (&0) as &Trait2; + let generic_box_trait = (box 0_isize) as Box>; + let generic_ref_trait = (&0_isize) as &Trait2; - let mut generic_mut_ref_trait_impl = 0; + let mut generic_mut_ref_trait_impl = 0_isize; let generic_mut_ref_trait = (&mut generic_mut_ref_trait_impl) as &mut Trait2>; diff --git a/src/test/pretty/path-type-bounds.rs b/src/test/pretty/path-type-bounds.rs index 0a20300e4f4..42b2fe806e9 100644 --- a/src/test/pretty/path-type-bounds.rs +++ b/src/test/pretty/path-type-bounds.rs @@ -21,5 +21,5 @@ fn foo<'a>(x: Box) -> Box { x } fn main() { let x: Box; - Box::new(1) as Box; + Box::new(1isize) as Box; } diff --git a/src/test/run-make/symbols-are-reasonable/lib.rs b/src/test/run-make/symbols-are-reasonable/lib.rs index f81d4803f8f..474a6782b61 100644 --- a/src/test/run-make/symbols-are-reasonable/lib.rs +++ b/src/test/run-make/symbols-are-reasonable/lib.rs @@ -16,5 +16,5 @@ impl Foo for uint {} pub fn dummy() { // force the vtable to be created - let _x = &1 as &Foo; + let _x = &1u as &Foo; } diff --git a/src/test/run-pass/autoderef-method-on-trait.rs b/src/test/run-pass/autoderef-method-on-trait.rs index 6a038927f4a..0bec3af4273 100644 --- a/src/test/run-pass/autoderef-method-on-trait.rs +++ b/src/test/run-pass/autoderef-method-on-trait.rs @@ -22,6 +22,6 @@ impl double for uint { } pub fn main() { - let x: Box<_> = box() (box 3 as Box); + let x: Box<_> = box() (box 3u as Box); assert_eq!(x.double(), 6); } diff --git a/src/test/run-pass/cast-region-to-uint.rs b/src/test/run-pass/cast-region-to-uint.rs index a298a08a1b7..deb0c0d0dc0 100644 --- a/src/test/run-pass/cast-region-to-uint.rs +++ b/src/test/run-pass/cast-region-to-uint.rs @@ -9,6 +9,6 @@ // except according to those terms. pub fn main() { - let x = 3; + let x: int = 3; println!("&x={:x}", (&x as *const int as uint)); } diff --git a/src/test/run-pass/infer-container-across-object-cast.rs b/src/test/run-pass/infer-container-across-object-cast.rs deleted file mode 100644 index 7347ded99e7..00000000000 --- a/src/test/run-pass/infer-container-across-object-cast.rs +++ /dev/null @@ -1,61 +0,0 @@ -// 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Given ` as Box`, we should be able to infer that a -// `Box<_>` is the expected type. - -// pretty-expanded FIXME #23616 - -trait Foo { fn foo(&self) -> u32; } -impl Foo for u32 { fn foo(&self) -> u32 { *self } } - -// (another impl to ensure trait-matching cannot just choose from a singleton set) -impl Foo for () { fn foo(&self) -> u32 { -176 } } - -trait Boxed { fn make() -> Self; } -impl Boxed for Box { fn make() -> Self { Box::new(7) } } - -// (another impl to ensure trait-matching cannot just choose from a singleton set) -impl Boxed for () { fn make() -> Self { () } } - -fn boxed_foo() { - let b7 = Boxed::make() as Box; - assert_eq!(b7.foo(), 7); -} - -trait Refed<'a,T> { fn make(&'a T) -> Self; } -impl<'a> Refed<'a, u32> for &'a u32 { fn make(x: &'a u32) -> Self { x } } - -// (another impl to ensure trait-matching cannot just choose from a singleton set) -impl<'a,'b> Refed<'a, ()> for &'b () { fn make(_: &'a ()) -> Self { static U: () = (); &U } } - -fn refed_foo() { - let a = 8; - let b7 = Refed::make(&a) as &Foo; - assert_eq!(b7.foo(), 8); -} - -fn check_subtyping_works() { - fn inner<'short, 'long:'short>(_s: &'short u32, - l: &'long u32) -> &'short (Foo+'short) { - Refed::make(l) as &Foo - } - - let a = 9; - let b = 10; - let r = inner(&b, &a); - assert_eq!(r.foo(), 9); -} - -pub fn main() { - boxed_foo(); - refed_foo(); - check_subtyping_works(); -} diff --git a/src/test/run-pass/issue-15763.rs b/src/test/run-pass/issue-15763.rs index 7bfd8e0ab71..f30991a1963 100644 --- a/src/test/run-pass/issue-15763.rs +++ b/src/test/run-pass/issue-15763.rs @@ -87,12 +87,12 @@ fn main() { assert_eq!(cc().unwrap(), 3); assert_eq!(dd().unwrap(), 3); - let i = box 32 as Box; + let i = box 32i as Box; assert_eq!(i.aaa(), 3); - let i = box 32 as Box; + let i = box 32i as Box; assert_eq!(i.bbb(), 3); - let i = box 32 as Box; + let i = box 32i as Box; assert_eq!(i.ccc().unwrap(), 3); - let i = box 32 as Box; + let i = box 32i as Box; assert_eq!(i.ddd().unwrap(), 3); } diff --git a/src/test/run-pass/issue-5708.rs b/src/test/run-pass/issue-5708.rs index 59bca87bed0..54773d71cbe 100644 --- a/src/test/run-pass/issue-5708.rs +++ b/src/test/run-pass/issue-5708.rs @@ -41,7 +41,7 @@ impl<'a> Outer<'a> { } pub fn main() { - let inner = 5; + let inner: int = 5; let outer = Outer::new(&inner as &Inner); outer.inner.print(); } diff --git a/src/test/run-pass/issue-9719.rs b/src/test/run-pass/issue-9719.rs index 669a5cdfe30..6e88379f9a4 100644 --- a/src/test/run-pass/issue-9719.rs +++ b/src/test/run-pass/issue-9719.rs @@ -21,7 +21,7 @@ mod a { impl X for int {} pub struct Z<'a>(Enum<&'a (X+'a)>); - fn foo() { let x = 42; let z = Z(Enum::A(&x as &X)); let _ = z; } + fn foo() { let x: int = 42; let z = Z(Enum::A(&x as &X)); let _ = z; } } mod b { @@ -34,7 +34,7 @@ mod b { } fn bar() { - let x = 42; + let x: int = 42; let _y = Y { x: Some(&x as &X) }; } } @@ -43,7 +43,7 @@ mod c { pub trait X { fn f(&self); } impl X for int { fn f(&self) {} } pub struct Z<'a>(Option<&'a (X+'a)>); - fn main() { let x = 42; let z = Z(Some(&x as &X)); let _ = z; } + fn main() { let x: int = 42; let z = Z(Some(&x as &X)); let _ = z; } } pub fn main() {} diff --git a/src/test/run-pass/method-two-traits-distinguished-via-where-clause.rs b/src/test/run-pass/method-two-traits-distinguished-via-where-clause.rs index c8da4852ad3..de8d116255b 100644 --- a/src/test/run-pass/method-two-traits-distinguished-via-where-clause.rs +++ b/src/test/run-pass/method-two-traits-distinguished-via-where-clause.rs @@ -33,6 +33,6 @@ impl B for *const [T] { fn main() { let x: [int; 4] = [1,2,3,4]; - let xptr = x.as_slice() as *const _; + let xptr = x.as_slice() as *const [int]; xptr.foo(); } diff --git a/src/test/run-pass/object-one-type-two-traits.rs b/src/test/run-pass/object-one-type-two-traits.rs index f8a3ce7cda0..baf8c6e4c97 100644 --- a/src/test/run-pass/object-one-type-two-traits.rs +++ b/src/test/run-pass/object-one-type-two-traits.rs @@ -35,7 +35,7 @@ fn is(x: &Any) -> bool { } fn main() { - let x = box 22 as Box; + let x = box 22isize as Box; println!("x={}", x.get()); let y = x.wrap(); } diff --git a/src/test/run-pass/objects-coerce-freeze-borrored.rs b/src/test/run-pass/objects-coerce-freeze-borrored.rs index efdd42c382c..368842ed1b0 100644 --- a/src/test/run-pass/objects-coerce-freeze-borrored.rs +++ b/src/test/run-pass/objects-coerce-freeze-borrored.rs @@ -42,7 +42,7 @@ fn do_it_imm(obj: &Foo, v: uint) { } pub fn main() { - let mut x = 22; + let mut x: uint = 22; let obj = &mut x as &mut Foo; do_it_mut(obj); do_it_imm(obj, 23); diff --git a/src/test/run-pass/regions-early-bound-trait-param.rs b/src/test/run-pass/regions-early-bound-trait-param.rs index 63fb18a8ba2..c87c79ca24e 100644 --- a/src/test/run-pass/regions-early-bound-trait-param.rs +++ b/src/test/run-pass/regions-early-bound-trait-param.rs @@ -83,7 +83,10 @@ impl<'s> Trait<'s> for (int,int) { } impl<'t> MakerTrait for Box+'static> { - fn mk() -> Box+'static> { box() (4,5) as Box } + fn mk() -> Box+'static> { + let tup: Box<(int, int)> = box() (4,5); + tup as Box + } } enum List<'l> { diff --git a/src/test/run-pass/stable-addr-of.rs b/src/test/run-pass/stable-addr-of.rs index 152fb5dc961..920cd9e03ab 100644 --- a/src/test/run-pass/stable-addr-of.rs +++ b/src/test/run-pass/stable-addr-of.rs @@ -13,6 +13,6 @@ // pretty-expanded FIXME #23616 pub fn main() { - let foo = 1; + let foo: int = 1; assert_eq!(&foo as *const int, &foo as *const int); } diff --git a/src/test/run-pass/task-spawn-move-and-copy.rs b/src/test/run-pass/task-spawn-move-and-copy.rs index a6c6db1a127..5c0d0fe9a63 100644 --- a/src/test/run-pass/task-spawn-move-and-copy.rs +++ b/src/test/run-pass/task-spawn-move-and-copy.rs @@ -19,7 +19,7 @@ use std::sync::mpsc::channel; pub fn main() { let (tx, rx) = channel::(); - let x: Box<_> = box 1; + let x: Box = box 1; let x_in_parent = &(*x) as *const int as uint; let _t = Thread::spawn(move || { diff --git a/src/test/run-pass/typeck_type_placeholder_1.rs b/src/test/run-pass/typeck_type_placeholder_1.rs index f4c0992ae1a..53e78db68b1 100644 --- a/src/test/run-pass/typeck_type_placeholder_1.rs +++ b/src/test/run-pass/typeck_type_placeholder_1.rs @@ -14,17 +14,17 @@ // pretty-expanded FIXME #23616 struct TestStruct { - x: *const int + x: *const isize } unsafe impl Sync for TestStruct {} -static CONSTEXPR: TestStruct = TestStruct{x: &413 as *const _}; +static CONSTEXPR: TestStruct = TestStruct{ x: &413 }; pub fn main() { let x: Vec<_> = (0..5).collect(); - let expected: &[uint] = &[0,1,2,3,4]; + let expected: &[usize] = &[0,1,2,3,4]; assert_eq!(x, expected); let x = (0..5).collect::>(); @@ -33,8 +33,8 @@ pub fn main() { let y: _ = "hello"; assert_eq!(y.len(), 5); - let ptr = &5; + let ptr: &usize = &5; let ptr2 = ptr as *const _; - assert_eq!(ptr as *const uint as uint, ptr2 as uint); + assert_eq!(ptr as *const usize as usize, ptr2 as usize); } diff --git a/src/test/run-pass/zero_sized_subslice_match.rs b/src/test/run-pass/zero_sized_subslice_match.rs index 4cb7e40a4fb..ba125997470 100644 --- a/src/test/run-pass/zero_sized_subslice_match.rs +++ b/src/test/run-pass/zero_sized_subslice_match.rs @@ -16,6 +16,6 @@ fn main() { // The subslice used to go out of bounds for zero-sized array items, check that this doesn't // happen anymore match x { - [_, y..] => assert_eq!(&x[1] as *const _, &y[0] as *const _) + [_, y..] => assert_eq!(&x[1] as *const (), &y[0] as *const ()) } } -- cgit 1.4.1-3-g733a5 From e7122a5a09d06aedd1d27d14c3ac38c40b0a7425 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Tue, 24 Mar 2015 11:23:34 +1300 Subject: Change lint names to plurals --- src/libcollections/lib.rs | 4 ++-- src/libcore/cell.rs | 2 +- src/libcore/fmt/mod.rs | 6 +++--- src/libcore/fmt/num.rs | 2 +- src/libcore/hash/mod.rs | 2 +- src/libcore/mem.rs | 2 +- src/libcore/num/i16.rs | 2 +- src/libcore/num/i32.rs | 2 +- src/libcore/num/i64.rs | 2 +- src/libcore/num/i8.rs | 2 +- src/libcore/num/int_macros.rs | 2 +- src/libcore/num/isize.rs | 2 +- src/libcore/num/mod.rs | 2 +- src/libcore/num/u16.rs | 2 +- src/libcore/num/u32.rs | 2 +- src/libcore/num/u64.rs | 2 +- src/libcore/num/u8.rs | 2 +- src/libcore/num/uint_macros.rs | 2 +- src/libcore/num/usize.rs | 2 +- src/librand/distributions/range.rs | 2 +- src/librand/isaac.rs | 2 +- src/librustc/lib.rs | 4 ++-- src/librustc/lint/builtin.rs | 8 ++++---- src/librustc_lint/builtin.rs | 2 +- src/librustc_llvm/lib.rs | 4 ++-- src/librustc_trans/lib.rs | 4 ++-- src/librustc_typeck/check/mod.rs | 8 ++++---- src/libserialize/json.rs | 4 ++-- src/libstd/lib.rs | 4 ++-- src/libsyntax/ext/quote.rs | 2 +- src/test/compile-fail/liveness-unused.rs | 2 +- src/test/compile-fail/object-safety-by-value-self.rs | 2 +- src/test/compile-fail/trivial_casts.rs | 4 ++-- src/test/run-pass/trivial_casts.rs | 2 +- 34 files changed, 49 insertions(+), 49 deletions(-) (limited to 'src/libstd') diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 0a61eeb6e1c..6a65c991c95 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -24,8 +24,8 @@ html_playground_url = "http://play.rust-lang.org/")] #![doc(test(no_crate_inject))] -#![allow(trivial_cast)] -#![allow(trivial_numeric_cast)] +#![allow(trivial_casts)] +#![allow(trivial_numeric_casts)] #![feature(alloc)] #![feature(box_syntax)] #![feature(box_patterns)] diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index f5db3e63c7a..9e6dbce0325 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -715,7 +715,7 @@ impl UnsafeCell { #[stable(feature = "rust1", since = "1.0.0")] pub fn get(&self) -> *mut T { // FIXME(#23542) Replace with type ascription. - #![allow(trivial_cast)] + #![allow(trivial_casts)] &self.value as *const T as *mut T } diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index e00cdc9de88..aa0d0a1539a 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -834,7 +834,7 @@ impl Pointer for *const T { impl Pointer for *mut T { fn fmt(&self, f: &mut Formatter) -> Result { // FIXME(#23542) Replace with type ascription. - #![allow(trivial_cast)] + #![allow(trivial_casts)] Pointer::fmt(&(*self as *const T), f) } } @@ -843,7 +843,7 @@ impl Pointer for *mut T { impl<'a, T> Pointer for &'a T { fn fmt(&self, f: &mut Formatter) -> Result { // FIXME(#23542) Replace with type ascription. - #![allow(trivial_cast)] + #![allow(trivial_casts)] Pointer::fmt(&(*self as *const T), f) } } @@ -852,7 +852,7 @@ impl<'a, T> Pointer for &'a T { impl<'a, T> Pointer for &'a mut T { fn fmt(&self, f: &mut Formatter) -> Result { // FIXME(#23542) Replace with type ascription. - #![allow(trivial_cast)] + #![allow(trivial_casts)] Pointer::fmt(&(&**self as *const T), f) } } diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs index d01d240e5b5..56d2eabc095 100644 --- a/src/libcore/fmt/num.rs +++ b/src/libcore/fmt/num.rs @@ -13,7 +13,7 @@ // FIXME: #6220 Implement floating point formatting #![allow(unsigned_negation)] -#![allow(trivial_numeric_cast)] +#![allow(trivial_numeric_casts)] use fmt; use iter::IteratorExt; diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs index ccc1d32eab3..2feb2f8b1e3 100644 --- a/src/libcore/hash/mod.rs +++ b/src/libcore/hash/mod.rs @@ -183,7 +183,7 @@ mod impls { fn hash_slice(data: &[$ty], state: &mut H) { // FIXME(#23542) Replace with type ascription. - #![allow(trivial_cast)] + #![allow(trivial_casts)] let newlen = data.len() * ::$ty::BYTES as usize; let ptr = data.as_ptr() as *const u8; state.write(unsafe { slice::from_raw_parts(ptr, newlen) }) diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 0bc41eb2c6e..1e6fb51a8a5 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -314,7 +314,7 @@ pub fn drop(_x: T) { } #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn transmute_copy(src: &T) -> U { // FIXME(#23542) Replace with type ascription. - #![allow(trivial_cast)] + #![allow(trivial_casts)] ptr::read(src as *const T as *const U) } diff --git a/src/libcore/num/i16.rs b/src/libcore/num/i16.rs index 1557434a28a..efafce3fdef 100644 --- a/src/libcore/num/i16.rs +++ b/src/libcore/num/i16.rs @@ -12,6 +12,6 @@ #![stable(feature = "rust1", since = "1.0.0")] #![doc(primitive = "i16")] -#![allow(trivial_numeric_cast)] +#![allow(trivial_numeric_casts)] int_module! { i16, 16 } diff --git a/src/libcore/num/i32.rs b/src/libcore/num/i32.rs index bdccab4cb9a..72b0236a8d2 100644 --- a/src/libcore/num/i32.rs +++ b/src/libcore/num/i32.rs @@ -12,6 +12,6 @@ #![stable(feature = "rust1", since = "1.0.0")] #![doc(primitive = "i32")] -#![allow(trivial_numeric_cast)] +#![allow(trivial_numeric_casts)] int_module! { i32, 32 } diff --git a/src/libcore/num/i64.rs b/src/libcore/num/i64.rs index d8f5aa6e548..a64a4febd5a 100644 --- a/src/libcore/num/i64.rs +++ b/src/libcore/num/i64.rs @@ -12,6 +12,6 @@ #![stable(feature = "rust1", since = "1.0.0")] #![doc(primitive = "i64")] -#![allow(trivial_numeric_cast)] +#![allow(trivial_numeric_casts)] int_module! { i64, 64 } diff --git a/src/libcore/num/i8.rs b/src/libcore/num/i8.rs index da2410a04cf..459814875ee 100644 --- a/src/libcore/num/i8.rs +++ b/src/libcore/num/i8.rs @@ -12,6 +12,6 @@ #![stable(feature = "rust1", since = "1.0.0")] #![doc(primitive = "i8")] -#![allow(trivial_numeric_cast)] +#![allow(trivial_numeric_casts)] int_module! { i8, 8 } diff --git a/src/libcore/num/int_macros.rs b/src/libcore/num/int_macros.rs index 5f697e02a99..675f568a960 100644 --- a/src/libcore/num/int_macros.rs +++ b/src/libcore/num/int_macros.rs @@ -9,7 +9,7 @@ // except according to those terms. #![doc(hidden)] -#![allow(trivial_numeric_cast)] +#![allow(trivial_numeric_casts)] macro_rules! int_module { ($T:ty, $bits:expr) => ( diff --git a/src/libcore/num/isize.rs b/src/libcore/num/isize.rs index 838caa59e47..9af51a36748 100644 --- a/src/libcore/num/isize.rs +++ b/src/libcore/num/isize.rs @@ -16,7 +16,7 @@ #![stable(feature = "rust1", since = "1.0.0")] #![doc(primitive = "isize")] -#![allow(trivial_numeric_cast)] +#![allow(trivial_numeric_casts)] #[cfg(target_pointer_width = "32")] int_module! { isize, 32 } diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 7686a990acc..0eec875afc3 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -14,7 +14,7 @@ #![stable(feature = "rust1", since = "1.0.0")] #![allow(missing_docs)] -#![allow(trivial_numeric_cast)] +#![allow(trivial_numeric_casts)] use self::wrapping::{OverflowingOps, WrappingOps}; diff --git a/src/libcore/num/u16.rs b/src/libcore/num/u16.rs index 9d91bbc7f90..289c5dbd08e 100644 --- a/src/libcore/num/u16.rs +++ b/src/libcore/num/u16.rs @@ -12,6 +12,6 @@ #![stable(feature = "rust1", since = "1.0.0")] #![doc(primitive = "u16")] -#![allow(trivial_numeric_cast)] +#![allow(trivial_numeric_casts)] uint_module! { u16, i16, 16 } diff --git a/src/libcore/num/u32.rs b/src/libcore/num/u32.rs index 2d5f163e093..6d0b6b0e5ea 100644 --- a/src/libcore/num/u32.rs +++ b/src/libcore/num/u32.rs @@ -12,6 +12,6 @@ #![stable(feature = "rust1", since = "1.0.0")] #![doc(primitive = "u32")] -#![allow(trivial_numeric_cast)] +#![allow(trivial_numeric_casts)] uint_module! { u32, i32, 32 } diff --git a/src/libcore/num/u64.rs b/src/libcore/num/u64.rs index 26813aa281c..bf8747fdb6e 100644 --- a/src/libcore/num/u64.rs +++ b/src/libcore/num/u64.rs @@ -12,6 +12,6 @@ #![stable(feature = "rust1", since = "1.0.0")] #![doc(primitive = "u64")] -#![allow(trivial_numeric_cast)] +#![allow(trivial_numeric_casts)] uint_module! { u64, i64, 64 } diff --git a/src/libcore/num/u8.rs b/src/libcore/num/u8.rs index 7fb28f27d62..05199735d4a 100644 --- a/src/libcore/num/u8.rs +++ b/src/libcore/num/u8.rs @@ -12,6 +12,6 @@ #![stable(feature = "rust1", since = "1.0.0")] #![doc(primitive = "u8")] -#![allow(trivial_numeric_cast)] +#![allow(trivial_numeric_casts)] uint_module! { u8, i8, 8 } diff --git a/src/libcore/num/uint_macros.rs b/src/libcore/num/uint_macros.rs index 9f502e3ea43..c22f31cc57e 100644 --- a/src/libcore/num/uint_macros.rs +++ b/src/libcore/num/uint_macros.rs @@ -9,7 +9,7 @@ // except according to those terms. #![doc(hidden)] -#![allow(trivial_numeric_cast)] +#![allow(trivial_numeric_casts)] macro_rules! uint_module { ($T:ty, $T_SIGNED:ty, $bits:expr) => ( diff --git a/src/libcore/num/usize.rs b/src/libcore/num/usize.rs index be5acaac92a..82dd3312782 100644 --- a/src/libcore/num/usize.rs +++ b/src/libcore/num/usize.rs @@ -16,6 +16,6 @@ #![stable(feature = "rust1", since = "1.0.0")] #![doc(primitive = "usize")] -#![allow(trivial_numeric_cast)] +#![allow(trivial_numeric_casts)] uint_module! { usize, isize, ::isize::BITS } diff --git a/src/librand/distributions/range.rs b/src/librand/distributions/range.rs index 0001cb6e0ca..a682fa85841 100644 --- a/src/librand/distributions/range.rs +++ b/src/librand/distributions/range.rs @@ -10,7 +10,7 @@ //! Generating numbers between two others. -#![allow(trivial_numeric_cast)] +#![allow(trivial_numeric_casts)] // this is surprisingly complicated to be both generic & correct diff --git a/src/librand/isaac.rs b/src/librand/isaac.rs index 673246fe30d..14bebe0cd91 100644 --- a/src/librand/isaac.rs +++ b/src/librand/isaac.rs @@ -447,7 +447,7 @@ impl Rng for Isaac64Rng { #[inline] fn next_u64(&mut self) -> u64 { - #![allow(trivial_numeric_cast)] + #![allow(trivial_numeric_casts)] if self.cnt == 0 { // make some more numbers self.isaac64(); diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index dd5f3cccea5..e8af07e4381 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -47,8 +47,8 @@ #![feature(into_cow)] #![cfg_attr(test, feature(test))] -#![allow(trivial_cast)] -#![allow(trivial_numeric_cast)] +#![allow(trivial_casts)] +#![allow(trivial_numeric_casts)] extern crate arena; extern crate flate; diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 4f56f2441dc..2cc47f258f0 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -101,13 +101,13 @@ declare_lint! { } declare_lint! { - pub TRIVIAL_CAST, + pub TRIVIAL_CASTS, Warn, "detects trivial casts which could be removed" } declare_lint! { - pub TRIVIAL_NUMERIC_CAST, + pub TRIVIAL_NUMERIC_CASTS, Warn, "detects trivial casts of numeric types which could be removed" } @@ -133,8 +133,8 @@ impl LintPass for HardwiredLints { UNKNOWN_CRATE_TYPES, VARIANT_SIZE_DIFFERENCES, FAT_PTR_TRANSMUTES, - TRIVIAL_CAST, - TRIVIAL_NUMERIC_CAST + TRIVIAL_CASTS, + TRIVIAL_NUMERIC_CASTS ) } } diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 395460aca9f..8b57a48f3ce 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1781,7 +1781,7 @@ impl LintPass for UnconditionalRecursion { fn check_fn(&mut self, cx: &Context, fn_kind: visit::FnKind, _: &ast::FnDecl, blk: &ast::Block, sp: Span, id: ast::NodeId) { // FIXME(#23542) Replace with type ascription. - #![allow(trivial_cast)] + #![allow(trivial_casts)] type F = for<'tcx> fn(&ty::ctxt<'tcx>, ast::NodeId, ast::NodeId, ast::Ident, ast::NodeId) -> bool; diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 4d821df72a6..9d564fa56f5 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -14,8 +14,8 @@ #![allow(non_camel_case_types)] #![allow(non_snake_case)] #![allow(dead_code)] -#![allow(trivial_cast)] -#![allow(trivial_numeric_cast)] +#![allow(trivial_casts)] +#![allow(trivial_numeric_casts)] #![crate_name = "rustc_llvm"] #![unstable(feature = "rustc_private")] diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index ef43b9c0de4..99a64156d66 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -43,8 +43,8 @@ #![feature(convert)] #![feature(path_relative_from)] -#![allow(trivial_cast)] -#![allow(trivial_numeric_cast)] +#![allow(trivial_casts)] +#![allow(trivial_numeric_casts)] extern crate arena; extern crate flate; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index c8c7fb046b1..47aafa2251d 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1088,14 +1088,14 @@ fn check_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, cast: &CastCheck<'tcx>) { if !ty::type_has_ty_infer(t_1) { if let Ok(()) = coercion::mk_assignty(fcx, e, t_e, t_1) { if ty::type_is_numeric(t_1) && ty::type_is_numeric(t_e) { - fcx.tcx().sess.add_lint(lint::builtin::TRIVIAL_NUMERIC_CAST, + fcx.tcx().sess.add_lint(lint::builtin::TRIVIAL_NUMERIC_CASTS, e.id, span, format!("trivial numeric cast: `{}` as `{}`", fcx.infcx().ty_to_string(t_e), fcx.infcx().ty_to_string(t_1))); } else { - fcx.tcx().sess.add_lint(lint::builtin::TRIVIAL_CAST, + fcx.tcx().sess.add_lint(lint::builtin::TRIVIAL_CASTS, e.id, span, format!("trivial cast: `{}` as `{}`", @@ -4581,7 +4581,7 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, ty: attr::IntType, disr: ty::Disr) -> bool { fn uint_in_range(ccx: &CrateCtxt, ty: ast::UintTy, disr: ty::Disr) -> bool { - #![allow(trivial_numeric_cast)] + #![allow(trivial_numeric_casts)] match ty { ast::TyU8 => disr as u8 as Disr == disr, @@ -4611,7 +4611,7 @@ pub fn check_enum_variants<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, id: ast::NodeId, hint: attr::ReprAttr) -> Vec>> { - #![allow(trivial_numeric_cast)] + #![allow(trivial_numeric_casts)] use std::num::Int; let rty = ty::node_id_to_type(ccx.tcx, id); diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 17c41448540..0d6ed91d529 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -2430,7 +2430,7 @@ macro_rules! to_json_impl_i64 { ($($t:ty), +) => ( $(impl ToJson for $t { fn to_json(&self) -> Json { - #![allow(trivial_numeric_cast)] + #![allow(trivial_numeric_casts)] Json::I64(*self as i64) } })+ @@ -2443,7 +2443,7 @@ macro_rules! to_json_impl_u64 { ($($t:ty), +) => ( $(impl ToJson for $t { fn to_json(&self) -> Json { - #![allow(trivial_numeric_cast)] + #![allow(trivial_numeric_casts)] Json::U64(*self as u64) } })+ diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 228b885b653..cca6bb747d4 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -135,8 +135,8 @@ #![feature(no_std)] #![no_std] -#![allow(trivial_cast)] -#![allow(trivial_numeric_cast)] +#![allow(trivial_casts)] +#![allow(trivial_numeric_casts)] #![deny(missing_docs)] #[cfg(test)] extern crate test; diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 1aceec310e1..a25a6451918 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -262,7 +262,7 @@ pub mod rt { (unsigned, $t:ty, $tag:expr) => ( impl ToSource for $t { fn to_source(&self) -> String { - #![allow(trivial_numeric_cast)] + #![allow(trivial_numeric_casts)] let lit = ast::LitInt(*self as u64, ast::UnsignedIntLit($tag)); pprust::lit_to_string(&dummy_spanned(lit)) } diff --git a/src/test/compile-fail/liveness-unused.rs b/src/test/compile-fail/liveness-unused.rs index addeba03ab8..0fee48a8c6c 100644 --- a/src/test/compile-fail/liveness-unused.rs +++ b/src/test/compile-fail/liveness-unused.rs @@ -10,7 +10,7 @@ #![deny(unused_variables)] #![deny(unused_assignments)] -#![allow(dead_code, non_camel_case_types, trivial_numeric_cast)] +#![allow(dead_code, non_camel_case_types, trivial_numeric_casts)] fn f1(x: isize) { //~^ ERROR unused variable: `x` diff --git a/src/test/compile-fail/object-safety-by-value-self.rs b/src/test/compile-fail/object-safety-by-value-self.rs index 3b0e5786f3d..5a8772d6142 100644 --- a/src/test/compile-fail/object-safety-by-value-self.rs +++ b/src/test/compile-fail/object-safety-by-value-self.rs @@ -12,7 +12,7 @@ #![feature(rustc_attrs)] #![allow(dead_code)] -#![allow(trivial_cast)] +#![allow(trivial_casts)] trait Bar { fn bar(self); diff --git a/src/test/compile-fail/trivial_casts.rs b/src/test/compile-fail/trivial_casts.rs index 05c7747d5b9..3119b865488 100644 --- a/src/test/compile-fail/trivial_casts.rs +++ b/src/test/compile-fail/trivial_casts.rs @@ -8,10 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Test the trivial_cast and trivial_numeric_cast lints. For each error we also +// Test the trivial_casts and trivial_numeric_casts lints. For each error we also // check that the cast can be done using just coercion. -#![deny(trivial_cast, trivial_numeric_cast)] +#![deny(trivial_casts, trivial_numeric_casts)] trait Foo { fn foo(&self) {} diff --git a/src/test/run-pass/trivial_casts.rs b/src/test/run-pass/trivial_casts.rs index 4b145f1079b..3da1ba0f045 100644 --- a/src/test/run-pass/trivial_casts.rs +++ b/src/test/run-pass/trivial_casts.rs @@ -10,7 +10,7 @@ // Test that all coercions can actually be done using casts (modulo the lints). -#![allow(trivial_cast, trivial_numeric_cast)] +#![allow(trivial_casts, trivial_numeric_casts)] trait Foo { fn foo(&self) {} -- cgit 1.4.1-3-g733a5 From 0adab507bbb0b04fe389a00af19fc17753b76343 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Sat, 21 Mar 2015 13:14:28 +0100 Subject: Added `T:Send` bound to `sync::mpsc::Receiver` and `sync::mpsc::Sender`. This was necessary to avoid specialized `Drop` impls for the two structs. --- src/libstd/sync/mpsc/mod.rs | 14 +++++++------- src/libstd/sync/mpsc/oneshot.rs | 8 ++++---- src/libstd/sync/mpsc/select.rs | 2 +- src/libstd/sync/mpsc/stream.rs | 8 ++++---- src/libstd/sys/common/helper_thread.rs | 2 +- 5 files changed, 17 insertions(+), 17 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index 7adfd9154ac..48629beafc8 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -342,7 +342,7 @@ mod spsc_queue; /// The receiving-half of Rust's channel type. This half can only be owned by /// one task #[stable(feature = "rust1", since = "1.0.0")] -pub struct Receiver { +pub struct Receiver { inner: UnsafeCell>, } @@ -354,14 +354,14 @@ unsafe impl Send for Receiver { } /// whenever `next` is called, waiting for a new message, and `None` will be /// returned when the corresponding channel has hung up. #[stable(feature = "rust1", since = "1.0.0")] -pub struct Iter<'a, T:'a> { +pub struct Iter<'a, T:Send+'a> { rx: &'a Receiver } /// The sending-half of Rust's asynchronous channel type. This half can only be /// owned by one task, but it can be cloned to send to other tasks. #[stable(feature = "rust1", since = "1.0.0")] -pub struct Sender { +pub struct Sender { inner: UnsafeCell>, } @@ -433,7 +433,7 @@ pub enum TrySendError { Disconnected(T), } -enum Flavor { +enum Flavor { Oneshot(Arc>>), Stream(Arc>>), Shared(Arc>>), @@ -441,7 +441,7 @@ enum Flavor { } #[doc(hidden)] -trait UnsafeFlavor { +trait UnsafeFlavor { fn inner_unsafe<'a>(&'a self) -> &'a UnsafeCell>; unsafe fn inner_mut<'a>(&'a self) -> &'a mut Flavor { &mut *self.inner_unsafe().get() @@ -450,12 +450,12 @@ trait UnsafeFlavor { &*self.inner_unsafe().get() } } -impl UnsafeFlavor for Sender { +impl UnsafeFlavor for Sender { fn inner_unsafe<'a>(&'a self) -> &'a UnsafeCell> { &self.inner } } -impl UnsafeFlavor for Receiver { +impl UnsafeFlavor for Receiver { fn inner_unsafe<'a>(&'a self) -> &'a UnsafeCell> { &self.inner } diff --git a/src/libstd/sync/mpsc/oneshot.rs b/src/libstd/sync/mpsc/oneshot.rs index f287712d9d4..13578ce0517 100644 --- a/src/libstd/sync/mpsc/oneshot.rs +++ b/src/libstd/sync/mpsc/oneshot.rs @@ -54,7 +54,7 @@ const DISCONNECTED: usize = 2; // channel is disconnected OR upgraded // moves *from* a pointer, ownership of the token is transferred to // whoever changed the state. -pub struct Packet { +pub struct Packet { // Internal state of the chan/port pair (stores the blocked task as well) state: AtomicUsize, // One-shot data slot location @@ -64,7 +64,7 @@ pub struct Packet { upgrade: MyUpgrade, } -pub enum Failure { +pub enum Failure { Empty, Disconnected, Upgraded(Receiver), @@ -76,13 +76,13 @@ pub enum UpgradeResult { UpWoke(SignalToken), } -pub enum SelectionResult { +pub enum SelectionResult { SelCanceled, SelUpgraded(SignalToken, Receiver), SelSuccess, } -enum MyUpgrade { +enum MyUpgrade { NothingSent, SendUsed, GoUp(Receiver), diff --git a/src/libstd/sync/mpsc/select.rs b/src/libstd/sync/mpsc/select.rs index 0f936641cdc..b509b3472ee 100644 --- a/src/libstd/sync/mpsc/select.rs +++ b/src/libstd/sync/mpsc/select.rs @@ -80,7 +80,7 @@ impl !marker::Send for Select {} /// A handle to a receiver which is currently a member of a `Select` set of /// receivers. This handle is used to keep the receiver in the set as well as /// interact with the underlying receiver. -pub struct Handle<'rx, T:'rx> { +pub struct Handle<'rx, T:Send+'rx> { /// The ID of this handle, used to compare against the return value of /// `Select::wait()` id: usize, diff --git a/src/libstd/sync/mpsc/stream.rs b/src/libstd/sync/mpsc/stream.rs index 5a1e05f9c15..a5a73314a6d 100644 --- a/src/libstd/sync/mpsc/stream.rs +++ b/src/libstd/sync/mpsc/stream.rs @@ -39,7 +39,7 @@ const MAX_STEALS: isize = 5; #[cfg(not(test))] const MAX_STEALS: isize = 1 << 20; -pub struct Packet { +pub struct Packet { queue: spsc::Queue>, // internal queue for all message cnt: AtomicIsize, // How many items are on this channel @@ -49,7 +49,7 @@ pub struct Packet { port_dropped: AtomicBool, // flag if the channel has been destroyed. } -pub enum Failure { +pub enum Failure { Empty, Disconnected, Upgraded(Receiver), @@ -61,7 +61,7 @@ pub enum UpgradeResult { UpWoke(SignalToken), } -pub enum SelectionResult { +pub enum SelectionResult { SelSuccess, SelCanceled, SelUpgraded(SignalToken, Receiver), @@ -69,7 +69,7 @@ pub enum SelectionResult { // Any message could contain an "upgrade request" to a new shared port, so the // internal queue it's a queue of T, but rather Message -enum Message { +enum Message { Data(T), GoUp(Receiver), } diff --git a/src/libstd/sys/common/helper_thread.rs b/src/libstd/sys/common/helper_thread.rs index 2a852fbcd57..e8bec66d987 100644 --- a/src/libstd/sys/common/helper_thread.rs +++ b/src/libstd/sys/common/helper_thread.rs @@ -38,7 +38,7 @@ use thread; /// /// The fields of this helper are all public, but they should not be used, this /// is for static initialization. -pub struct Helper { +pub struct Helper { /// Internal lock which protects the remaining fields pub lock: StaticMutex, pub cond: StaticCondvar, -- cgit 1.4.1-3-g733a5 From 26a79e3c204496f55b8c6ff9db741672554f1705 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Sat, 21 Mar 2015 13:20:12 +0100 Subject: Added `Write` bounds to avoid a specialized Drop impl for `BufWriter`. --- src/libstd/io/buffered.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 4def601f1c0..2a1294f23b2 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -120,7 +120,7 @@ impl fmt::Debug for BufReader where R: fmt::Debug { /// /// The buffer will be written out when the writer is dropped. #[stable(feature = "rust1", since = "1.0.0")] -pub struct BufWriter { +pub struct BufWriter { inner: Option, buf: Vec, } @@ -220,7 +220,7 @@ impl Write for BufWriter { } #[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Debug for BufWriter where W: fmt::Debug { +impl fmt::Debug for BufWriter where W: fmt::Debug { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "BufWriter {{ writer: {:?}, buffer: {}/{} }}", self.inner.as_ref().unwrap(), self.buf.len(), self.buf.capacity()) @@ -276,7 +276,7 @@ impl fmt::Display for IntoInnerError { /// /// The buffer will be written out when the writer is dropped. #[stable(feature = "rust1", since = "1.0.0")] -pub struct LineWriter { +pub struct LineWriter { inner: BufWriter, } @@ -335,7 +335,7 @@ impl Write for LineWriter { } #[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Debug for LineWriter where W: fmt::Debug { +impl fmt::Debug for LineWriter where W: fmt::Debug { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "LineWriter {{ writer: {:?}, buffer: {}/{} }}", self.inner.inner, self.inner.buf.len(), @@ -343,16 +343,16 @@ impl fmt::Debug for LineWriter where W: fmt::Debug { } } -struct InternalBufWriter(BufWriter); +struct InternalBufWriter(BufWriter); -impl InternalBufWriter { +impl InternalBufWriter { fn get_mut(&mut self) -> &mut BufWriter { let InternalBufWriter(ref mut w) = *self; return w; } } -impl Read for InternalBufWriter { +impl Read for InternalBufWriter { fn read(&mut self, buf: &mut [u8]) -> io::Result { self.get_mut().inner.as_mut().unwrap().read(buf) } @@ -367,7 +367,7 @@ impl Read for InternalBufWriter { /// /// The output buffer will be written out when this stream is dropped. #[stable(feature = "rust1", since = "1.0.0")] -pub struct BufStream { +pub struct BufStream { inner: BufReader> } @@ -448,7 +448,7 @@ impl Write for BufStream { } #[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Debug for BufStream where S: fmt::Debug { +impl fmt::Debug for BufStream where S: fmt::Debug { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let reader = &self.inner; let writer = &self.inner.inner.0; -- cgit 1.4.1-3-g733a5 From 1249e6089180211c18fdc381a464274ec95edb25 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Sat, 21 Mar 2015 13:22:21 +0100 Subject: Added `T:Send` bound to `Queue` to avoid specialized Drop impl. --- src/libstd/sync/mpsc/mpsc_queue.rs | 2 +- src/libstd/sync/mpsc/shared.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/sync/mpsc/mpsc_queue.rs b/src/libstd/sync/mpsc/mpsc_queue.rs index 14ed253d8e2..1be8b0dd862 100644 --- a/src/libstd/sync/mpsc/mpsc_queue.rs +++ b/src/libstd/sync/mpsc/mpsc_queue.rs @@ -72,7 +72,7 @@ struct Node { /// The multi-producer single-consumer structure. This is not cloneable, but it /// may be safely shared so long as it is guaranteed that there is only one /// popper at a time (many pushers are allowed). -pub struct Queue { +pub struct Queue { head: AtomicPtr>, tail: UnsafeCell<*mut Node>, } diff --git a/src/libstd/sync/mpsc/shared.rs b/src/libstd/sync/mpsc/shared.rs index 8d14824d37f..f3930a8a5d6 100644 --- a/src/libstd/sync/mpsc/shared.rs +++ b/src/libstd/sync/mpsc/shared.rs @@ -40,7 +40,7 @@ const MAX_STEALS: isize = 5; #[cfg(not(test))] const MAX_STEALS: isize = 1 << 20; -pub struct Packet { +pub struct Packet { queue: mpsc::Queue, cnt: AtomicIsize, // How many items are on this channel steals: isize, // How many times has a port received without blocking? -- cgit 1.4.1-3-g733a5 From 1e71d2e71c037b0008ce9f65a61cf814abd52b68 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Sat, 21 Mar 2015 13:28:20 +0100 Subject: Added `W: Writer` bound to `BufferedWriter` to avoid specialized `Drop` impl. --- src/libstd/old_io/buffered.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/old_io/buffered.rs b/src/libstd/old_io/buffered.rs index cb67d709a14..9a9d421dfe1 100644 --- a/src/libstd/old_io/buffered.rs +++ b/src/libstd/old_io/buffered.rs @@ -148,14 +148,14 @@ impl Reader for BufferedReader { /// writer.write_str("hello, world").unwrap(); /// writer.flush().unwrap(); /// ``` -pub struct BufferedWriter { +pub struct BufferedWriter { inner: Option, buf: Vec, pos: uint } #[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Debug for BufferedWriter where W: fmt::Debug { +impl fmt::Debug for BufferedWriter where W: fmt::Debug { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "BufferedWriter {{ writer: {:?}, buffer: {}/{} }}", self.inner.as_ref().unwrap(), self.pos, self.buf.len()) @@ -250,12 +250,12 @@ impl Drop for BufferedWriter { /// `'\n'`) is detected. /// /// This writer will be flushed when it is dropped. -pub struct LineBufferedWriter { +pub struct LineBufferedWriter { inner: BufferedWriter, } #[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Debug for LineBufferedWriter where W: fmt::Debug { +impl fmt::Debug for LineBufferedWriter where W: fmt::Debug { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "LineBufferedWriter {{ writer: {:?}, buffer: {}/{} }}", self.inner.inner, self.inner.pos, self.inner.buf.len()) @@ -299,16 +299,16 @@ impl Writer for LineBufferedWriter { fn flush(&mut self) -> IoResult<()> { self.inner.flush() } } -struct InternalBufferedWriter(BufferedWriter); +struct InternalBufferedWriter(BufferedWriter); -impl InternalBufferedWriter { +impl InternalBufferedWriter { fn get_mut<'a>(&'a mut self) -> &'a mut BufferedWriter { let InternalBufferedWriter(ref mut w) = *self; return w; } } -impl Reader for InternalBufferedWriter { +impl Reader for InternalBufferedWriter { fn read(&mut self, buf: &mut [u8]) -> IoResult { self.get_mut().inner.as_mut().unwrap().read(buf) } @@ -343,12 +343,12 @@ impl Reader for InternalBufferedWriter { /// Err(e) => println!("error reading: {}", e) /// } /// ``` -pub struct BufferedStream { +pub struct BufferedStream { inner: BufferedReader> } #[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Debug for BufferedStream where S: fmt::Debug { +impl fmt::Debug for BufferedStream where S: fmt::Debug { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let reader = &self.inner; let writer = &self.inner.inner.0; -- cgit 1.4.1-3-g733a5 From 018eeb76f0e7384f760afa2a97a07110eef05145 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Sat, 21 Mar 2015 13:30:26 +0100 Subject: added `T:Send` bound to `Mutex` to avoid specialized Drop impl. --- src/libstd/sync/mutex.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libstd') diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index 2bf75cf1d37..6c1cda783b7 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -112,7 +112,7 @@ use fmt; /// *guard += 1; /// ``` #[stable(feature = "rust1", since = "1.0.0")] -pub struct Mutex { +pub struct Mutex { // Note that this static mutex is in a *box*, not inlined into the struct // itself. Once a native mutex has been used once, its address can never // change (it can't be moved). This mutex type can be safely moved at any -- cgit 1.4.1-3-g733a5 From 123b5c124e12ba08bd351c414753902aae9eb045 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Sat, 21 Mar 2015 13:31:58 +0100 Subject: Added `T:Send` bound to `Packet` to avoid specialized `Drop` impl. --- src/libstd/sync/mpsc/mod.rs | 2 +- src/libstd/sync/mpsc/sync.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index 48629beafc8..eb421fe55a4 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -372,7 +372,7 @@ unsafe impl Send for Sender { } /// The sending-half of Rust's synchronous channel type. This half can only be /// owned by one task, but it can be cloned to send to other tasks. #[stable(feature = "rust1", since = "1.0.0")] -pub struct SyncSender { +pub struct SyncSender { inner: Arc>>, } diff --git a/src/libstd/sync/mpsc/sync.rs b/src/libstd/sync/mpsc/sync.rs index 33c1614e1b2..71236269487 100644 --- a/src/libstd/sync/mpsc/sync.rs +++ b/src/libstd/sync/mpsc/sync.rs @@ -47,7 +47,7 @@ use sync::mpsc::blocking::{self, WaitToken, SignalToken}; use sync::mpsc::select::StartResult::{self, Installed, Abort}; use sync::{Mutex, MutexGuard}; -pub struct Packet { +pub struct Packet { /// Only field outside of the mutex. Just done for kicks, but mainly because /// the other shared channel already had the code implemented channels: AtomicUsize, -- cgit 1.4.1-3-g733a5 From 5f57fd591d890cbf9cfc94123071c1a30d809b9e Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Sat, 21 Mar 2015 13:33:12 +0100 Subject: Added `T:Send` bound to `Queue` to avoid specialized `Drop` impl. --- src/libstd/sync/mpsc/spsc_queue.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libstd') diff --git a/src/libstd/sync/mpsc/spsc_queue.rs b/src/libstd/sync/mpsc/spsc_queue.rs index 3fb13739aa7..cd6d1ee05c7 100644 --- a/src/libstd/sync/mpsc/spsc_queue.rs +++ b/src/libstd/sync/mpsc/spsc_queue.rs @@ -57,7 +57,7 @@ struct Node { /// but it can be safely shared in an Arc if it is guaranteed that there /// is only one popper and one pusher touching the queue at any one point in /// time. -pub struct Queue { +pub struct Queue { // consumer fields tail: UnsafeCell<*mut Node>, // where to pop from tail_prev: AtomicPtr>, // where to pop from -- cgit 1.4.1-3-g733a5 From 290c8de0a6f233b1d30c8a97cb41614fce989d30 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Sat, 21 Mar 2015 13:34:33 +0100 Subject: Added `T:Send` bound to `JoinGuard` to avoid specialized `Drop` impl. --- src/libstd/thread/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/libstd') diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 57baeb1fb74..27b50fc9aaa 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -698,7 +698,7 @@ impl Drop for JoinHandle { /// permission. #[must_use = "thread will be immediately joined if `JoinGuard` is not used"] #[stable(feature = "rust1", since = "1.0.0")] -pub struct JoinGuard<'a, T: 'a> { +pub struct JoinGuard<'a, T: Send + 'a> { inner: JoinInner, _marker: PhantomData<&'a T>, } -- cgit 1.4.1-3-g733a5 From 5b2e8693e42dee545d336c0364773b3fbded93a5 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Sat, 21 Mar 2015 13:12:08 +0100 Subject: Reject specialized Drop impls. See Issue 8142 for discussion. This makes it illegal for a Drop impl to be more specialized than the original item. So for example, all of the following are now rejected (when they would have been blindly accepted before): ```rust struct S { ... }; impl Drop for S { ... } // error: specialized to concrete type struct T<'a> { ... }; impl Drop for T<'static> { ... } // error: specialized to concrete region struct U { ... }; impl Drop for U { ... } // error: added extra type requirement struct V<'a,'b>; impl<'a,'b:a> Drop for V<'a,'b> { ... } // error: added extra region requirement ``` Due to examples like the above, this is a [breaking-change]. (The fix is to either remove the specialization from the `Drop` impl, or to transcribe the requirements into the struct/enum definition; examples of both are shown in the PR's fixed to `libstd`.) ---- This is likely to be the last thing blocking the removal of the `#[unsafe_destructor]` attribute. Includes two new error codes for the new dropck check. Update run-pass tests to accommodate new dropck pass. Update tests and docs to reflect new destructor restriction. ---- Implementation notes: We identify Drop impl specialization by not being as parametric as the struct/enum definition via unification. More specifically: 1. Attempt unification of a skolemized instance of the struct/enum with an instance of the Drop impl's type expression where all of the impl's generics (i.e. the free variables of the type expression) have been replaced with unification variables. 2. If unification fails, then reject Drop impl as specialized. 3. If unification succeeds, check if any of the skolemized variables "leaked" into the constraint set for the inference context; if so, then reject Drop impl as specialized. 4. Otherwise, unification succeeded without leaking skolemized variables: accept the Drop impl. We identify whether a Drop impl is injecting new predicates by simply looking whether the predicate, after an appropriate substitution, appears on the struct/enum definition. --- src/doc/trpl/unsafe.md | 17 +- src/librustc/middle/infer/higher_ranked/mod.rs | 58 ++++++ src/librustc/middle/infer/mod.rs | 9 + src/librustc/middle/ty.rs | 3 + src/librustc_typeck/check/dropck.rs | 240 ++++++++++++++++++++++++- src/librustc_typeck/check/mod.rs | 14 ++ src/librustc_typeck/diagnostics.rs | 4 +- src/libstd/sync/mutex.rs | 2 +- src/test/auxiliary/issue-2526.rs | 2 +- src/test/run-pass/issue-15858.rs | 2 +- src/test/run-pass/issue-15924.rs | 2 +- src/test/run-pass/issue-2718.rs | 4 +- src/test/run-pass/issue-4252.rs | 2 +- 13 files changed, 341 insertions(+), 18 deletions(-) (limited to 'src/libstd') diff --git a/src/doc/trpl/unsafe.md b/src/doc/trpl/unsafe.md index 2116976d55a..dbf0cae6f4b 100644 --- a/src/doc/trpl/unsafe.md +++ b/src/doc/trpl/unsafe.md @@ -197,15 +197,16 @@ use std::ptr; // Define a wrapper around the handle returned by the foreign code. // Unique has the same semantics as Box -pub struct Unique { +// +// NB: For simplicity and correctness, we require that T has kind Send +// (owned boxes relax this restriction). +pub struct Unique { // It contains a single raw, mutable pointer to the object in question. ptr: *mut T } // Implement methods for creating and using the values in the box. -// NB: For simplicity and correctness, we require that T has kind Send -// (owned boxes relax this restriction). impl Unique { pub fn new(value: T) -> Unique { unsafe { @@ -239,11 +240,11 @@ impl Unique { // Unique, making the struct manage the raw pointer: when the // struct goes out of scope, it will automatically free the raw pointer. // -// NB: This is an unsafe destructor, because rustc will not normally -// allow destructors to be associated with parameterized types, due to -// bad interaction with managed boxes. (With the Send restriction, -// we don't have this problem.) Note that the `#[unsafe_destructor]` -// feature gate is required to use unsafe destructors. +// NB: This is an unsafe destructor; rustc will not normally allow +// destructors to be associated with parameterized types (due to +// historically failing to check them soundly). Note that the +// `#[unsafe_destructor]` feature gate is currently required to use +// unsafe destructors. #[unsafe_destructor] impl Drop for Unique { fn drop(&mut self) { diff --git a/src/librustc/middle/infer/higher_ranked/mod.rs b/src/librustc/middle/infer/higher_ranked/mod.rs index 7d789bedc50..16b387330b9 100644 --- a/src/librustc/middle/infer/higher_ranked/mod.rs +++ b/src/librustc/middle/infer/higher_ranked/mod.rs @@ -14,6 +14,7 @@ use super::{CombinedSnapshot, cres, InferCtxt, HigherRankedType, SkolemizationMap}; use super::combine::{Combine, Combineable}; +use middle::subst; use middle::ty::{self, Binder}; use middle::ty_fold::{self, TypeFoldable}; use syntax::codemap::Span; @@ -455,6 +456,63 @@ impl<'a,'tcx> InferCtxtExt for InferCtxt<'a,'tcx> { } } +/// Constructs and returns a substitution that, for a given type +/// scheme parameterized by `generics`, will replace every generic +/// parmeter in the type with a skolemized type/region (which one can +/// think of as a "fresh constant", except at the type/region level of +/// reasoning). +/// +/// Since we currently represent bound/free type parameters in the +/// same way, this only has an effect on regions. +/// +/// (Note that unlike a substitution from `ty::construct_free_substs`, +/// this inserts skolemized regions rather than free regions; this +/// allows one to use `fn leak_check` to catch attmepts to unify the +/// skolemized regions with e.g. the `'static` lifetime) +pub fn construct_skolemized_substs<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>, + generics: &ty::Generics<'tcx>, + snapshot: &CombinedSnapshot) + -> (subst::Substs<'tcx>, SkolemizationMap) +{ + let mut map = FnvHashMap(); + + // map T => T + let mut types = subst::VecPerParamSpace::empty(); + push_types_from_defs(infcx.tcx, &mut types, generics.types.as_slice()); + + // map early- or late-bound 'a => fresh 'a + let mut regions = subst::VecPerParamSpace::empty(); + push_region_params(infcx, &mut map, &mut regions, generics.regions.as_slice(), snapshot); + + let substs = subst::Substs { types: types, + regions: subst::NonerasedRegions(regions) }; + return (substs, map); + + fn push_region_params<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>, + map: &mut SkolemizationMap, + regions: &mut subst::VecPerParamSpace, + region_params: &[ty::RegionParameterDef], + snapshot: &CombinedSnapshot) + { + for r in region_params { + let br = r.to_bound_region(); + let skol_var = infcx.region_vars.new_skolemized(br, &snapshot.region_vars_snapshot); + let sanity_check = map.insert(br, skol_var); + assert!(sanity_check.is_none()); + regions.push(r.space, skol_var); + } + } + + fn push_types_from_defs<'tcx>(tcx: &ty::ctxt<'tcx>, + types: &mut subst::VecPerParamSpace>, + defs: &[ty::TypeParameterDef<'tcx>]) { + for def in defs { + let ty = ty::mk_param_from_def(tcx, def); + types.push(def.space, ty); + } + } +} + pub fn skolemize_late_bound_regions<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>, binder: &ty::Binder, snapshot: &CombinedSnapshot) diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 835964828d4..a38adabee91 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -726,6 +726,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }) } + pub fn construct_skolemized_subst(&self, + generics: &ty::Generics<'tcx>, + snapshot: &CombinedSnapshot) + -> (subst::Substs<'tcx>, SkolemizationMap) { + /*! See `higher_ranked::construct_skolemized_subst` */ + + higher_ranked::construct_skolemized_substs(self, generics, snapshot) + } + pub fn skolemize_late_bound_regions(&self, value: &ty::Binder, snapshot: &CombinedSnapshot) diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index e5e89c3fbd4..71c4962d526 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -1793,6 +1793,9 @@ impl RegionParameterDef { pub fn to_early_bound_region(&self) -> ty::Region { ty::ReEarlyBound(self.def_id.node, self.space, self.index, self.name) } + pub fn to_bound_region(&self) -> ty::BoundRegion { + ty::BoundRegion::BrNamed(self.def_id, self.name) + } } /// Information about the formal type/lifetime parameters associated diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 9c48ac43ee4..c48033cab89 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -12,13 +12,249 @@ use check::regionck::{self, Rcx}; use middle::infer; use middle::region; -use middle::subst; +use middle::subst::{self, Subst}; use middle::ty::{self, Ty}; use util::ppaux::{Repr, UserString}; use syntax::ast; -use syntax::codemap::Span; +use syntax::codemap::{self, Span}; + +/// check_drop_impl confirms that the Drop implementation identfied by +/// `drop_impl_did` is not any more specialized than the type it is +/// attached to (Issue #8142). +/// +/// This means: +/// +/// 1. The self type must be nominal (this is already checked during +/// coherence), +/// +/// 2. The generic region/type parameters of the impl's self-type must +/// all be parameters of the Drop impl itself (i.e. no +/// specialization like `impl Drop for Foo`), and, +/// +/// 3. Any bounds on the generic parameters must be reflected in the +/// struct/enum definition for the nominal type itself (i.e. +/// cannot do `struct S; impl Drop for S { ... }`). +/// +pub fn check_drop_impl(tcx: &ty::ctxt, drop_impl_did: ast::DefId) -> Result<(), ()> { + let ty::TypeScheme { generics: ref dtor_generics, + ty: ref dtor_self_type } = ty::lookup_item_type(tcx, drop_impl_did); + let dtor_predicates = ty::lookup_predicates(tcx, drop_impl_did); + match dtor_self_type.sty { + ty::ty_enum(self_type_did, self_to_impl_substs) | + ty::ty_struct(self_type_did, self_to_impl_substs) | + ty::ty_closure(self_type_did, self_to_impl_substs) => { + try!(ensure_drop_params_and_item_params_correspond(tcx, + drop_impl_did, + dtor_generics, + dtor_self_type, + self_type_did)); + + ensure_drop_predicates_are_implied_by_item_defn(tcx, + drop_impl_did, + &dtor_predicates, + self_type_did, + self_to_impl_substs) + } + _ => { + // Destructors only work on nominal types. This was + // already checked by coherence, so we can panic here. + let span = tcx.map.def_id_span(drop_impl_did, codemap::DUMMY_SP); + tcx.sess.span_bug( + span, &format!("should have been rejected by coherence check: {}", + dtor_self_type.repr(tcx))); + } + } +} + +fn ensure_drop_params_and_item_params_correspond<'tcx>( + tcx: &ty::ctxt<'tcx>, + drop_impl_did: ast::DefId, + drop_impl_generics: &ty::Generics<'tcx>, + drop_impl_ty: &ty::Ty<'tcx>, + self_type_did: ast::DefId) -> Result<(), ()> +{ + // New strategy based on review suggestion from nikomatsakis. + // + // (In the text and code below, "named" denotes "struct/enum", and + // "generic params" denotes "type and region params") + // + // 1. Create fresh skolemized type/region "constants" for each of + // the named type's generic params. Instantiate the named type + // with the fresh constants, yielding `named_skolem`. + // + // 2. Create unification variables for each of the Drop impl's + // generic params. Instantiate the impl's Self's type with the + // unification-vars, yielding `drop_unifier`. + // + // 3. Attempt to unify Self_unif with Type_skolem. If unification + // succeeds, continue (i.e. with the predicate checks). + + let ty::TypeScheme { generics: ref named_type_generics, + ty: named_type } = + ty::lookup_item_type(tcx, self_type_did); + + let infcx = infer::new_infer_ctxt(tcx); + infcx.try(|snapshot| { + let (named_type_to_skolem, skol_map) = + infcx.construct_skolemized_subst(named_type_generics, snapshot); + let named_type_skolem = named_type.subst(tcx, &named_type_to_skolem); + + let drop_impl_span = tcx.map.def_id_span(drop_impl_did, codemap::DUMMY_SP); + let drop_to_unifier = + infcx.fresh_substs_for_generics(drop_impl_span, drop_impl_generics); + let drop_unifier = drop_impl_ty.subst(tcx, &drop_to_unifier); + + if let Ok(()) = infer::mk_eqty(&infcx, true, infer::TypeOrigin::Misc(drop_impl_span), + named_type_skolem, drop_unifier) { + // Even if we did manage to equate the types, the process + // may have just gathered unsolvable region constraints + // like `R == 'static` (represented as a pair of subregion + // constraints) for some skolemization constant R. + // + // However, the leak_check method allows us to confirm + // that no skolemized regions escaped (i.e. were related + // to other regions in the constraint graph). + if let Ok(()) = infcx.leak_check(&skol_map, snapshot) { + return Ok(()) + } + } + + span_err!(tcx.sess, drop_impl_span, E0366, + "Implementations of Drop cannot be specialized"); + let item_span = tcx.map.span(self_type_did.node); + tcx.sess.span_note(item_span, + "Use same sequence of generic type and region \ + parameters that is on the struct/enum definition"); + return Err(()); + }) +} + +/// Confirms that every predicate imposed by dtor_predicates is +/// implied by assuming the predicates attached to self_type_did. +fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( + tcx: &ty::ctxt<'tcx>, + drop_impl_did: ast::DefId, + dtor_predicates: &ty::GenericPredicates<'tcx>, + self_type_did: ast::DefId, + self_to_impl_substs: &subst::Substs<'tcx>) -> Result<(), ()> { + + // Here is an example, analogous to that from + // `compare_impl_method`. + // + // Consider a struct type: + // + // struct Type<'c, 'b:'c, 'a> { + // x: &'a Contents // (contents are irrelevant; + // y: &'c Cell<&'b Contents>, // only the bounds matter for our purposes.) + // } + // + // and a Drop impl: + // + // impl<'z, 'y:'z, 'x:'y> Drop for P<'z, 'y, 'x> { + // fn drop(&mut self) { self.y.set(self.x); } // (only legal if 'x: 'y) + // } + // + // We start out with self_to_impl_substs, that maps the generic + // parameters of Type to that of the Drop impl. + // + // self_to_impl_substs = {'c => 'z, 'b => 'y, 'a => 'x} + // + // Applying this to the predicates (i.e. assumptions) provided by the item + // definition yields the instantiated assumptions: + // + // ['y : 'z] + // + // We then check all of the predicates of the Drop impl: + // + // ['y:'z, 'x:'y] + // + // and ensure each is in the list of instantiated + // assumptions. Here, `'y:'z` is present, but `'x:'y` is + // absent. So we report an error that the Drop impl injected a + // predicate that is not present on the struct definition. + + assert_eq!(self_type_did.krate, ast::LOCAL_CRATE); + + let drop_impl_span = tcx.map.def_id_span(drop_impl_did, codemap::DUMMY_SP); + + // We can assume the predicates attached to struct/enum definition + // hold. + let generic_assumptions = ty::lookup_predicates(tcx, self_type_did); + + let assumptions_in_impl_context = generic_assumptions.instantiate(tcx, &self_to_impl_substs); + assert!(assumptions_in_impl_context.predicates.is_empty_in(subst::SelfSpace)); + assert!(assumptions_in_impl_context.predicates.is_empty_in(subst::FnSpace)); + let assumptions_in_impl_context = + assumptions_in_impl_context.predicates.get_slice(subst::TypeSpace); + + // An earlier version of this code attempted to do this checking + // via the traits::fulfill machinery. However, it ran into trouble + // since the fulfill machinery merely turns outlives-predicates + // 'a:'b and T:'b into region inference constraints. It is simpler + // just to look for all the predicates directly. + + assert!(dtor_predicates.predicates.is_empty_in(subst::SelfSpace)); + assert!(dtor_predicates.predicates.is_empty_in(subst::FnSpace)); + let predicates = dtor_predicates.predicates.get_slice(subst::TypeSpace); + for predicate in predicates { + // (We do not need to worry about deep analysis of type + // expressions etc because the Drop impls are already forced + // to take on a structure that is roughly a alpha-renaming of + // the generic parameters of the item definition.) + + // This path now just checks *all* predicates via the direct + // lookup, rather than using fulfill machinery. + // + // However, it may be more efficient in the future to batch + // the analysis together via the fulfill , rather than the + // repeated `contains` calls. + + if !assumptions_in_impl_context.contains(&predicate) { + let item_span = tcx.map.span(self_type_did.node); + let req = predicate.user_string(tcx); + span_err!(tcx.sess, drop_impl_span, E0367, + "The requirement `{}` is added only by the Drop impl.", req); + tcx.sess.span_note(item_span, + "The same requirement must be part of \ + the struct/enum definition"); + } + } + + if tcx.sess.has_errors() { + return Err(()); + } + Ok(()) +} +/// check_safety_of_destructor_if_necessary confirms that the type +/// expression `typ` conforms to the "Drop Check Rule" from the Sound +/// Generic Drop (RFC 769). +/// +/// ---- +/// +/// The Drop Check Rule is the following: +/// +/// Let `v` be some value (either temporary or named) and 'a be some +/// lifetime (scope). If the type of `v` owns data of type `D`, where +/// +/// (1.) `D` has a lifetime- or type-parametric Drop implementation, and +/// (2.) the structure of `D` can reach a reference of type `&'a _`, and +/// (3.) either: +/// +/// (A.) the Drop impl for `D` instantiates `D` at 'a directly, +/// i.e. `D<'a>`, or, +/// +/// (B.) the Drop impl for `D` has some type parameter with a +/// trait bound `T` where `T` is a trait that has at least +/// one method, +/// +/// then 'a must strictly outlive the scope of v. +/// +/// ---- +/// +/// This function is meant to by applied to the type for every +/// expression in the program. pub fn check_safety_of_destructor_if_necessary<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>, typ: ty::Ty<'tcx>, span: Span, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index c3f4937d26b..04ea7961f50 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -478,6 +478,20 @@ pub fn check_item_types(ccx: &CrateCtxt) { visit::walk_crate(&mut visit, krate); ccx.tcx.sess.abort_if_errors(); + + for drop_method_did in ccx.tcx.destructors.borrow().iter() { + if drop_method_did.krate == ast::LOCAL_CRATE { + let drop_impl_did = ccx.tcx.map.get_parent_did(drop_method_did.node); + match dropck::check_drop_impl(ccx.tcx, drop_impl_did) { + Ok(()) => {} + Err(()) => { + assert!(ccx.tcx.sess.has_errors()); + } + } + } + } + + ccx.tcx.sess.abort_if_errors(); } fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 396d060de9e..95e06879fb2 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -177,7 +177,9 @@ register_diagnostics! { E0319, // trait impls for defaulted traits allowed just for structs/enums E0320, // recursive overflow during dropck E0321, // extended coherence rules for defaulted traits violated - E0322 // cannot implement Sized explicitly + E0322, // cannot implement Sized explicitly + E0366, // dropck forbid specialization to concrete type or region + E0367 // dropck forbid specialization to predicate not in struct/enum } __build_diagnostic_array! { DIAGNOSTICS } diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index 6c1cda783b7..b24cfbb6899 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -366,7 +366,7 @@ mod test { use sync::{Arc, Mutex, StaticMutex, MUTEX_INIT, Condvar}; use thread; - struct Packet(Arc<(Mutex, Condvar)>); + struct Packet(Arc<(Mutex, Condvar)>); unsafe impl Send for Packet {} unsafe impl Sync for Packet {} diff --git a/src/test/auxiliary/issue-2526.rs b/src/test/auxiliary/issue-2526.rs index 89b3b56121a..832665abdc2 100644 --- a/src/test/auxiliary/issue-2526.rs +++ b/src/test/auxiliary/issue-2526.rs @@ -15,7 +15,7 @@ use std::marker; -struct arc_destruct { +struct arc_destruct { _data: int, _marker: marker::PhantomData } diff --git a/src/test/run-pass/issue-15858.rs b/src/test/run-pass/issue-15858.rs index 9b300deaa49..265db3fe133 100644 --- a/src/test/run-pass/issue-15858.rs +++ b/src/test/run-pass/issue-15858.rs @@ -25,7 +25,7 @@ impl Bar for BarImpl { } -struct Foo(B); +struct Foo(B); #[unsafe_destructor] impl Drop for Foo { diff --git a/src/test/run-pass/issue-15924.rs b/src/test/run-pass/issue-15924.rs index 6af07c422ef..e544585745d 100644 --- a/src/test/run-pass/issue-15924.rs +++ b/src/test/run-pass/issue-15924.rs @@ -18,7 +18,7 @@ use std::fmt; use serialize::{Encoder, Encodable}; use serialize::json; -struct Foo { +struct Foo { v: T, } diff --git a/src/test/run-pass/issue-2718.rs b/src/test/run-pass/issue-2718.rs index 8d0e0654933..7ca0ee01015 100644 --- a/src/test/run-pass/issue-2718.rs +++ b/src/test/run-pass/issue-2718.rs @@ -162,7 +162,7 @@ pub mod pipes { } } - pub struct send_packet { + pub struct send_packet { p: Option<*const packet>, } @@ -192,7 +192,7 @@ pub mod pipes { } } - pub struct recv_packet { + pub struct recv_packet { p: Option<*const packet>, } diff --git a/src/test/run-pass/issue-4252.rs b/src/test/run-pass/issue-4252.rs index 9d5f8576c63..08ee955cabb 100644 --- a/src/test/run-pass/issue-4252.rs +++ b/src/test/run-pass/issue-4252.rs @@ -21,7 +21,7 @@ trait X { struct Y(int); #[derive(Debug)] -struct Z { +struct Z { x: T } -- cgit 1.4.1-3-g733a5 From 7e3ee02006ec53ff176fc3490ba01eb2a9c823b8 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Tue, 24 Mar 2015 13:50:14 +1300 Subject: Bug fixes --- src/librustc_typeck/check/coercion.rs | 23 ----------------------- src/libstd/sys/windows/os.rs | 2 +- src/libstd/thread/local.rs | 1 + src/libterm/win.rs | 2 +- 4 files changed, 3 insertions(+), 25 deletions(-) (limited to 'src/libstd') diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 8ad11e19b34..ae1dbbb1b00 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -381,29 +381,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { None } } - (&ty::ty_trait(ref data_a), &ty::ty_trait(ref data_b)) => { - // For now, we only support upcasts from - // `Foo+Send` to `Foo` (really, any time there are - // fewer builtin bounds then before). These are - // convenient because they don't require any sort - // of change to the vtable at runtime. - if data_a.bounds.builtin_bounds != data_b.bounds.builtin_bounds && - data_a.bounds.builtin_bounds.is_superset(&data_b.bounds.builtin_bounds) - { - let bounds_a1 = ty::ExistentialBounds { - region_bound: data_a.bounds.region_bound, - builtin_bounds: data_b.bounds.builtin_bounds, - projection_bounds: data_a.bounds.projection_bounds.clone(), - }; - let ty_a1 = ty::mk_trait(tcx, data_a.principal.clone(), bounds_a1); - match self.fcx.infcx().try(|_| self.subtype(ty_a1, ty_b)) { - Ok(_) => Some((ty_b, ty::UnsizeUpcast(ty_b))), - Err(_) => None, - } - } else { - None - } - } (_, &ty::ty_trait(ref data)) => { Some((ty_b, ty::UnsizeVtable(ty::TyTrait { principal: data.principal.clone(), diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs index 83d06371734..167db1e8ac2 100644 --- a/src/libstd/sys/windows/os.rs +++ b/src/libstd/sys/windows/os.rs @@ -109,7 +109,7 @@ impl Iterator for Env { if *self.cur == 0 { return None } let p = &*self.cur; let mut len = 0; - while *(p as *const _).offset(len) != 0 { + while *(p as *const u16).offset(len) != 0 { len += 1; } let p = p as *const u16; diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs index 1bf1b09681c..a2b824bb016 100644 --- a/src/libstd/thread/local.rs +++ b/src/libstd/thread/local.rs @@ -176,6 +176,7 @@ macro_rules! __thread_local_inner { } }; + #[allow(trivial_casts)] #[cfg(any(not(any(target_os = "macos", target_os = "linux")), target_arch = "aarch64"))] const _INIT: ::std::thread::__local::__impl::KeyInner<$t> = { ::std::thread::__local::__impl::KeyInner { diff --git a/src/libterm/win.rs b/src/libterm/win.rs index e29e0e27394..001313db676 100644 --- a/src/libterm/win.rs +++ b/src/libterm/win.rs @@ -126,7 +126,7 @@ impl WinConsole { } Some(box WinConsole { buf: out, def_foreground: fg, def_background: bg, - foreground: fg, background: bg } as Box+Send>) + foreground: fg, background: bg }) } } -- cgit 1.4.1-3-g733a5 From efaef2430484852fc761b08b0653b7d74a17becd Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 24 Mar 2015 16:48:50 -0700 Subject: Test fixes and rebase conflicts, round 1 --- src/libstd/fs/mod.rs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/fs/mod.rs b/src/libstd/fs/mod.rs index ab7675e4646..c1253706832 100644 --- a/src/libstd/fs/mod.rs +++ b/src/libstd/fs/mod.rs @@ -183,6 +183,7 @@ impl File { /// /// ```no_run /// use std::fs::File; + /// use std::io::prelude::*; /// /// # fn foo() -> std::io::Result<()> { /// let mut f = try!(File::create("foo.txt")); @@ -211,6 +212,7 @@ impl File { /// /// ```no_run /// use std::fs::File; + /// use std::io::prelude::*; /// /// # fn foo() -> std::io::Result<()> { /// let mut f = try!(File::create("foo.txt")); -- cgit 1.4.1-3-g733a5 From 3021d4c56422e15331e38f4b7b04c7229e024fda Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 24 Mar 2015 16:55:35 -0700 Subject: Test fixes and rebase conflicts, round 2 --- src/libcore/str/mod.rs | 1 + src/liblibc/lib.rs | 1 + src/librbml/lib.rs | 2 +- src/librustdoc/html/format.rs | 6 +++--- src/librustdoc/html/render.rs | 6 +++--- src/librustdoc/visit_ast.rs | 2 +- src/libstd/sys/windows/net.rs | 2 +- src/libstd/sys/windows/thread_local.rs | 8 ++++++-- 8 files changed, 17 insertions(+), 11 deletions(-) (limited to 'src/libstd') diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 36c3eb33c77..ea98f6f5f24 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -28,6 +28,7 @@ use iter::ExactSizeIterator; use iter::{Map, Iterator, IteratorExt, DoubleEndedIterator}; use marker::Sized; use mem; +#[allow(deprecated)] use num::Int; use ops::{Fn, FnMut, FnOnce}; use option::Option::{self, None, Some}; diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index 1cb1f956e26..89843979cd0 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -2439,6 +2439,7 @@ pub mod consts { } pub mod posix88 { use types::os::arch::c95::c_int; + use types::os::arch::posix88::mode_t; pub const O_RDONLY : c_int = 0; pub const O_WRONLY : c_int = 1; diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs index 182b05acbb6..1ffc6001af5 100644 --- a/src/librbml/lib.rs +++ b/src/librbml/lib.rs @@ -352,7 +352,7 @@ pub mod reader { let i = (val >> 28) as uint; let (shift, mask) = SHIFT_MASK_TABLE[i]; Ok(Res { - val: ((val >> shift) & mask) as uint, + val: ((val >> shift) & mask) as usize, next: start + ((32 - shift) >> 3), }) } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 0e6e008c616..df6beab0f58 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -290,7 +290,7 @@ fn resolved_path(w: &mut fmt::Formatter, did: ast::DefId, p: &clean::Path, if ast_util::is_local(did) || cache.inlined.contains(&did) { Some(repeat("../").take(loc.len()).collect::()) } else { - match cache.extern_locations[did.krate] { + match cache.extern_locations[&did.krate] { render::Remote(ref s) => Some(s.to_string()), render::Local => { Some(repeat("../").take(loc.len()).collect::()) @@ -404,11 +404,11 @@ fn primitive_link(f: &mut fmt::Formatter, needs_termination = true; } Some(&cnum) => { - let path = &m.paths[ast::DefId { + let path = &m.paths[&ast::DefId { krate: cnum, node: ast::CRATE_NODE_ID, }]; - let loc = match m.extern_locations[cnum] { + let loc = match m.extern_locations[&cnum] { render::Remote(ref s) => Some(s.to_string()), render::Local => { let len = CURRENT_LOCATION_KEY.with(|s| s.borrow().len()); diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 28dfe8dca7d..d57739c4002 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1409,8 +1409,8 @@ impl<'a> Item<'a> { // located, then we return `None`. } else { let cache = cache(); - let path = &cache.external_paths[self.item.def_id]; - let root = match cache.extern_locations[self.item.def_id.krate] { + let path = &cache.external_paths[&self.item.def_id]; + let root = match cache.extern_locations[&self.item.def_id.krate] { Remote(ref s) => s.to_string(), Local => self.cx.root_path.clone(), Unknown => return None, @@ -1868,7 +1868,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, path = if ast_util::is_local(it.def_id) { cx.current.connect("/") } else { - let path = &cache.external_paths[it.def_id]; + let path = &cache.external_paths[&it.def_id]; path[..path.len() - 1].connect("/") }, ty = shortty(it).to_static_str(), diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 34f89bfb877..3f813b30ecc 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -196,7 +196,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { Some(tcx) => tcx, None => return false }; - let def = tcx.def_map.borrow()[id].def_id(); + let def = tcx.def_map.borrow()[&id].def_id(); if !ast_util::is_local(def) { return false } let analysis = match self.analysis { Some(analysis) => analysis, None => return false diff --git a/src/libstd/sys/windows/net.rs b/src/libstd/sys/windows/net.rs index e092faf4935..734268c70ac 100644 --- a/src/libstd/sys/windows/net.rs +++ b/src/libstd/sys/windows/net.rs @@ -36,7 +36,7 @@ pub fn init() { &mut data); assert_eq!(ret, 0); - rt::at_exit(|| { c::WSACleanup(); }) + let _ = rt::at_exit(|| { c::WSACleanup(); }); }); } diff --git a/src/libstd/sys/windows/thread_local.rs b/src/libstd/sys/windows/thread_local.rs index 1359803070a..c908c791247 100644 --- a/src/libstd/sys/windows/thread_local.rs +++ b/src/libstd/sys/windows/thread_local.rs @@ -133,9 +133,8 @@ unsafe fn init_dtors() { if !DTORS.is_null() { return } let dtors = box Vec::<(Key, Dtor)>::new(); - DTORS = boxed::into_raw(dtors); - rt::at_exit(move|| { + let res = rt::at_exit(move|| { DTOR_LOCK.lock(); let dtors = DTORS; DTORS = 1 as *mut _; @@ -143,6 +142,11 @@ unsafe fn init_dtors() { assert!(DTORS as uint == 1); // can't re-init after destructing DTOR_LOCK.unlock(); }); + if res.is_ok() { + DTORS = boxed::into_raw(dtors); + } else { + DTORS = 1 as *mut _; + } } unsafe fn register_dtor(key: Key, dtor: Dtor) { -- cgit 1.4.1-3-g733a5