mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-10 22:13:27 +00:00
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:
commit
74ff7dcb13
126
RELEASES.md
126
RELEASES.md
@ -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/
|
||||
|
@ -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
|
||||
|
||||
|
@ -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};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)]
|
||||
|
@ -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)),
|
||||
|
@ -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) {
|
||||
|
@ -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),
|
||||
);
|
||||
|
@ -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(
|
||||
|
@ -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);
|
||||
});
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
|
@ -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();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
///
|
||||
|
@ -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.
|
||||
///
|
||||
|
5
src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.rs
Normal file
5
src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.rs
Normal 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() {}
|
10
src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr
Normal file
10
src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr
Normal 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
|
||||
|
14
src/test/ui/consts/min_const_fn/cast_errors.rs
Normal file
14
src/test/ui/consts/min_const_fn/cast_errors.rs
Normal 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
|
32
src/test/ui/consts/min_const_fn/cast_errors.stderr
Normal file
32
src/test/ui/consts/min_const_fn/cast_errors.stderr
Normal 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
|
||||
|
@ -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`.
|
@ -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`.
|
21
src/test/ui/generator/generator-region-requirements.rs
Normal file
21
src/test/ui/generator/generator-region-requirements.rs
Normal 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() {}
|
9
src/test/ui/lint/no-unused-parens-return-block.rs
Normal file
9
src/test/ui/lint/no-unused-parens-return-block.rs
Normal file
@ -0,0 +1,9 @@
|
||||
// run-pass
|
||||
|
||||
#![deny(unused_parens)]
|
||||
#![allow(unreachable_code)]
|
||||
|
||||
fn main() {
|
||||
match (return) {} // ok
|
||||
if (return) {} // ok
|
||||
}
|
Loading…
Reference in New Issue
Block a user