Auto merge of #55194 - kennytm:rollup, r=kennytm

Rollup of 7 pull requests

Successful merges:

 - #54300 (Updated RELEASES.md for 1.30.0)
 - #55013 ([NLL] Propagate bounds from generators)
 - #55071 (Fix ICE and report a human readable error)
 - #55144 (Cleanup resolve)
 - #55166 (Don't warn about parentheses on `match (return)`)
 - #55169 (Add a `copysign` function to f32 and f64)
 - #55178 (Stabilize slice::chunks_exact(), chunks_exact_mut(), rchunks(), rchunks_mut(), rchunks_exact(), rchunks_exact_mut())
This commit is contained in:
bors 2018-10-19 09:29:48 +00:00
commit 74ff7dcb13
27 changed files with 501 additions and 236 deletions

View File

@ -1,3 +1,124 @@
Version 1.30.0 (2018-10-25)
==========================
Language
--------
- [Procedural macros are now available.][52081] These kinds of macros allow for
more powerful code generation, there is a [new chapter available][proc-macros]
in Rust Programming Language book that goes further in depth.
- [You can now use keywords as identifiers using the raw identifiers
syntax (`r#`).][53236] e.g. `let r#bool = true;`
- [Using anonymous parameters in traits is now deprecated with a warning and
will be a hard error in the 2018 edition.][53272]
- [You can now use `crate` in paths.][54404] This allows you to refer to the
crate root in the path. e.g. `use crate::foo;` refers to `foo` in `src/lib.rs`.
- [Using a external crate now no longer requires being prefixed with `::`.][54404]
e.g. previously using a external crate in a module without a use statement
required `let json = ::serde_json::from_str(foo);` can now be written
as `let json = serde_json::from_str(foo);`.
- [You can now apply the `#[used]` attribute to static items to prevent the
compiler from optimising them away even if they appear to be unused.][51363]
e.g. `#[used] static FOO: u32 = 1;`
- [You can now import and reexport macros from other crates with the `use`
syntax.][50911] Macros exported with `#[macro_export]` are now placed into
the root module of the crate. If your macro relies on calling other local
macros it is recommended to export with the
`#[macro_export(local_inner_macros)]` attribute so that users won't have to
import those macros.
- [`mod.rs` files are now optional.][54146] Previously if you had a `foo` module
with a `bar` submodule, you would have `src/foo/mod.rs` and `src/foo/bar.rs`.
Now you can have `src/foo.rs` and `src/foo/bar.rs` to achieve the same effect.
- [You can now catch visibility keywords (e.g. `pub`, `pub(crate)`) in macros
using the `vis` specifier.][53370]
- [Non-macro attributes now allow all forms of literals not just
strings.][53044] e.g. Previously you would write `#[attr("true")]` you can now
write `#[attr(true)]`.
- [You can now specify a function to handle a panic in the Rust runtime with the
`#[panic_handler]` attribute.][51366]
Compiler
--------
- [Added the `riscv32imc-unknown-none-elf` target.][53822]
- [Added the `aarch64-unknown-netbsd` target][53165]
Libraries
---------
- [`ManuallyDrop` now allows the inner type to be unsized.][53033]
Stabilized APIs
---------------
- [`Ipv4Addr::BROADCAST`]
- [`Ipv4Addr::LOCALHOST`]
- [`Ipv4Addr::UNSPECIFIED`]
- [`Ipv6Addr::LOCALHOST`]
- [`Ipv6Addr::UNSPECIFIED`]
- [`Iterator::find_map`]
The following methods are a replacement methods for `trim_left`, `trim_right`,
`trim_left_matches`, and `trim_right_matches`. Which will be deprecated
in 1.33.0.
- [`str::trim_end_matches`]
- [`str::trim_end`]
- [`str::trim_start_matches`]
- [`str::trim_start`]
Cargo
----
- [`cargo run` doesn't require specifying a package in workspaces.][cargo/5877]
- [`cargo doc` now supports `--message-format=json`.][cargo/5878] This is
equivalent to calling `rustdoc --error-format=json`.
- [You can specify which edition to create a project in cargo
with `cargo new --edition`.][cargo/5984] Currently only `2015` is a
valid option.
- [Cargo will now provide a progress bar for builds.][cargo/5995]
Misc
----
- [`rustdoc` allows you to specify what edition to treat your code as with the
`--edition` option.][54057]
- [`rustdoc` now has the `--color` (Specify whether to output color) and
`--error-format` (Specify error format e.g. `json`) options.][53003]
- [We now distribute a `rust-gdbgui` script that invokes `gdbgui` with Rust
debug symbols.][53774]
- [Attributes from Rust tools such as `rustfmt` or `clippy` are now
available.][53459] e.g. `#[rustfmt::skip]` will skip formatting the next item.
[50911]: https://github.com/rust-lang/rust/pull/50911/
[51363]: https://github.com/rust-lang/rust/pull/51363/
[51366]: https://github.com/rust-lang/rust/pull/51366/
[52081]: https://github.com/rust-lang/rust/pull/52081/
[53003]: https://github.com/rust-lang/rust/pull/53003/
[53033]: https://github.com/rust-lang/rust/pull/53033/
[53044]: https://github.com/rust-lang/rust/pull/53044/
[53165]: https://github.com/rust-lang/rust/pull/53165/
[53213]: https://github.com/rust-lang/rust/pull/53213/
[53236]: https://github.com/rust-lang/rust/pull/53236/
[53272]: https://github.com/rust-lang/rust/pull/53272/
[53370]: https://github.com/rust-lang/rust/pull/53370/
[53459]: https://github.com/rust-lang/rust/pull/53459/
[53774]: https://github.com/rust-lang/rust/pull/53774/
[53822]: https://github.com/rust-lang/rust/pull/53822/
[54057]: https://github.com/rust-lang/rust/pull/54057/
[54146]: https://github.com/rust-lang/rust/pull/54146/
[54404]: https://github.com/rust-lang/rust/pull/54404/
[cargo/5877]: https://github.com/rust-lang/cargo/pull/5877/
[cargo/5878]: https://github.com/rust-lang/cargo/pull/5878/
[cargo/5984]: https://github.com/rust-lang/cargo/pull/5984/
[cargo/5995]: https://github.com/rust-lang/cargo/pull/5995/
[proc-macros]: https://doc.rust-lang.org/book/2018-edition/ch19-06-macros.html
[`Ipv4Addr::BROADCAST`]: https://doc.rust-lang.org/nightly/std/net/struct.Ipv4Addr.html#associatedconstant.BROADCAST
[`Ipv4Addr::LOCALHOST`]: https://doc.rust-lang.org/nightly/std/net/struct.Ipv4Addr.html#associatedconstant.LOCALHOST
[`Ipv4Addr::UNSPECIFIED`]: https://doc.rust-lang.org/nightly/std/net/struct.Ipv4Addr.html#associatedconstant.UNSPECIFIED
[`Ipv6Addr::LOCALHOST`]: https://doc.rust-lang.org/nightly/std/net/struct.Ipv6Addr.html#associatedconstant.LOCALHOST
[`Ipv6Addr::UNSPECIFIED`]: https://doc.rust-lang.org/nightly/std/net/struct.Ipv6Addr.html#associatedconstant.UNSPECIFIED
[`Iterator::find_map`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.find_map
[`str::trim_end_matches`]: https://doc.rust-lang.org/nightly/std/primitive.str.html#method.trim_end_matches
[`str::trim_end`]: https://doc.rust-lang.org/nightly/std/primitive.str.html#method.trim_end
[`str::trim_start_matches`]: https://doc.rust-lang.org/nightly/std/primitive.str.html#method.trim_start_matches
[`str::trim_start`]: https://doc.rust-lang.org/nightly/std/primitive.str.html#method.trim_start
Version 1.29.2 (2018-10-11)
===========================
@ -6,6 +127,7 @@ Version 1.29.2 (2018-10-11)
[54639]: https://github.com/rust-lang/rust/pull/54639
Version 1.29.1 (2018-09-25)
===========================
@ -19,6 +141,7 @@ Security Notes
Thank you to Scott McMurray for responsibily disclosing this vulnerability to
us.
Version 1.29.0 (2018-09-13)
==========================
@ -73,7 +196,10 @@ Compatibility Notes
Consider using the `home_dir` function from
https://crates.io/crates/dirs instead.
- [`rustc` will no longer silently ignore invalid data in target spec.][52330]
- [`cfg` attributes and `--cfg` command line flags are now more
strictly validated.][53893]
[53893]: https://github.com/rust-lang/rust/pull/53893/
[52861]: https://github.com/rust-lang/rust/pull/52861/
[52656]: https://github.com/rust-lang/rust/pull/52656/
[52239]: https://github.com/rust-lang/rust/pull/52239/

View File

@ -115,12 +115,10 @@
#![feature(unsize)]
#![feature(allocator_internals)]
#![feature(on_unimplemented)]
#![feature(chunks_exact)]
#![feature(rustc_const_unstable)]
#![feature(const_vec_new)]
#![feature(slice_partition_dedup)]
#![feature(maybe_uninit)]
#![feature(rchunks)]
// Allow testing this library

View File

@ -123,9 +123,9 @@ pub use core::slice::{from_raw_parts, from_raw_parts_mut};
pub use core::slice::{from_ref, from_mut};
#[stable(feature = "slice_get_slice", since = "1.28.0")]
pub use core::slice::SliceIndex;
#[unstable(feature = "chunks_exact", issue = "47115")]
#[stable(feature = "chunks_exact", since = "1.31.0")]
pub use core::slice::{ChunksExact, ChunksExactMut};
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
pub use core::slice::{RChunks, RChunksMut, RChunksExact, RChunksExactMut};
////////////////////////////////////////////////////////////////////////////////

View File

@ -19,8 +19,6 @@
#![feature(str_escape)]
#![feature(try_reserve)]
#![feature(unboxed_closures)]
#![feature(chunks_exact)]
#![feature(rchunks)]
#![feature(repeat_generic_slice)]
extern crate alloc_system;

View File

@ -713,8 +713,6 @@ impl<T> [T] {
/// # Examples
///
/// ```
/// #![feature(chunks_exact)]
///
/// let slice = ['l', 'o', 'r', 'e', 'm'];
/// let mut iter = slice.chunks_exact(2);
/// assert_eq!(iter.next().unwrap(), &['l', 'o']);
@ -725,7 +723,7 @@ impl<T> [T] {
///
/// [`chunks`]: #method.chunks
/// [`rchunks_exact`]: #method.rchunks_exact
#[unstable(feature = "chunks_exact", issue = "47115")]
#[stable(feature = "chunks_exact", since = "1.31.0")]
#[inline]
pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<T> {
assert!(chunk_size != 0);
@ -756,8 +754,6 @@ impl<T> [T] {
/// # Examples
///
/// ```
/// #![feature(chunks_exact)]
///
/// let v = &mut [0, 0, 0, 0, 0];
/// let mut count = 1;
///
@ -772,7 +768,7 @@ impl<T> [T] {
///
/// [`chunks_mut`]: #method.chunks_mut
/// [`rchunks_exact_mut`]: #method.rchunks_exact_mut
#[unstable(feature = "chunks_exact", issue = "47115")]
#[stable(feature = "chunks_exact", since = "1.31.0")]
#[inline]
pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<T> {
assert!(chunk_size != 0);
@ -799,8 +795,6 @@ impl<T> [T] {
/// # Examples
///
/// ```
/// #![feature(rchunks)]
///
/// let slice = ['l', 'o', 'r', 'e', 'm'];
/// let mut iter = slice.rchunks(2);
/// assert_eq!(iter.next().unwrap(), &['e', 'm']);
@ -811,7 +805,7 @@ impl<T> [T] {
///
/// [`rchunks_exact`]: #method.rchunks_exact
/// [`chunks`]: #method.chunks
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
#[inline]
pub fn rchunks(&self, chunk_size: usize) -> RChunks<T> {
assert!(chunk_size != 0);
@ -835,8 +829,6 @@ impl<T> [T] {
/// # Examples
///
/// ```
/// #![feature(rchunks)]
///
/// let v = &mut [0, 0, 0, 0, 0];
/// let mut count = 1;
///
@ -851,7 +843,7 @@ impl<T> [T] {
///
/// [`rchunks_exact_mut`]: #method.rchunks_exact_mut
/// [`chunks_mut`]: #method.chunks_mut
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
#[inline]
pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<T> {
assert!(chunk_size != 0);
@ -879,8 +871,6 @@ impl<T> [T] {
/// # Examples
///
/// ```
/// #![feature(rchunks)]
///
/// let slice = ['l', 'o', 'r', 'e', 'm'];
/// let mut iter = slice.rchunks_exact(2);
/// assert_eq!(iter.next().unwrap(), &['e', 'm']);
@ -891,7 +881,7 @@ impl<T> [T] {
///
/// [`rchunks`]: #method.rchunks
/// [`chunks_exact`]: #method.chunks_exact
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
#[inline]
pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<T> {
assert!(chunk_size != 0);
@ -921,8 +911,6 @@ impl<T> [T] {
/// # Examples
///
/// ```
/// #![feature(rchunks)]
///
/// let v = &mut [0, 0, 0, 0, 0];
/// let mut count = 1;
///
@ -937,7 +925,7 @@ impl<T> [T] {
///
/// [`rchunks_mut`]: #method.rchunks_mut
/// [`chunks_exact_mut`]: #method.chunks_exact_mut
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
#[inline]
pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<T> {
assert!(chunk_size != 0);
@ -4022,25 +4010,25 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksMut<'a, T> {
/// [`remainder`]: ../../std/slice/struct.ChunksExact.html#method.remainder
/// [slices]: ../../std/primitive.slice.html
#[derive(Debug)]
#[unstable(feature = "chunks_exact", issue = "47115")]
#[stable(feature = "chunks_exact", since = "1.31.0")]
pub struct ChunksExact<'a, T:'a> {
v: &'a [T],
rem: &'a [T],
chunk_size: usize
}
#[unstable(feature = "chunks_exact", issue = "47115")]
impl<'a, T> ChunksExact<'a, T> {
/// Return the remainder of the original slice that is not going to be
/// returned by the iterator. The returned slice has at most `chunk_size-1`
/// elements.
#[stable(feature = "chunks_exact", since = "1.31.0")]
pub fn remainder(&self) -> &'a [T] {
self.rem
}
}
// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
#[unstable(feature = "chunks_exact", issue = "47115")]
#[stable(feature = "chunks_exact", since = "1.31.0")]
impl<T> Clone for ChunksExact<'_, T> {
fn clone(&self) -> Self {
ChunksExact {
@ -4051,7 +4039,7 @@ impl<T> Clone for ChunksExact<'_, T> {
}
}
#[unstable(feature = "chunks_exact", issue = "47115")]
#[stable(feature = "chunks_exact", since = "1.31.0")]
impl<'a, T> Iterator for ChunksExact<'a, T> {
type Item = &'a [T];
@ -4096,7 +4084,7 @@ impl<'a, T> Iterator for ChunksExact<'a, T> {
}
}
#[unstable(feature = "chunks_exact", issue = "47115")]
#[stable(feature = "chunks_exact", since = "1.31.0")]
impl<'a, T> DoubleEndedIterator for ChunksExact<'a, T> {
#[inline]
fn next_back(&mut self) -> Option<&'a [T]> {
@ -4110,7 +4098,7 @@ impl<'a, T> DoubleEndedIterator for ChunksExact<'a, T> {
}
}
#[unstable(feature = "chunks_exact", issue = "47115")]
#[stable(feature = "chunks_exact", since = "1.31.0")]
impl<T> ExactSizeIterator for ChunksExact<'_, T> {
fn is_empty(&self) -> bool {
self.v.is_empty()
@ -4120,11 +4108,11 @@ impl<T> ExactSizeIterator for ChunksExact<'_, T> {
#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<T> TrustedLen for ChunksExact<'_, T> {}
#[unstable(feature = "chunks_exact", issue = "47115")]
#[stable(feature = "chunks_exact", since = "1.31.0")]
impl<T> FusedIterator for ChunksExact<'_, T> {}
#[doc(hidden)]
#[unstable(feature = "chunks_exact", issue = "47115")]
#[stable(feature = "chunks_exact", since = "1.31.0")]
unsafe impl<'a, T> TrustedRandomAccess for ChunksExact<'a, T> {
unsafe fn get_unchecked(&mut self, i: usize) -> &'a [T] {
let start = i * self.chunk_size;
@ -4146,24 +4134,24 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExact<'a, T> {
/// [`into_remainder`]: ../../std/slice/struct.ChunksExactMut.html#method.into_remainder
/// [slices]: ../../std/primitive.slice.html
#[derive(Debug)]
#[unstable(feature = "chunks_exact", issue = "47115")]
#[stable(feature = "chunks_exact", since = "1.31.0")]
pub struct ChunksExactMut<'a, T:'a> {
v: &'a mut [T],
rem: &'a mut [T],
chunk_size: usize
}
#[unstable(feature = "chunks_exact", issue = "47115")]
impl<'a, T> ChunksExactMut<'a, T> {
/// Return the remainder of the original slice that is not going to be
/// returned by the iterator. The returned slice has at most `chunk_size-1`
/// elements.
#[stable(feature = "chunks_exact", since = "1.31.0")]
pub fn into_remainder(self) -> &'a mut [T] {
self.rem
}
}
#[unstable(feature = "chunks_exact", issue = "47115")]
#[stable(feature = "chunks_exact", since = "1.31.0")]
impl<'a, T> Iterator for ChunksExactMut<'a, T> {
type Item = &'a mut [T];
@ -4210,7 +4198,7 @@ impl<'a, T> Iterator for ChunksExactMut<'a, T> {
}
}
#[unstable(feature = "chunks_exact", issue = "47115")]
#[stable(feature = "chunks_exact", since = "1.31.0")]
impl<'a, T> DoubleEndedIterator for ChunksExactMut<'a, T> {
#[inline]
fn next_back(&mut self) -> Option<&'a mut [T]> {
@ -4226,7 +4214,7 @@ impl<'a, T> DoubleEndedIterator for ChunksExactMut<'a, T> {
}
}
#[unstable(feature = "chunks_exact", issue = "47115")]
#[stable(feature = "chunks_exact", since = "1.31.0")]
impl<T> ExactSizeIterator for ChunksExactMut<'_, T> {
fn is_empty(&self) -> bool {
self.v.is_empty()
@ -4236,11 +4224,11 @@ impl<T> ExactSizeIterator for ChunksExactMut<'_, T> {
#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<T> TrustedLen for ChunksExactMut<'_, T> {}
#[unstable(feature = "chunks_exact", issue = "47115")]
#[stable(feature = "chunks_exact", since = "1.31.0")]
impl<T> FusedIterator for ChunksExactMut<'_, T> {}
#[doc(hidden)]
#[unstable(feature = "chunks_exact", issue = "47115")]
#[stable(feature = "chunks_exact", since = "1.31.0")]
unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> {
unsafe fn get_unchecked(&mut self, i: usize) -> &'a mut [T] {
let start = i * self.chunk_size;
@ -4260,14 +4248,14 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> {
/// [`rchunks`]: ../../std/primitive.slice.html#method.rchunks
/// [slices]: ../../std/primitive.slice.html
#[derive(Debug)]
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
pub struct RChunks<'a, T:'a> {
v: &'a [T],
chunk_size: usize
}
// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
impl<'a, T> Clone for RChunks<'a, T> {
fn clone(&self) -> RChunks<'a, T> {
RChunks {
@ -4277,7 +4265,7 @@ impl<'a, T> Clone for RChunks<'a, T> {
}
}
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
impl<'a, T> Iterator for RChunks<'a, T> {
type Item = &'a [T];
@ -4341,7 +4329,7 @@ impl<'a, T> Iterator for RChunks<'a, T> {
}
}
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
impl<'a, T> DoubleEndedIterator for RChunks<'a, T> {
#[inline]
fn next_back(&mut self) -> Option<&'a [T]> {
@ -4357,17 +4345,17 @@ impl<'a, T> DoubleEndedIterator for RChunks<'a, T> {
}
}
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
impl<'a, T> ExactSizeIterator for RChunks<'a, T> {}
#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<'a, T> TrustedLen for RChunks<'a, T> {}
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
impl<'a, T> FusedIterator for RChunks<'a, T> {}
#[doc(hidden)]
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
unsafe impl<'a, T> TrustedRandomAccess for RChunks<'a, T> {
unsafe fn get_unchecked(&mut self, i: usize) -> &'a [T] {
let end = self.v.len() - i * self.chunk_size;
@ -4391,13 +4379,13 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunks<'a, T> {
/// [`rchunks_mut`]: ../../std/primitive.slice.html#method.rchunks_mut
/// [slices]: ../../std/primitive.slice.html
#[derive(Debug)]
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
pub struct RChunksMut<'a, T:'a> {
v: &'a mut [T],
chunk_size: usize
}
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
impl<'a, T> Iterator for RChunksMut<'a, T> {
type Item = &'a mut [T];
@ -4465,7 +4453,7 @@ impl<'a, T> Iterator for RChunksMut<'a, T> {
}
}
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
impl<'a, T> DoubleEndedIterator for RChunksMut<'a, T> {
#[inline]
fn next_back(&mut self) -> Option<&'a mut [T]> {
@ -4482,17 +4470,17 @@ impl<'a, T> DoubleEndedIterator for RChunksMut<'a, T> {
}
}
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
impl<'a, T> ExactSizeIterator for RChunksMut<'a, T> {}
#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<'a, T> TrustedLen for RChunksMut<'a, T> {}
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
impl<'a, T> FusedIterator for RChunksMut<'a, T> {}
#[doc(hidden)]
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
unsafe impl<'a, T> TrustedRandomAccess for RChunksMut<'a, T> {
unsafe fn get_unchecked(&mut self, i: usize) -> &'a mut [T] {
let end = self.v.len() - i * self.chunk_size;
@ -4518,25 +4506,25 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksMut<'a, T> {
/// [`remainder`]: ../../std/slice/struct.ChunksExact.html#method.remainder
/// [slices]: ../../std/primitive.slice.html
#[derive(Debug)]
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
pub struct RChunksExact<'a, T:'a> {
v: &'a [T],
rem: &'a [T],
chunk_size: usize
}
#[unstable(feature = "rchunks", issue = "55177")]
impl<'a, T> RChunksExact<'a, T> {
/// Return the remainder of the original slice that is not going to be
/// returned by the iterator. The returned slice has at most `chunk_size-1`
/// elements.
#[stable(feature = "rchunks", since = "1.31.0")]
pub fn remainder(&self) -> &'a [T] {
self.rem
}
}
// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
impl<'a, T> Clone for RChunksExact<'a, T> {
fn clone(&self) -> RChunksExact<'a, T> {
RChunksExact {
@ -4547,7 +4535,7 @@ impl<'a, T> Clone for RChunksExact<'a, T> {
}
}
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
impl<'a, T> Iterator for RChunksExact<'a, T> {
type Item = &'a [T];
@ -4592,7 +4580,7 @@ impl<'a, T> Iterator for RChunksExact<'a, T> {
}
}
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
impl<'a, T> DoubleEndedIterator for RChunksExact<'a, T> {
#[inline]
fn next_back(&mut self) -> Option<&'a [T]> {
@ -4606,7 +4594,7 @@ impl<'a, T> DoubleEndedIterator for RChunksExact<'a, T> {
}
}
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
impl<'a, T> ExactSizeIterator for RChunksExact<'a, T> {
fn is_empty(&self) -> bool {
self.v.is_empty()
@ -4616,11 +4604,11 @@ impl<'a, T> ExactSizeIterator for RChunksExact<'a, T> {
#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<'a, T> TrustedLen for RChunksExact<'a, T> {}
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
impl<'a, T> FusedIterator for RChunksExact<'a, T> {}
#[doc(hidden)]
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
unsafe impl<'a, T> TrustedRandomAccess for RChunksExact<'a, T> {
unsafe fn get_unchecked(&mut self, i: usize) -> &'a [T] {
let end = self.v.len() - i * self.chunk_size;
@ -4643,24 +4631,24 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExact<'a, T> {
/// [`into_remainder`]: ../../std/slice/struct.ChunksExactMut.html#method.into_remainder
/// [slices]: ../../std/primitive.slice.html
#[derive(Debug)]
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
pub struct RChunksExactMut<'a, T:'a> {
v: &'a mut [T],
rem: &'a mut [T],
chunk_size: usize
}
#[unstable(feature = "rchunks", issue = "55177")]
impl<'a, T> RChunksExactMut<'a, T> {
/// Return the remainder of the original slice that is not going to be
/// returned by the iterator. The returned slice has at most `chunk_size-1`
/// elements.
#[stable(feature = "rchunks", since = "1.31.0")]
pub fn into_remainder(self) -> &'a mut [T] {
self.rem
}
}
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
impl<'a, T> Iterator for RChunksExactMut<'a, T> {
type Item = &'a mut [T];
@ -4709,7 +4697,7 @@ impl<'a, T> Iterator for RChunksExactMut<'a, T> {
}
}
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
impl<'a, T> DoubleEndedIterator for RChunksExactMut<'a, T> {
#[inline]
fn next_back(&mut self) -> Option<&'a mut [T]> {
@ -4724,7 +4712,7 @@ impl<'a, T> DoubleEndedIterator for RChunksExactMut<'a, T> {
}
}
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
impl<'a, T> ExactSizeIterator for RChunksExactMut<'a, T> {
fn is_empty(&self) -> bool {
self.v.is_empty()
@ -4734,11 +4722,11 @@ impl<'a, T> ExactSizeIterator for RChunksExactMut<'a, T> {
#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<'a, T> TrustedLen for RChunksExactMut<'a, T> {}
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
impl<'a, T> FusedIterator for RChunksExactMut<'a, T> {}
#[doc(hidden)]
#[unstable(feature = "rchunks", issue = "55177")]
#[stable(feature = "rchunks", since = "1.31.0")]
unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {
unsafe fn get_unchecked(&mut self, i: usize) -> &'a mut [T] {
let end = self.v.len() - i * self.chunk_size;

View File

@ -34,8 +34,6 @@
#![feature(trusted_len)]
#![feature(try_from)]
#![feature(try_trait)]
#![feature(chunks_exact)]
#![feature(rchunks)]
#![feature(align_offset)]
#![feature(reverse_bits)]
#![feature(inner_deref)]

View File

@ -58,6 +58,8 @@ pub enum CastKind {
}
impl<'tcx> CastTy<'tcx> {
/// Returns `Some` for integral/pointer casts.
/// casts like unsizing casts will return `None`
pub fn from_ty(t: Ty<'tcx>) -> Option<CastTy<'tcx>> {
match t.sty {
ty::Bool => Some(CastTy::Int(IntTy::Bool)),

View File

@ -276,10 +276,13 @@ impl UnusedParens {
cx: &EarlyContext,
value: &ast::Expr,
msg: &str,
struct_lit_needs_parens: bool) {
followed_by_block: bool) {
if let ast::ExprKind::Paren(ref inner) = value.node {
let necessary = struct_lit_needs_parens &&
parser::contains_exterior_struct_lit(&inner);
let necessary = followed_by_block && if let ast::ExprKind::Ret(_) = inner.node {
true
} else {
parser::contains_exterior_struct_lit(&inner)
};
if !necessary {
let pattern = pprust::expr_to_string(value);
Self::remove_outer_parens(cx, value.span, &pattern, msg);
@ -343,7 +346,7 @@ impl LintPass for UnusedParens {
impl EarlyLintPass for UnusedParens {
fn check_expr(&mut self, cx: &EarlyContext, e: &ast::Expr) {
use syntax::ast::ExprKind::*;
let (value, msg, struct_lit_needs_parens) = match e.node {
let (value, msg, followed_by_block) = match e.node {
If(ref cond, ..) => (cond, "`if` condition", true),
While(ref cond, ..) => (cond, "`while` condition", true),
IfLet(_, ref cond, ..) => (cond, "`if let` head expression", true),
@ -380,7 +383,7 @@ impl EarlyLintPass for UnusedParens {
return;
}
};
self.check_unused_parens_expr(cx, &value, msg, struct_lit_needs_parens);
self.check_unused_parens_expr(cx, &value, msg, followed_by_block);
}
fn check_pat(&mut self, cx: &EarlyContext, p: &ast::Pat) {

View File

@ -1268,7 +1268,7 @@ pub trait ClosureRegionRequirementsExt<'gcx, 'tcx> {
tcx: TyCtxt<'_, 'gcx, 'tcx>,
location: Location,
closure_def_id: DefId,
closure_substs: ty::ClosureSubsts<'tcx>,
closure_substs: &'tcx ty::subst::Substs<'tcx>,
) -> Vec<QueryRegionConstraint<'tcx>>;
fn subst_closure_mapping<T>(
@ -1299,23 +1299,19 @@ impl<'gcx, 'tcx> ClosureRegionRequirementsExt<'gcx, 'tcx> for ClosureRegionRequi
tcx: TyCtxt<'_, 'gcx, 'tcx>,
location: Location,
closure_def_id: DefId,
closure_substs: ty::ClosureSubsts<'tcx>,
closure_substs: &'tcx ty::subst::Substs<'tcx>,
) -> Vec<QueryRegionConstraint<'tcx>> {
debug!(
"apply_requirements(location={:?}, closure_def_id={:?}, closure_substs={:?})",
location, closure_def_id, closure_substs
);
// Get Tu.
let user_closure_ty = tcx.mk_closure(closure_def_id, closure_substs);
debug!("apply_requirements: user_closure_ty={:?}", user_closure_ty);
// Extract the values of the free regions in `user_closure_ty`
// Extract the values of the free regions in `closure_substs`
// into a vector. These are the regions that we will be
// relating to one another.
let closure_mapping = &UniversalRegions::closure_mapping(
tcx,
user_closure_ty,
closure_substs,
self.num_external_vids,
tcx.closure_base_def_id(closure_def_id),
);

View File

@ -42,7 +42,7 @@ use rustc::traits::query::type_op::custom::CustomTypeOp;
use rustc::traits::query::{Fallible, NoSolution};
use rustc::traits::{ObligationCause, PredicateObligations};
use rustc::ty::fold::TypeFoldable;
use rustc::ty::subst::{Subst, UnpackedKind};
use rustc::ty::subst::{Subst, Substs, UnpackedKind};
use rustc::ty::{self, RegionVid, ToPolyTraitRef, Ty, TyCtxt, TyKind};
use std::rc::Rc;
use std::{fmt, iter};
@ -2075,12 +2075,9 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
// desugaring. A closure gets desugared to a struct, and
// these extra requirements are basically like where
// clauses on the struct.
AggregateKind::Closure(def_id, substs) => {
self.prove_closure_bounds(tcx, *def_id, *substs, location)
}
AggregateKind::Generator(def_id, substs, _) => {
tcx.predicates_of(*def_id).instantiate(tcx, substs.substs)
AggregateKind::Closure(def_id, ty::ClosureSubsts { substs })
| AggregateKind::Generator(def_id, ty::GeneratorSubsts { substs }, _) => {
self.prove_closure_bounds(tcx, *def_id, substs, location)
}
AggregateKind::Array(_) | AggregateKind::Tuple => ty::InstantiatedPredicates::empty(),
@ -2096,7 +2093,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
&mut self,
tcx: TyCtxt<'a, 'gcx, 'tcx>,
def_id: DefId,
substs: ty::ClosureSubsts<'tcx>,
substs: &'tcx Substs<'tcx>,
location: Location,
) -> ty::InstantiatedPredicates<'tcx> {
if let Some(closure_region_requirements) =
@ -2155,7 +2152,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
);
}
tcx.predicates_of(def_id).instantiate(tcx, substs.substs)
tcx.predicates_of(def_id).instantiate(tcx, substs)
}
fn prove_trait_ref(

View File

@ -232,13 +232,13 @@ impl<'tcx> UniversalRegions<'tcx> {
/// `V[1]: V[2]`.
pub fn closure_mapping(
tcx: TyCtxt<'_, '_, 'tcx>,
closure_ty: Ty<'tcx>,
closure_substs: &'tcx Substs<'tcx>,
expected_num_vars: usize,
closure_base_def_id: DefId,
) -> IndexVec<RegionVid, ty::Region<'tcx>> {
let mut region_mapping = IndexVec::with_capacity(expected_num_vars);
region_mapping.push(tcx.types.re_static);
tcx.for_each_free_region(&closure_ty, |fr| {
tcx.for_each_free_region(&closure_substs, |fr| {
region_mapping.push(fr);
});

View File

@ -148,7 +148,7 @@ fn check_rvalue(
Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) => {
check_place(tcx, mir, place, span, PlaceMode::Read)
}
Rvalue::Cast(_, operand, cast_ty) => {
Rvalue::Cast(CastKind::Misc, operand, cast_ty) => {
use rustc::ty::cast::CastTy;
let cast_in = CastTy::from_ty(operand.ty(mir, tcx)).expect("bad input type for cast");
let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
@ -163,6 +163,16 @@ fn check_rvalue(
_ => check_operand(tcx, mir, operand, span),
}
}
Rvalue::Cast(CastKind::UnsafeFnPointer, _, _) |
Rvalue::Cast(CastKind::ClosureFnPointer, _, _) |
Rvalue::Cast(CastKind::ReifyFnPointer, _, _) => Err((
span,
"function pointer casts are not allowed in const fn".into(),
)),
Rvalue::Cast(CastKind::Unsize, _, _) => Err((
span,
"unsizing casts are not allowed in const fn".into(),
)),
// binops are fine on integers
Rvalue::BinaryOp(_, lhs, rhs) | Rvalue::CheckedBinaryOp(_, lhs, rhs) => {
check_operand(tcx, mir, lhs, span)?;
@ -177,8 +187,11 @@ fn check_rvalue(
))
}
}
// checked by regular const fn checks
Rvalue::NullaryOp(..) => Ok(()),
Rvalue::NullaryOp(NullOp::SizeOf, _) => Ok(()),
Rvalue::NullaryOp(NullOp::Box, _) => Err((
span,
"heap allocations are not allowed in const fn".into(),
)),
Rvalue::UnaryOp(_, operand) => {
let ty = operand.ty(mir, tcx);
if ty.is_integral() || ty.is_bool() {

View File

@ -139,7 +139,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
let prefix_iter = || parent_prefix.iter().cloned()
.chain(use_tree.prefix.segments.iter().map(|seg| seg.ident));
let prefix_start = prefix_iter().nth(0);
let prefix_start = prefix_iter().next();
let starts_with_non_keyword = prefix_start.map_or(false, |ident| {
!ident.is_path_segment_keyword()
});
@ -1048,13 +1048,10 @@ impl<'a, 'b, 'cl> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b, 'cl> {
fn visit_token(&mut self, t: Token) {
if let Token::Interpolated(nt) = t {
match nt.0 {
token::NtExpr(ref expr) => {
if let ast::ExprKind::Mac(..) = expr.node {
self.visit_invoc(expr.id);
}
if let token::NtExpr(ref expr) = nt.0 {
if let ast::ExprKind::Mac(..) = expr.node {
self.visit_invoc(expr.id);
}
_ => {}
}
}
}

View File

@ -109,7 +109,7 @@ impl<'a, 'b, 'cl> Visitor<'a> for UnusedImportCheckVisitor<'a, 'b, 'cl> {
self.item_span
};
if items.len() == 0 {
if items.is_empty() {
self.unused_imports
.entry(self.base_id)
.or_default()
@ -170,7 +170,7 @@ pub fn check_crate(resolver: &mut Resolver, krate: &ast::Crate) {
for (id, spans) in &visitor.unused_imports {
let len = spans.len();
let mut spans = spans.values().map(|s| *s).collect::<Vec<Span>>();
let mut spans = spans.values().cloned().collect::<Vec<Span>>();
spans.sort();
let ms = MultiSpan::from_spans(spans.clone());
let mut span_snippets = spans.iter()
@ -183,7 +183,7 @@ pub fn check_crate(resolver: &mut Resolver, krate: &ast::Crate) {
span_snippets.sort();
let msg = format!("unused import{}{}",
if len > 1 { "s" } else { "" },
if span_snippets.len() > 0 {
if !span_snippets.is_empty() {
format!(": {}", span_snippets.join(", "))
} else {
String::new()

View File

@ -1633,19 +1633,17 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
*def = module.def().unwrap(),
PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 =>
*def = path_res.base_def(),
PathResult::NonModule(..) => match self.resolve_path(
None,
&path,
None,
true,
span,
CrateLint::No,
) {
PathResult::Failed(span, msg, _) => {
PathResult::NonModule(..) =>
if let PathResult::Failed(span, msg, _) = self.resolve_path(
None,
&path,
None,
true,
span,
CrateLint::No,
) {
error_callback(self, span, ResolutionError::FailedToResolve(&msg));
}
_ => {}
},
},
PathResult::Module(ModuleOrUniformRoot::UniformRoot(_)) |
PathResult::Indeterminate => unreachable!(),
PathResult::Failed(span, msg, _) => {
@ -2357,7 +2355,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
span: prefix.span.to(use_tree.prefix.span),
};
if items.len() == 0 {
if items.is_empty() {
// Resolve prefix of an import with empty braces (issue #28388).
self.smart_resolve_path_with_crate_lint(
id,
@ -2696,7 +2694,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
let map_j = self.binding_mode_map(&q);
for (&key, &binding_i) in &map_i {
if map_j.len() == 0 { // Account for missing bindings when
if map_j.is_empty() { // Account for missing bindings when
let binding_error = missing_vars // map_j has none.
.entry(key.name)
.or_insert(BindingError {
@ -2757,9 +2755,8 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
// This has to happen *after* we determine which pat_idents are variants
self.check_consistent_bindings(&arm.pats);
match arm.guard {
Some(ast::Guard::If(ref expr)) => self.visit_expr(expr),
_ => {}
if let Some(ast::Guard::If(ref expr)) = arm.guard {
self.visit_expr(expr)
}
self.visit_expr(&arm.body);
@ -3000,14 +2997,14 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
// Make the base error.
let expected = source.descr_expected();
let path_str = names_to_string(path);
let item_str = path[path.len() - 1];
let item_str = path.last().unwrap();
let code = source.error_code(def.is_some());
let (base_msg, fallback_label, base_span) = if let Some(def) = def {
(format!("expected {}, found {} `{}`", expected, def.kind_name(), path_str),
format!("not a {}", expected),
span)
} else {
let item_span = path[path.len() - 1].span;
let item_span = path.last().unwrap().span;
let (mod_prefix, mod_str) = if path.len() == 1 {
(String::new(), "this scope".to_string())
} else if path.len() == 2 && path[0].name == keywords::CrateRoot.name() {
@ -3030,10 +3027,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
let mut err = this.session.struct_span_err_with_code(base_span, &base_msg, code);
// Emit help message for fake-self from other languages like `this`(javascript)
let fake_self: Vec<Ident> = ["this", "my"].iter().map(
|s| Ident::from_str(*s)
).collect();
if fake_self.contains(&item_str)
if ["this", "my"].contains(&&*item_str.as_str())
&& this.self_value_is_available(path[0].span, span) {
err.span_suggestion_with_applicability(
span,
@ -3374,7 +3368,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
);
}
break;
} else if snippet.trim().len() != 0 {
} else if !snippet.trim().is_empty() {
debug!("tried to find type ascription `:` token, couldn't find it");
break;
}
@ -3936,7 +3930,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
}
_ => {}
}
return def;
def
}
fn lookup_assoc_candidate<FilterFn>(&mut self,
@ -4386,10 +4380,9 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
where FilterFn: Fn(Def) -> bool
{
let mut candidates = Vec::new();
let mut worklist = Vec::new();
let mut seen_modules = FxHashSet();
let not_local_module = crate_name != keywords::Crate.ident();
worklist.push((start_module, Vec::<ast::PathSegment>::new(), not_local_module));
let mut worklist = vec![(start_module, Vec::<ast::PathSegment>::new(), not_local_module)];
while let Some((in_module,
path_segments,
@ -4476,33 +4469,24 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
-> Vec<ImportSuggestion>
where FilterFn: Fn(Def) -> bool
{
let mut suggestions = vec![];
suggestions.extend(
self.lookup_import_candidates_from_module(
lookup_name, namespace, self.graph_root, keywords::Crate.ident(), &filter_fn
)
);
let mut suggestions = self.lookup_import_candidates_from_module(
lookup_name, namespace, self.graph_root, keywords::Crate.ident(), &filter_fn);
if self.session.rust_2018() {
let extern_prelude_names = self.extern_prelude.clone();
for &name in extern_prelude_names.iter() {
let ident = Ident::with_empty_ctxt(name);
match self.crate_loader.maybe_process_path_extern(name, ident.span) {
Some(crate_id) => {
let crate_root = self.get_module(DefId {
krate: crate_id,
index: CRATE_DEF_INDEX,
});
self.populate_module_if_necessary(&crate_root);
if let Some(crate_id) = self.crate_loader.maybe_process_path_extern(name,
ident.span)
{
let crate_root = self.get_module(DefId {
krate: crate_id,
index: CRATE_DEF_INDEX,
});
self.populate_module_if_necessary(&crate_root);
suggestions.extend(
self.lookup_import_candidates_from_module(
lookup_name, namespace, crate_root, ident, &filter_fn
)
);
}
None => {}
suggestions.extend(self.lookup_import_candidates_from_module(
lookup_name, namespace, crate_root, ident, &filter_fn));
}
}
}
@ -4515,9 +4499,8 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
-> Option<(Module<'a>, ImportSuggestion)>
{
let mut result = None;
let mut worklist = Vec::new();
let mut seen_modules = FxHashSet();
worklist.push((self.graph_root, Vec::new()));
let mut worklist = vec![(self.graph_root, Vec::new())];
while let Some((in_module, path_segments)) = worklist.pop() {
// abort if the module is already found

View File

@ -203,9 +203,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
self.current_module = invocation.module.get();
self.current_module.unresolved_invocations.borrow_mut().remove(&mark);
self.current_module.unresolved_invocations.borrow_mut().extend(derives);
for &derive in derives {
self.invocations.insert(derive, invocation);
}
self.invocations.extend(derives.iter().map(|&derive| (derive, invocation)));
let mut visitor = BuildReducedGraphVisitor {
resolver: self,
current_legacy_scope: invocation.parent_legacy_scope.get(),
@ -277,11 +275,12 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
if traits.is_empty() {
attrs.remove(i);
} else {
let mut tokens = Vec::new();
let mut tokens = Vec::with_capacity(traits.len() - 1);
for (j, path) in traits.iter().enumerate() {
if j > 0 {
tokens.push(TokenTree::Token(attrs[i].span, Token::Comma).into());
}
tokens.reserve((path.segments.len() * 2).saturating_sub(1));
for (k, segment) in path.segments.iter().enumerate() {
if k > 0 {
tokens.push(TokenTree::Token(path.span, Token::ModSep).into());

View File

@ -672,7 +672,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
};
let has_explicit_self =
import.module_path.len() > 0 &&
!import.module_path.is_empty() &&
import.module_path[0].name == keywords::SelfValue.name();
self.per_ns(|_, ns| {
@ -703,9 +703,8 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
if let SingleImport { source, ref result, .. } = import.subclass {
if source.name == "self" {
// Silence `unresolved import` error if E0429 is already emitted
match result.value_ns.get() {
Err(Determined) => continue,
_ => {},
if let Err(Determined) = result.value_ns.get() {
continue;
}
}
}
@ -822,20 +821,19 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
fn throw_unresolved_import_error(&self, error_vec: Vec<(Span, String, String)>,
span: Option<MultiSpan>) {
let max_span_label_msg_count = 10; // upper limit on number of span_label message.
let (span,msg) = match error_vec.is_empty() {
true => (span.unwrap(), "unresolved import".to_string()),
false => {
let span = MultiSpan::from_spans(error_vec.clone().into_iter()
.map(|elem: (Span, String, String)| { elem.0 }
).collect());
let path_vec: Vec<String> = error_vec.clone().into_iter()
.map(|elem: (Span, String, String)| { format!("`{}`", elem.1) }
).collect();
let path = path_vec.join(", ");
let msg = format!("unresolved import{} {}",
if path_vec.len() > 1 { "s" } else { "" }, path);
(span, msg)
}
let (span, msg) = if error_vec.is_empty() {
(span.unwrap(), "unresolved import".to_string())
} else {
let span = MultiSpan::from_spans(error_vec.clone().into_iter()
.map(|elem: (Span, String, String)| { elem.0 })
.collect());
let path_vec: Vec<String> = error_vec.clone().into_iter()
.map(|elem: (Span, String, String)| { format!("`{}`", elem.1) })
.collect();
let path = path_vec.join(", ");
let msg = format!("unresolved import{} {}",
if path_vec.len() > 1 { "s" } else { "" }, path);
(span, msg)
};
let mut err = struct_span_err!(self.resolver.session, span, E0432, "{}", &msg);
for span_error in error_vec.into_iter().take(max_span_label_msg_count) {
@ -1026,9 +1024,8 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
if all_ns_err {
let mut all_ns_failed = true;
self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
match this.resolve_ident_in_module(module, ident, ns, record_used, span) {
Ok(_) => all_ns_failed = false,
_ => {}
if this.resolve_ident_in_module(module, ident, ns, record_used, span).is_ok() {
all_ns_failed = false;
}
});
@ -1247,65 +1244,62 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
}
}
match binding.kind {
NameBindingKind::Import { binding: orig_binding, directive, .. } => {
if ns == TypeNS && orig_binding.is_variant() &&
!orig_binding.vis.is_at_least(binding.vis, &*self) {
let msg = match directive.subclass {
ImportDirectiveSubclass::SingleImport { .. } => {
format!("variant `{}` is private and cannot be re-exported",
ident)
},
ImportDirectiveSubclass::GlobImport { .. } => {
let msg = "enum is private and its variants \
cannot be re-exported".to_owned();
let error_id = (DiagnosticMessageId::ErrorId(0), // no code?!
Some(binding.span),
msg.clone());
let fresh = self.session.one_time_diagnostics
.borrow_mut().insert(error_id);
if !fresh {
continue;
}
msg
},
ref s @ _ => bug!("unexpected import subclass {:?}", s)
};
let mut err = self.session.struct_span_err(binding.span, &msg);
if let NameBindingKind::Import { binding: orig_binding, directive, .. } = binding.kind {
if ns == TypeNS && orig_binding.is_variant() &&
!orig_binding.vis.is_at_least(binding.vis, &*self) {
let msg = match directive.subclass {
ImportDirectiveSubclass::SingleImport { .. } => {
format!("variant `{}` is private and cannot be re-exported",
ident)
},
ImportDirectiveSubclass::GlobImport { .. } => {
let msg = "enum is private and its variants \
cannot be re-exported".to_owned();
let error_id = (DiagnosticMessageId::ErrorId(0), // no code?!
Some(binding.span),
msg.clone());
let fresh = self.session.one_time_diagnostics
.borrow_mut().insert(error_id);
if !fresh {
continue;
}
msg
},
ref s @ _ => bug!("unexpected import subclass {:?}", s)
};
let mut err = self.session.struct_span_err(binding.span, &msg);
let imported_module = match directive.imported_module.get() {
Some(ModuleOrUniformRoot::Module(module)) => module,
_ => bug!("module should exist"),
};
let resolutions = imported_module.parent.expect("parent should exist")
.resolutions.borrow();
let enum_path_segment_index = directive.module_path.len() - 1;
let enum_ident = directive.module_path[enum_path_segment_index];
let imported_module = match directive.imported_module.get() {
Some(ModuleOrUniformRoot::Module(module)) => module,
_ => bug!("module should exist"),
};
let resolutions = imported_module.parent.expect("parent should exist")
.resolutions.borrow();
let enum_path_segment_index = directive.module_path.len() - 1;
let enum_ident = directive.module_path[enum_path_segment_index];
let enum_resolution = resolutions.get(&(enum_ident, TypeNS))
.expect("resolution should exist");
let enum_span = enum_resolution.borrow()
.binding.expect("binding should exist")
.span;
let enum_def_span = self.session.source_map().def_span(enum_span);
let enum_def_snippet = self.session.source_map()
.span_to_snippet(enum_def_span).expect("snippet should exist");
// potentially need to strip extant `crate`/`pub(path)` for suggestion
let after_vis_index = enum_def_snippet.find("enum")
.expect("`enum` keyword should exist in snippet");
let suggestion = format!("pub {}",
&enum_def_snippet[after_vis_index..]);
let enum_resolution = resolutions.get(&(enum_ident, TypeNS))
.expect("resolution should exist");
let enum_span = enum_resolution.borrow()
.binding.expect("binding should exist")
.span;
let enum_def_span = self.session.source_map().def_span(enum_span);
let enum_def_snippet = self.session.source_map()
.span_to_snippet(enum_def_span).expect("snippet should exist");
// potentially need to strip extant `crate`/`pub(path)` for suggestion
let after_vis_index = enum_def_snippet.find("enum")
.expect("`enum` keyword should exist in snippet");
let suggestion = format!("pub {}",
&enum_def_snippet[after_vis_index..]);
self.session
.diag_span_suggestion_once(&mut err,
DiagnosticMessageId::ErrorId(0),
enum_def_span,
"consider making the enum public",
suggestion);
err.emit();
}
self.session
.diag_span_suggestion_once(&mut err,
DiagnosticMessageId::ErrorId(0),
enum_def_span,
"consider making the enum public",
suggestion);
err.emit();
}
_ => {}
}
}

View File

@ -198,6 +198,35 @@ impl f32 {
}
}
/// Returns a number composed of the magnitude of one number and the sign of
/// another.
///
/// Equal to `self` if the sign of `self` and `y` are the same, otherwise
/// equal to `-y`. If `self` is a `NAN`, then a `NAN` with the sign of `y`
/// is returned.
///
/// # Examples
///
/// ```
/// #![feature(copysign)]
/// use std::f32;
///
/// let f = 3.5_f32;
///
/// assert_eq!(f.copysign(0.42), 3.5_f32);
/// assert_eq!(f.copysign(-0.42), -3.5_f32);
/// assert_eq!((-f).copysign(0.42), 3.5_f32);
/// assert_eq!((-f).copysign(-0.42), -3.5_f32);
///
/// assert!(f32::NAN.copysign(1.0).is_nan());
/// ```
#[inline]
#[must_use]
#[unstable(feature="copysign", issue="55169")]
pub fn copysign(self, y: f32) -> f32 {
unsafe { intrinsics::copysignf32(self, y) }
}
/// Fused multiply-add. Computes `(self * a) + b` with only one rounding
/// error, yielding a more accurate result than an unfused multiply-add.
///

View File

@ -176,6 +176,35 @@ impl f64 {
}
}
/// Returns a number composed of the magnitude of one number and the sign of
/// another.
///
/// Equal to `self` if the sign of `self` and `y` are the same, otherwise
/// equal to `-y`. If `self` is a `NAN`, then a `NAN` with the sign of `y`
/// is returned.
///
/// # Examples
///
/// ```
/// #![feature(copysign)]
/// use std::f64;
///
/// let f = 3.5_f64;
///
/// assert_eq!(f.copysign(0.42), 3.5_f64);
/// assert_eq!(f.copysign(-0.42), -3.5_f64);
/// assert_eq!((-f).copysign(0.42), 3.5_f64);
/// assert_eq!((-f).copysign(-0.42), -3.5_f64);
///
/// assert!(f64::NAN.copysign(1.0).is_nan());
/// ```
#[inline]
#[must_use]
#[unstable(feature="copysign", issue="55169")]
pub fn copysign(self, y: f64) -> f64 {
unsafe { intrinsics::copysignf64(self, y) }
}
/// Fused multiply-add. Computes `(self * a) + b` with only one rounding
/// error, yielding a more accurate result than an unfused multiply-add.
///

View File

@ -0,0 +1,5 @@
const fn foo(a: i32) -> Vec<i32> {
vec![1, 2, 3] //~ ERROR heap allocations are not allowed in const fn
}
fn main() {}

View File

@ -0,0 +1,10 @@
error: heap allocations are not allowed in const fn
--> $DIR/bad_const_fn_body_ice.rs:2:5
|
LL | vec![1, 2, 3] //~ ERROR heap allocations are not allowed in const fn
| ^^^^^^^^^^^^^
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
error: aborting due to previous error

View File

@ -0,0 +1,14 @@
fn main() {}
const fn unsize(x: &[u8; 3]) -> &[u8] { x }
//~^ ERROR unsizing casts are not allowed in const fn
const fn closure() -> fn() { || {} }
//~^ ERROR function pointers in const fn are unstable
const fn closure2() {
(|| {}) as fn();
//~^ ERROR function pointers in const fn are unstable
}
const fn reify(f: fn()) -> unsafe fn() { f }
//~^ ERROR function pointers in const fn are unstable
const fn reify2() { main as unsafe fn(); }
//~^ ERROR function pointers in const fn are unstable

View File

@ -0,0 +1,32 @@
error: unsizing casts are not allowed in const fn
--> $DIR/cast_errors.rs:3:41
|
LL | const fn unsize(x: &[u8; 3]) -> &[u8] { x }
| ^
error: function pointers in const fn are unstable
--> $DIR/cast_errors.rs:5:23
|
LL | const fn closure() -> fn() { || {} }
| ^^^^
error: function pointers in const fn are unstable
--> $DIR/cast_errors.rs:8:5
|
LL | (|| {}) as fn();
| ^^^^^^^^^^^^^^^
error: function pointers in const fn are unstable
--> $DIR/cast_errors.rs:11:28
|
LL | const fn reify(f: fn()) -> unsafe fn() { f }
| ^^^^^^^^^^^
error: function pointers in const fn are unstable
--> $DIR/cast_errors.rs:13:21
|
LL | const fn reify2() { main as unsafe fn(); }
| ^^^^^^^^^^^^^^^^^^^
error: aborting due to 5 previous errors

View File

@ -0,0 +1,12 @@
error[E0621]: explicit lifetime required in the type of `x`
--> $DIR/generator-region-requirements.rs:15:51
|
LL | fn dangle(x: &mut i32) -> &'static mut i32 {
| -------- help: add explicit lifetime `'static` to the type of `x`: `&'static mut i32`
...
LL | GeneratorState::Complete(c) => return c,
| ^ lifetime `'static` required
error: aborting due to previous error
For more information about this error, try `rustc --explain E0621`.

View File

@ -0,0 +1,12 @@
error[E0621]: explicit lifetime required in the type of `x`
--> $DIR/generator-region-requirements.rs:11:9
|
LL | fn dangle(x: &mut i32) -> &'static mut i32 {
| -------- help: add explicit lifetime `'static` to the type of `x`: `&'static mut i32`
...
LL | x
| ^ lifetime `'static` required
error: aborting due to previous error
For more information about this error, try `rustc --explain E0621`.

View File

@ -0,0 +1,21 @@
// revisions: ast nll
// ignore-compare-mode-nll
#![feature(generators, generator_trait)]
#![cfg_attr(nll, feature(nll))]
use std::ops::{Generator, GeneratorState};
fn dangle(x: &mut i32) -> &'static mut i32 {
let mut g = || {
yield;
x
};
loop {
match unsafe { g.resume() } {
GeneratorState::Complete(c) => return c,
GeneratorState::Yielded(_) => (),
}
}
}
fn main() {}

View File

@ -0,0 +1,9 @@
// run-pass
#![deny(unused_parens)]
#![allow(unreachable_code)]
fn main() {
match (return) {} // ok
if (return) {} // ok
}