mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +00:00
Auto merge of #67670 - oli-obk:rollup-2dp08sd, r=oli-obk
Rollup of 15 pull requests Successful merges: - #65244 (add IntoFuture trait and support for await) - #67576 (reuse `capacity` variable in slice::repeat) - #67588 (Use NonNull in slice::Iter and slice::IterMut.) - #67594 (Update libc to 0.2.66) - #67602 (Use issue = "none" instead of "0" in intrinsics) - #67604 (Add Scalar::to_(u|i)16 methods) - #67617 (Remove `compiler_builtins_lib` documentation) - #67621 (Use the correct type for static qualifs) - #67629 (Remove redundant link texts) - #67632 (Convert collapsed to shortcut reference links) - #67633 (Update .mailmap) - #67635 (Document safety of Path casting) - #67654 (Add regression test for old NLL ICE) - #67659 (Stabilize the `matches!` macro) - #67664 (Fix some mailmap entries) Failed merges: r? @ghost
This commit is contained in:
commit
3a087ad3a9
11
.mailmap
11
.mailmap
@ -54,9 +54,10 @@ Chris C Cerami <chrisccerami@users.noreply.github.com> Chris C Cerami <chrisccer
|
||||
Chris Pressey <cpressey@gmail.com>
|
||||
Chris Thorn <chris@thorn.co> Chris Thorn <thorn@thoughtbot.com>
|
||||
Chris Vittal <christopher.vittal@gmail.com> Christopher Vittal <christopher.vittal@gmail.com>
|
||||
Christian Poveda <christianpoveda@protonmail.com> <cn.poveda.ruiz@gmail.com>
|
||||
Christian Poveda <christianpoveda@protonmail.com> <z1mvader@protonmail.com>
|
||||
Christian Poveda <christianpoveda@protonmail.com> <cpovedar@fnal.gov>
|
||||
Christian Poveda <git@christianpoveda.xyz> <christianpoveda@protonmail.com>
|
||||
Christian Poveda <git@christianpoveda.xyz> <cn.poveda.ruiz@gmail.com>
|
||||
Christian Poveda <git@christianpoveda.xyz> <z1mvader@protonmail.com>
|
||||
Christian Poveda <git@christianpoveda.xyz> <cpovedar@fnal.gov>
|
||||
Clark Gaebel <cg.wowus.cg@gmail.com> <cgaebel@mozilla.com>
|
||||
Clinton Ryan <clint.ryan3@gmail.com>
|
||||
Corey Richardson <corey@octayn.net> Elaine "See More" Nemo <corey@octayn.net>
|
||||
@ -154,6 +155,7 @@ Lindsey Kuper <lindsey@composition.al> <lkuper@mozilla.com>
|
||||
Luke Metz <luke.metz@students.olin.edu>
|
||||
Luqman Aden <me@luqman.ca> <laden@csclub.uwaterloo.ca>
|
||||
Luqman Aden <me@luqman.ca> <laden@mozilla.com>
|
||||
Manish Goregaokar <manishsmail@gmail.com>
|
||||
Marcell Pardavi <marcell.pardavi@gmail.com>
|
||||
Margaret Meyerhofer <mmeyerho@andrew.cmu.edu> <mmeyerho@andrew>
|
||||
Mark Rousskov <mark.simulacrum@gmail.com>
|
||||
@ -185,6 +187,7 @@ Neil Pankey <npankey@gmail.com> <neil@wire.im>
|
||||
Nick Platt <platt.nicholas@gmail.com>
|
||||
Nicole Mazzuca <npmazzuca@gmail.com>
|
||||
Nif Ward <nif.ward@gmail.com>
|
||||
Nika Layzell <michael@thelayzells.com>
|
||||
Oliver Middleton <olliemail27@gmail.com> <ollie27@users.noreply.github.com>
|
||||
Oliver Scherer <oliver.schneider@kit.edu> <git-spam-no-reply9815368754983@oli-obk.de>
|
||||
Oliver Scherer <oliver.schneider@kit.edu> <git-spam9815368754983@oli-obk.de>
|
||||
@ -204,7 +207,6 @@ Paul Faria <paul_faria@ultimatesoftware.com> Paul Faria <Nashenas88@gmail.com>
|
||||
Peer Aramillo Irizar <peer.aramillo.irizar@gmail.com> parir <peer.aramillo.irizar@gmail.com>
|
||||
Peter Elmers <peter.elmers@yahoo.com> <peter.elmers@rice.edu>
|
||||
Peter Liniker <peter.liniker+github@gmail.com>
|
||||
Peter Zotov <whitequark@whitequark.org>
|
||||
Phil Dawes <phil@phildawes.net> Phil Dawes <pdawes@drw.com>
|
||||
Philipp Brüschweiler <blei42@gmail.com> <blei42@gmail.com>
|
||||
Philipp Brüschweiler <blei42@gmail.com> <bruphili@student.ethz.ch>
|
||||
@ -255,6 +257,7 @@ Ulrik Sverdrup <bluss@users.noreply.github.com> Ulrik Sverdrup <root@localhost>
|
||||
Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
|
||||
Vadim Petrochenkov <vadim.petrochenkov@gmail.com> petrochenkov <vadim.petrochenkov@gmail.com>
|
||||
Vitali Haravy <HumaneProgrammer@gmail.com> Vitali Haravy <humaneprogrammer@gmail.com>
|
||||
whitequark <whitequark@whitequark.org>
|
||||
William Ting <io@williamting.com> <william.h.ting@gmail.com>
|
||||
Xuefeng Wu <benewu@gmail.com> Xuefeng Wu <xfwu@thoughtworks.com>
|
||||
Xuefeng Wu <benewu@gmail.com> XuefengWu <benewu@gmail.com>
|
||||
|
@ -367,7 +367,7 @@ labels to triage issues:
|
||||
to fix the issue.
|
||||
|
||||
* The dark blue **final-comment-period** label marks bugs that are using the
|
||||
RFC signoff functionality of [rfcbot][rfcbot] and are currently in the final
|
||||
RFC signoff functionality of [rfcbot] and are currently in the final
|
||||
comment period.
|
||||
|
||||
* Red, **I**-prefixed labels indicate the **importance** of the issue. The
|
||||
@ -385,7 +385,7 @@ labels to triage issues:
|
||||
label.
|
||||
|
||||
* The gray **proposed-final-comment-period** label marks bugs that are using
|
||||
the RFC signoff functionality of [rfcbot][rfcbot] and are currently awaiting
|
||||
the RFC signoff functionality of [rfcbot] and are currently awaiting
|
||||
signoff of all team members in order to enter the final comment period.
|
||||
|
||||
* Pink, **regression**-prefixed labels track regressions from stable to the
|
||||
|
@ -1773,9 +1773,9 @@ checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.64"
|
||||
version = "0.2.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74dfca3d9957906e8d1e6a0b641dc9a59848e793f1da2165889fd4f62d10d79c"
|
||||
checksum = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
|
||||
dependencies = [
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
28
RELEASES.md
28
RELEASES.md
@ -4951,10 +4951,10 @@ Stabilized APIs
|
||||
---------------
|
||||
|
||||
* [`std::panic`]
|
||||
* [`std::panic::catch_unwind`][] (renamed from `recover`)
|
||||
* [`std::panic::resume_unwind`][] (renamed from `propagate`)
|
||||
* [`std::panic::AssertUnwindSafe`][] (renamed from `AssertRecoverSafe`)
|
||||
* [`std::panic::UnwindSafe`][] (renamed from `RecoverSafe`)
|
||||
* [`std::panic::catch_unwind`] (renamed from `recover`)
|
||||
* [`std::panic::resume_unwind`] (renamed from `propagate`)
|
||||
* [`std::panic::AssertUnwindSafe`] (renamed from `AssertRecoverSafe`)
|
||||
* [`std::panic::UnwindSafe`] (renamed from `RecoverSafe`)
|
||||
* [`str::is_char_boundary`]
|
||||
* [`<*const T>::as_ref`]
|
||||
* [`<*mut T>::as_ref`]
|
||||
@ -5234,18 +5234,18 @@ Libraries
|
||||
---------
|
||||
|
||||
* Stabilized APIs:
|
||||
* [`str::encode_utf16`][] (renamed from `utf16_units`)
|
||||
* [`str::EncodeUtf16`][] (renamed from `Utf16Units`)
|
||||
* [`str::encode_utf16`] (renamed from `utf16_units`)
|
||||
* [`str::EncodeUtf16`] (renamed from `Utf16Units`)
|
||||
* [`Ref::map`]
|
||||
* [`RefMut::map`]
|
||||
* [`ptr::drop_in_place`]
|
||||
* [`time::Instant`]
|
||||
* [`time::SystemTime`]
|
||||
* [`Instant::now`]
|
||||
* [`Instant::duration_since`][] (renamed from `duration_from_earlier`)
|
||||
* [`Instant::duration_since`] (renamed from `duration_from_earlier`)
|
||||
* [`Instant::elapsed`]
|
||||
* [`SystemTime::now`]
|
||||
* [`SystemTime::duration_since`][] (renamed from `duration_from_earlier`)
|
||||
* [`SystemTime::duration_since`] (renamed from `duration_from_earlier`)
|
||||
* [`SystemTime::elapsed`]
|
||||
* Various `Add`/`Sub` impls for `Time` and `SystemTime`
|
||||
* [`SystemTimeError`]
|
||||
@ -5432,8 +5432,8 @@ Libraries
|
||||
|
||||
* Stabilized APIs
|
||||
* `Path`
|
||||
* [`Path::strip_prefix`][] (renamed from relative_from)
|
||||
* [`path::StripPrefixError`][] (new error type returned from strip_prefix)
|
||||
* [`Path::strip_prefix`] (renamed from relative_from)
|
||||
* [`path::StripPrefixError`] (new error type returned from strip_prefix)
|
||||
* `Ipv4Addr`
|
||||
* [`Ipv4Addr::is_loopback`]
|
||||
* [`Ipv4Addr::is_private`]
|
||||
@ -5646,7 +5646,7 @@ Libraries
|
||||
|
||||
* Stabilized APIs:
|
||||
[`Read::read_exact`],
|
||||
[`ErrorKind::UnexpectedEof`][] (renamed from `UnexpectedEOF`),
|
||||
[`ErrorKind::UnexpectedEof`] (renamed from `UnexpectedEOF`),
|
||||
[`fs::DirBuilder`], [`fs::DirBuilder::new`],
|
||||
[`fs::DirBuilder::recursive`], [`fs::DirBuilder::create`],
|
||||
[`os::unix::fs::DirBuilderExt`],
|
||||
@ -5659,11 +5659,11 @@ Libraries
|
||||
[`collections::hash_set::HashSet::drain`],
|
||||
[`collections::binary_heap::Drain`],
|
||||
[`collections::binary_heap::BinaryHeap::drain`],
|
||||
[`Vec::extend_from_slice`][] (renamed from `push_all`),
|
||||
[`Vec::extend_from_slice`] (renamed from `push_all`),
|
||||
[`Mutex::get_mut`], [`Mutex::into_inner`], [`RwLock::get_mut`],
|
||||
[`RwLock::into_inner`],
|
||||
[`Iterator::min_by_key`][] (renamed from `min_by`),
|
||||
[`Iterator::max_by_key`][] (renamed from `max_by`).
|
||||
[`Iterator::min_by_key`] (renamed from `min_by`),
|
||||
[`Iterator::max_by_key`] (renamed from `max_by`).
|
||||
* The [core library][1.6co] is stable, as are most of its APIs.
|
||||
* [The `assert_eq!` macro supports arguments that don't implement
|
||||
`Sized`][1.6ae], such as arrays. In this way it behaves more like
|
||||
|
@ -188,11 +188,7 @@ pub extern fn rust_begin_panic(info: &PanicInfo) -> ! {
|
||||
|
||||
In many cases, you may need to manually link to the `compiler_builtins` crate
|
||||
when building a `no_std` binary. You may observe this via linker error messages
|
||||
such as "```undefined reference to `__rust_probestack'```". Using this crate
|
||||
also requires enabling the library feature `compiler_builtins_lib`. You can read
|
||||
more about this [here][compiler-builtins-lib].
|
||||
|
||||
[compiler-builtins-lib]: ../library-features/compiler-builtins-lib.md
|
||||
such as "```undefined reference to `__rust_probestack'```".
|
||||
|
||||
## More about the language items
|
||||
|
||||
|
@ -1,35 +0,0 @@
|
||||
# `compiler_builtins_lib`
|
||||
|
||||
The tracking issue for this feature is: None.
|
||||
|
||||
------------------------
|
||||
|
||||
This feature is required to link to the `compiler_builtins` crate which contains
|
||||
"compiler intrinsics". Compiler intrinsics are software implementations of basic
|
||||
operations like multiplication of `u64`s. These intrinsics are only required on
|
||||
platforms where these operations don't directly map to a hardware instruction.
|
||||
|
||||
You should never need to explicitly link to the `compiler_builtins` crate when
|
||||
building "std" programs as `compiler_builtins` is already in the dependency
|
||||
graph of `std`. But you may need it when building `no_std` **binary** crates. If
|
||||
you get a *linker* error like:
|
||||
|
||||
``` text
|
||||
$PWD/src/main.rs:11: undefined reference to `__aeabi_lmul'
|
||||
$PWD/src/main.rs:11: undefined reference to `__aeabi_uldivmod'
|
||||
```
|
||||
|
||||
That means that you need to link to this crate.
|
||||
|
||||
When you link to this crate, make sure it only appears once in your crate
|
||||
dependency graph. Also, it doesn't matter where in the dependency graph you
|
||||
place the `compiler_builtins` crate.
|
||||
|
||||
<!-- NOTE(ignore) doctests don't support `no_std` binaries -->
|
||||
|
||||
``` rust,ignore
|
||||
#![feature(compiler_builtins_lib)]
|
||||
#![no_std]
|
||||
|
||||
extern crate compiler_builtins;
|
||||
```
|
@ -1094,7 +1094,7 @@ impl<T> FusedIterator for Iter<'_, T> {}
|
||||
|
||||
/// An owning iterator over the elements of a `BinaryHeap`.
|
||||
///
|
||||
/// This `struct` is created by the [`into_iter`] method on [`BinaryHeap`][`BinaryHeap`]
|
||||
/// This `struct` is created by the [`into_iter`] method on [`BinaryHeap`]
|
||||
/// (provided by the `IntoIterator` trait). See its documentation for more.
|
||||
///
|
||||
/// [`into_iter`]: struct.BinaryHeap.html#method.into_iter
|
||||
|
@ -283,7 +283,7 @@ pub struct IterMut<'a, K: 'a, V: 'a> {
|
||||
|
||||
/// An owning iterator over the entries of a `BTreeMap`.
|
||||
///
|
||||
/// This `struct` is created by the [`into_iter`] method on [`BTreeMap`][`BTreeMap`]
|
||||
/// This `struct` is created by the [`into_iter`] method on [`BTreeMap`]
|
||||
/// (provided by the `IntoIterator` trait). See its documentation for more.
|
||||
///
|
||||
/// [`into_iter`]: struct.BTreeMap.html#method.into_iter
|
||||
|
@ -83,7 +83,7 @@ impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> {
|
||||
|
||||
/// An owning iterator over the items of a `BTreeSet`.
|
||||
///
|
||||
/// This `struct` is created by the [`into_iter`] method on [`BTreeSet`][`BTreeSet`]
|
||||
/// This `struct` is created by the [`into_iter`] method on [`BTreeSet`]
|
||||
/// (provided by the `IntoIterator` trait). See its documentation for more.
|
||||
///
|
||||
/// [`BTreeSet`]: struct.BTreeSet.html
|
||||
|
@ -105,7 +105,7 @@ impl<T: fmt::Debug> fmt::Debug for IterMut<'_, T> {
|
||||
|
||||
/// An owning iterator over the elements of a `LinkedList`.
|
||||
///
|
||||
/// This `struct` is created by the [`into_iter`] method on [`LinkedList`][`LinkedList`]
|
||||
/// This `struct` is created by the [`into_iter`] method on [`LinkedList`]
|
||||
/// (provided by the `IntoIterator` trait). See its documentation for more.
|
||||
///
|
||||
/// [`into_iter`]: struct.LinkedList.html#method.into_iter
|
||||
|
@ -2474,7 +2474,7 @@ impl<T> FusedIterator for IterMut<'_, T> {}
|
||||
|
||||
/// An owning iterator over the elements of a `VecDeque`.
|
||||
///
|
||||
/// This `struct` is created by the [`into_iter`] method on [`VecDeque`][`VecDeque`]
|
||||
/// This `struct` is created by the [`into_iter`] method on [`VecDeque`]
|
||||
/// (provided by the `IntoIterator` trait). See its documentation for more.
|
||||
///
|
||||
/// [`into_iter`]: struct.VecDeque.html#method.into_iter
|
||||
|
@ -330,7 +330,7 @@
|
||||
//!
|
||||
//! Additionally, the return value of this function is [`fmt::Result`] which is a
|
||||
//! type alias of [`Result`]`<(), `[`std::fmt::Error`]`>`. Formatting implementations
|
||||
//! should ensure that they propagate errors from the [`Formatter`][`Formatter`] (e.g., when
|
||||
//! should ensure that they propagate errors from the [`Formatter`] (e.g., when
|
||||
//! calling [`write!`]). However, they should never return errors spuriously. That
|
||||
//! is, a formatting implementation must and may only return an error if the
|
||||
//! passed-in [`Formatter`] returns an error. This is because, contrary to what
|
||||
|
@ -450,7 +450,8 @@ impl<T> [T] {
|
||||
// and `rem` is the remaining part of `n`.
|
||||
|
||||
// Using `Vec` to access `set_len()`.
|
||||
let mut buf = Vec::with_capacity(self.len().checked_mul(n).expect("capacity overflow"));
|
||||
let capacity = self.len().checked_mul(n).expect("capacity overflow");
|
||||
let mut buf = Vec::with_capacity(capacity);
|
||||
|
||||
// `2^expn` repetition is done by doubling `buf` `expn`-times.
|
||||
buf.extend(self);
|
||||
@ -476,7 +477,7 @@ impl<T> [T] {
|
||||
|
||||
// `rem` (`= n - 2^expn`) repetition is done by copying
|
||||
// first `rem` repetitions from `buf` itself.
|
||||
let rem_len = self.len() * n - buf.len(); // `self.len() * rem`
|
||||
let rem_len = capacity - buf.len(); // `self.len() * rem`
|
||||
if rem_len > 0 {
|
||||
// `buf.extend(buf[0 .. rem_len])`:
|
||||
unsafe {
|
||||
@ -487,8 +488,7 @@ impl<T> [T] {
|
||||
rem_len,
|
||||
);
|
||||
// `buf.len() + rem_len` equals to `buf.capacity()` (`= self.len() * n`).
|
||||
let buf_cap = buf.capacity();
|
||||
buf.set_len(buf_cap);
|
||||
buf.set_len(capacity);
|
||||
}
|
||||
}
|
||||
buf
|
||||
|
@ -242,7 +242,7 @@ use crate::raw_vec::RawVec;
|
||||
/// ensures no unnecessary allocations or deallocations occur. Emptying a `Vec`
|
||||
/// and then filling it back up to the same [`len`] should incur no calls to
|
||||
/// the allocator. If you wish to free up unused memory, use
|
||||
/// [`shrink_to_fit`][`shrink_to_fit`].
|
||||
/// [`shrink_to_fit`].
|
||||
///
|
||||
/// [`push`] and [`insert`] will never (re)allocate if the reported capacity is
|
||||
/// sufficient. [`push`] and [`insert`] *will* (re)allocate if
|
||||
@ -2461,7 +2461,7 @@ where
|
||||
|
||||
/// An iterator that moves out of a vector.
|
||||
///
|
||||
/// This `struct` is created by the `into_iter` method on [`Vec`][`Vec`] (provided
|
||||
/// This `struct` is created by the `into_iter` method on [`Vec`] (provided
|
||||
/// by the [`IntoIterator`] trait).
|
||||
///
|
||||
/// [`Vec`]: struct.Vec.html
|
||||
|
@ -99,6 +99,21 @@ pub trait Future {
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
|
||||
}
|
||||
|
||||
/// Conversion into a `Future`.
|
||||
#[unstable(feature = "into_future", issue = "67644")]
|
||||
pub trait IntoFuture {
|
||||
/// The output that the future will produce on completion.
|
||||
#[unstable(feature = "into_future", issue = "67644")]
|
||||
type Output;
|
||||
/// Which kind of future are we turning this into?
|
||||
#[unstable(feature = "into_future", issue = "67644")]
|
||||
type Future: Future<Output = Self::Output>;
|
||||
|
||||
/// Creates a future from a value.
|
||||
#[unstable(feature = "into_future", issue = "67644")]
|
||||
fn into_future(self) -> Self::Future;
|
||||
}
|
||||
|
||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
impl<F: ?Sized + Future + Unpin> Future for &mut F {
|
||||
type Output = F::Output;
|
||||
@ -119,3 +134,13 @@ where
|
||||
Pin::get_mut(self).as_mut().poll(cx)
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "into_future", issue = "67644")]
|
||||
impl<F: Future> IntoFuture for F {
|
||||
type Output = F::Output;
|
||||
type Future = F;
|
||||
|
||||
fn into_future(self) -> Self::Future {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
@ -5,3 +5,6 @@
|
||||
mod future;
|
||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
pub use self::future::Future;
|
||||
|
||||
#[unstable(feature = "into_future", issue = "67644")]
|
||||
pub use self::future::IntoFuture;
|
||||
|
@ -697,7 +697,7 @@ extern "rust-intrinsic" {
|
||||
|
||||
#[rustc_const_stable(feature = "const_min_align_of", since = "1.40.0")]
|
||||
pub fn min_align_of<T>() -> usize;
|
||||
#[rustc_const_unstable(feature = "const_pref_align_of", issue = "0")]
|
||||
#[rustc_const_unstable(feature = "const_pref_align_of", issue = "none")]
|
||||
pub fn pref_align_of<T>() -> usize;
|
||||
|
||||
/// The size of the referenced value in bytes.
|
||||
@ -708,13 +708,13 @@ extern "rust-intrinsic" {
|
||||
pub fn min_align_of_val<T: ?Sized>(_: &T) -> usize;
|
||||
|
||||
/// Gets a static string slice containing the name of a type.
|
||||
#[rustc_const_unstable(feature = "const_type_name", issue = "0")]
|
||||
#[rustc_const_unstable(feature = "const_type_name", issue = "none")]
|
||||
pub fn type_name<T: ?Sized>() -> &'static str;
|
||||
|
||||
/// Gets an identifier which is globally unique to the specified type. This
|
||||
/// function will return the same value for a type regardless of whichever
|
||||
/// crate it is invoked in.
|
||||
#[rustc_const_unstable(feature = "const_type_id", issue = "0")]
|
||||
#[rustc_const_unstable(feature = "const_type_id", issue = "none")]
|
||||
pub fn type_id<T: ?Sized + 'static>() -> u64;
|
||||
|
||||
/// A guard for unsafe functions that cannot ever be executed if `T` is uninhabited:
|
||||
@ -1222,7 +1222,7 @@ extern "rust-intrinsic" {
|
||||
/// let num_leading = unsafe { ctlz_nonzero(x) };
|
||||
/// assert_eq!(num_leading, 3);
|
||||
/// ```
|
||||
#[rustc_const_unstable(feature = "constctlz", issue = "0")]
|
||||
#[rustc_const_unstable(feature = "constctlz", issue = "none")]
|
||||
pub fn ctlz_nonzero<T>(x: T) -> T;
|
||||
|
||||
/// Returns the number of trailing unset bits (zeroes) in an integer type `T`.
|
||||
@ -1267,7 +1267,7 @@ extern "rust-intrinsic" {
|
||||
/// let num_trailing = unsafe { cttz_nonzero(x) };
|
||||
/// assert_eq!(num_trailing, 3);
|
||||
/// ```
|
||||
#[rustc_const_unstable(feature = "const_cttz", issue = "0")]
|
||||
#[rustc_const_unstable(feature = "const_cttz", issue = "none")]
|
||||
pub fn cttz_nonzero<T>(x: T) -> T;
|
||||
|
||||
/// Reverses the bytes in an integer type `T`.
|
||||
@ -1396,7 +1396,7 @@ extern "rust-intrinsic" {
|
||||
pub fn nontemporal_store<T>(ptr: *mut T, val: T);
|
||||
|
||||
/// See documentation of `<*const T>::offset_from` for details.
|
||||
#[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "0")]
|
||||
#[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "none")]
|
||||
pub fn ptr_offset_from<T>(ptr: *const T, base: *const T) -> isize;
|
||||
|
||||
/// Internal hook used by Miri to implement unwinding.
|
||||
|
@ -252,8 +252,6 @@ macro_rules! debug_assert_ne {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(matches_macro)]
|
||||
///
|
||||
/// let foo = 'f';
|
||||
/// assert!(matches!(foo, 'A'..='Z' | 'a'..='z'));
|
||||
///
|
||||
@ -261,7 +259,7 @@ macro_rules! debug_assert_ne {
|
||||
/// assert!(matches!(bar, Some(x) if x > 2));
|
||||
/// ```
|
||||
#[macro_export]
|
||||
#[unstable(feature = "matches_macro", issue = "65721")]
|
||||
#[stable(feature = "matches_macro", since = "1.42.0")]
|
||||
macro_rules! matches {
|
||||
($expression:expr, $( $pattern:pat )|+ $( if $guard: expr )?) => {
|
||||
match $expression {
|
||||
|
@ -142,7 +142,7 @@ pub trait Unsize<T: ?Sized> {
|
||||
/// In either of the two scenarios above, we reject usage of such a constant in
|
||||
/// a pattern match.
|
||||
///
|
||||
/// See also the [structural match RFC][RFC1445], and [issue 63438][] which
|
||||
/// See also the [structural match RFC][RFC1445], and [issue 63438] which
|
||||
/// motivated migrating from attribute-based design to this trait.
|
||||
///
|
||||
/// [RFC1445]: https://github.com/rust-lang/rfcs/blob/master/text/1445-restrict-constants-in-patterns.md
|
||||
|
@ -226,7 +226,7 @@ impl f32 {
|
||||
}
|
||||
|
||||
/// Returns `true` if the number is neither zero, infinite,
|
||||
/// [subnormal][subnormal], or `NaN`.
|
||||
/// [subnormal], or `NaN`.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f32;
|
||||
|
@ -226,7 +226,7 @@ impl f64 {
|
||||
}
|
||||
|
||||
/// Returns `true` if the number is neither zero, infinite,
|
||||
/// [subnormal][subnormal], or `NaN`.
|
||||
/// [subnormal], or `NaN`.
|
||||
///
|
||||
/// ```
|
||||
/// use std::f64;
|
||||
|
@ -2,12 +2,12 @@
|
||||
///
|
||||
/// Instances of `Fn` can be called repeatedly without mutating state.
|
||||
///
|
||||
/// *This trait (`Fn`) is not to be confused with [function pointers][]
|
||||
/// *This trait (`Fn`) is not to be confused with [function pointers]
|
||||
/// (`fn`).*
|
||||
///
|
||||
/// `Fn` is implemented automatically by closures which only take immutable
|
||||
/// references to captured variables or don't capture anything at all, as well
|
||||
/// as (safe) [function pointers][] (with some caveats, see their documentation
|
||||
/// as (safe) [function pointers] (with some caveats, see their documentation
|
||||
/// for more details). Additionally, for any type `F` that implements `Fn`, `&F`
|
||||
/// implements `Fn`, too.
|
||||
///
|
||||
@ -78,7 +78,7 @@ pub trait Fn<Args>: FnMut<Args> {
|
||||
///
|
||||
/// `FnMut` is implemented automatically by closures which take mutable
|
||||
/// references to captured variables, as well as all types that implement
|
||||
/// [`Fn`], e.g., (safe) [function pointers][] (since `FnMut` is a supertrait of
|
||||
/// [`Fn`], e.g., (safe) [function pointers] (since `FnMut` is a supertrait of
|
||||
/// [`Fn`]). Additionally, for any type `F` that implements `FnMut`, `&mut F`
|
||||
/// implements `FnMut`, too.
|
||||
///
|
||||
@ -162,7 +162,7 @@ pub trait FnMut<Args>: FnOnce<Args> {
|
||||
///
|
||||
/// `FnOnce` is implemented automatically by closure that might consume captured
|
||||
/// variables, as well as all types that implement [`FnMut`], e.g., (safe)
|
||||
/// [function pointers][] (since `FnOnce` is a supertrait of [`FnMut`]).
|
||||
/// [function pointers] (since `FnOnce` is a supertrait of [`FnMut`]).
|
||||
///
|
||||
/// Since both [`Fn`] and [`FnMut`] are subtraits of `FnOnce`, any instance of
|
||||
/// [`Fn`] or [`FnMut`] can be used where a `FnOnce` is expected.
|
||||
|
@ -1370,7 +1370,7 @@ unsafe impl<A> TrustedLen for IterMut<'_, A> {}
|
||||
/// The iterator yields one value if the result is [`Ok`], otherwise none.
|
||||
///
|
||||
/// This struct is created by the [`into_iter`] method on
|
||||
/// [`Result`][`Result`] (provided by the [`IntoIterator`] trait).
|
||||
/// [`Result`] (provided by the [`IntoIterator`] trait).
|
||||
///
|
||||
/// [`Ok`]: enum.Result.html#variant.Ok
|
||||
/// [`Result`]: enum.Result.html
|
||||
|
@ -34,7 +34,7 @@ use crate::mem;
|
||||
use crate::ops::{self, FnMut, Range};
|
||||
use crate::option::Option;
|
||||
use crate::option::Option::{None, Some};
|
||||
use crate::ptr;
|
||||
use crate::ptr::{self, NonNull};
|
||||
use crate::result::Result;
|
||||
use crate::result::Result::{Err, Ok};
|
||||
|
||||
@ -628,7 +628,7 @@ impl<T> [T] {
|
||||
ptr.add(self.len())
|
||||
};
|
||||
|
||||
Iter { ptr, end, _marker: marker::PhantomData }
|
||||
Iter { ptr: NonNull::new_unchecked(ptr as *mut T), end, _marker: marker::PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
@ -656,7 +656,7 @@ impl<T> [T] {
|
||||
ptr.add(self.len())
|
||||
};
|
||||
|
||||
IterMut { ptr, end, _marker: marker::PhantomData }
|
||||
IterMut { ptr: NonNull::new_unchecked(ptr), end, _marker: marker::PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
@ -3095,7 +3095,7 @@ macro_rules! is_empty {
|
||||
// The way we encode the length of a ZST iterator, this works both for ZST
|
||||
// and non-ZST.
|
||||
($self: ident) => {
|
||||
$self.ptr == $self.end
|
||||
$self.ptr.as_ptr() as *const T == $self.end
|
||||
};
|
||||
}
|
||||
// To get rid of some bounds checks (see `position`), we compute the length in a somewhat
|
||||
@ -3105,17 +3105,17 @@ macro_rules! len {
|
||||
#![allow(unused_unsafe)] // we're sometimes used within an unsafe block
|
||||
|
||||
let start = $self.ptr;
|
||||
let size = size_from_ptr(start);
|
||||
let size = size_from_ptr(start.as_ptr());
|
||||
if size == 0 {
|
||||
// This _cannot_ use `unchecked_sub` because we depend on wrapping
|
||||
// to represent the length of long ZST slice iterators.
|
||||
($self.end as usize).wrapping_sub(start as usize)
|
||||
($self.end as usize).wrapping_sub(start.as_ptr() as usize)
|
||||
} else {
|
||||
// We know that `start <= end`, so can do better than `offset_from`,
|
||||
// which needs to deal in signed. By setting appropriate flags here
|
||||
// we can tell LLVM this, which helps it remove bounds checks.
|
||||
// SAFETY: By the type invariant, `start <= end`
|
||||
let diff = unsafe { unchecked_sub($self.end as usize, start as usize) };
|
||||
let diff = unsafe { unchecked_sub($self.end as usize, start.as_ptr() as usize) };
|
||||
// By also telling LLVM that the pointers are apart by an exact
|
||||
// multiple of the type size, it can optimize `len() == 0` down to
|
||||
// `start == end` instead of `(end - start) < size`.
|
||||
@ -3161,7 +3161,7 @@ macro_rules! iterator {
|
||||
// Helper function for creating a slice from the iterator.
|
||||
#[inline(always)]
|
||||
fn make_slice(&self) -> &'a [T] {
|
||||
unsafe { from_raw_parts(self.ptr, len!(self)) }
|
||||
unsafe { from_raw_parts(self.ptr.as_ptr(), len!(self)) }
|
||||
}
|
||||
|
||||
// Helper function for moving the start of the iterator forwards by `offset` elements,
|
||||
@ -3171,10 +3171,10 @@ macro_rules! iterator {
|
||||
unsafe fn post_inc_start(&mut self, offset: isize) -> * $raw_mut T {
|
||||
if mem::size_of::<T>() == 0 {
|
||||
zst_shrink!(self, offset);
|
||||
self.ptr
|
||||
self.ptr.as_ptr()
|
||||
} else {
|
||||
let old = self.ptr;
|
||||
self.ptr = self.ptr.offset(offset);
|
||||
let old = self.ptr.as_ptr();
|
||||
self.ptr = NonNull::new_unchecked(self.ptr.as_ptr().offset(offset));
|
||||
old
|
||||
}
|
||||
}
|
||||
@ -3186,7 +3186,7 @@ macro_rules! iterator {
|
||||
unsafe fn pre_dec_end(&mut self, offset: isize) -> * $raw_mut T {
|
||||
if mem::size_of::<T>() == 0 {
|
||||
zst_shrink!(self, offset);
|
||||
self.ptr
|
||||
self.ptr.as_ptr()
|
||||
} else {
|
||||
self.end = self.end.offset(-offset);
|
||||
self.end
|
||||
@ -3215,7 +3215,7 @@ macro_rules! iterator {
|
||||
fn next(&mut self) -> Option<$elem> {
|
||||
// could be implemented with slices, but this avoids bounds checks
|
||||
unsafe {
|
||||
assume(!self.ptr.is_null());
|
||||
assume(!self.ptr.as_ptr().is_null());
|
||||
if mem::size_of::<T>() != 0 {
|
||||
assume(!self.end.is_null());
|
||||
}
|
||||
@ -3245,9 +3245,12 @@ macro_rules! iterator {
|
||||
if mem::size_of::<T>() == 0 {
|
||||
// We have to do it this way as `ptr` may never be 0, but `end`
|
||||
// could be (due to wrapping).
|
||||
self.end = self.ptr;
|
||||
self.end = self.ptr.as_ptr();
|
||||
} else {
|
||||
self.ptr = self.end;
|
||||
unsafe {
|
||||
// End can't be 0 if T isn't ZST because ptr isn't 0 and end >= ptr
|
||||
self.ptr = NonNull::new_unchecked(self.end as *mut T);
|
||||
}
|
||||
}
|
||||
return None;
|
||||
}
|
||||
@ -3308,7 +3311,7 @@ macro_rules! iterator {
|
||||
fn next_back(&mut self) -> Option<$elem> {
|
||||
// could be implemented with slices, but this avoids bounds checks
|
||||
unsafe {
|
||||
assume(!self.ptr.is_null());
|
||||
assume(!self.ptr.as_ptr().is_null());
|
||||
if mem::size_of::<T>() != 0 {
|
||||
assume(!self.end.is_null());
|
||||
}
|
||||
@ -3324,7 +3327,7 @@ macro_rules! iterator {
|
||||
fn nth_back(&mut self, n: usize) -> Option<$elem> {
|
||||
if n >= len!(self) {
|
||||
// This iterator is now empty.
|
||||
self.end = self.ptr;
|
||||
self.end = self.ptr.as_ptr();
|
||||
return None;
|
||||
}
|
||||
// We are in bounds. `pre_dec_end` does the right thing even for ZSTs.
|
||||
@ -3365,7 +3368,7 @@ macro_rules! iterator {
|
||||
/// [slices]: ../../std/primitive.slice.html
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct Iter<'a, T: 'a> {
|
||||
ptr: *const T,
|
||||
ptr: NonNull<T>,
|
||||
end: *const T, // If T is a ZST, this is actually ptr+len. This encoding is picked so that
|
||||
// ptr == end is a quick test for the Iterator being empty, that works
|
||||
// for both ZST and non-ZST.
|
||||
@ -3467,7 +3470,7 @@ impl<T> AsRef<[T]> for Iter<'_, T> {
|
||||
/// [slices]: ../../std/primitive.slice.html
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct IterMut<'a, T: 'a> {
|
||||
ptr: *mut T,
|
||||
ptr: NonNull<T>,
|
||||
end: *mut T, // If T is a ZST, this is actually ptr+len. This encoding is picked so that
|
||||
// ptr == end is a quick test for the Iterator being empty, that works
|
||||
// for both ZST and non-ZST.
|
||||
@ -3522,7 +3525,7 @@ impl<'a, T> IterMut<'a, T> {
|
||||
/// ```
|
||||
#[stable(feature = "iter_to_slice", since = "1.4.0")]
|
||||
pub fn into_slice(self) -> &'a mut [T] {
|
||||
unsafe { from_raw_parts_mut(self.ptr, len!(self)) }
|
||||
unsafe { from_raw_parts_mut(self.ptr.as_ptr(), len!(self)) }
|
||||
}
|
||||
|
||||
/// Views the underlying data as a subslice of the original data.
|
||||
@ -5682,7 +5685,7 @@ impl_marker_for!(BytewiseEquality,
|
||||
#[doc(hidden)]
|
||||
unsafe impl<'a, T> TrustedRandomAccess for Iter<'a, T> {
|
||||
unsafe fn get_unchecked(&mut self, i: usize) -> &'a T {
|
||||
&*self.ptr.add(i)
|
||||
&*self.ptr.as_ptr().add(i)
|
||||
}
|
||||
fn may_have_side_effect() -> bool {
|
||||
false
|
||||
@ -5692,7 +5695,7 @@ unsafe impl<'a, T> TrustedRandomAccess for Iter<'a, T> {
|
||||
#[doc(hidden)]
|
||||
unsafe impl<'a, T> TrustedRandomAccess for IterMut<'a, T> {
|
||||
unsafe fn get_unchecked(&mut self, i: usize) -> &'a mut T {
|
||||
&mut *self.ptr.add(i)
|
||||
&mut *self.ptr.as_ptr().add(i)
|
||||
}
|
||||
fn may_have_side_effect() -> bool {
|
||||
false
|
||||
|
@ -168,6 +168,7 @@ pub struct LoweringContext<'a, 'hir: 'a> {
|
||||
|
||||
allow_try_trait: Option<Lrc<[Symbol]>>,
|
||||
allow_gen_future: Option<Lrc<[Symbol]>>,
|
||||
allow_into_future: Option<Lrc<[Symbol]>>,
|
||||
}
|
||||
|
||||
pub trait Resolver {
|
||||
@ -300,6 +301,7 @@ pub fn lower_crate<'a, 'hir>(
|
||||
in_scope_lifetimes: Vec::new(),
|
||||
allow_try_trait: Some([sym::try_trait][..].into()),
|
||||
allow_gen_future: Some([sym::gen_future][..].into()),
|
||||
allow_into_future: Some([sym::into_future][..].into()),
|
||||
}
|
||||
.lower_crate(krate)
|
||||
}
|
||||
|
@ -529,7 +529,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
|
||||
/// Desugar `<expr>.await` into:
|
||||
/// ```rust
|
||||
/// match <expr> {
|
||||
/// match ::std::future::IntoFuture::into_future(<expr>) {
|
||||
/// mut pinned => loop {
|
||||
/// match ::std::future::poll_with_tls_context(unsafe {
|
||||
/// <::std::pin::Pin>::new_unchecked(&mut pinned)
|
||||
@ -653,11 +653,27 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
// mut pinned => loop { ... }
|
||||
let pinned_arm = self.arm(pinned_pat, loop_expr);
|
||||
|
||||
// match <expr> {
|
||||
// `match ::std::future::IntoFuture::into_future(<expr>) { ... }`
|
||||
let into_future_span = self.mark_span_with_reason(
|
||||
DesugaringKind::Await,
|
||||
await_span,
|
||||
self.allow_into_future.clone(),
|
||||
);
|
||||
let expr = self.lower_expr_mut(expr);
|
||||
let into_future_expr = self.expr_call_std_path(
|
||||
into_future_span,
|
||||
&[sym::future, sym::IntoFuture, sym::into_future],
|
||||
arena_vec![self; expr],
|
||||
);
|
||||
|
||||
// match <into_future_expr> {
|
||||
// mut pinned => loop { .. }
|
||||
// }
|
||||
let expr = self.lower_expr(expr);
|
||||
hir::ExprKind::Match(expr, arena_vec![self; pinned_arm], hir::MatchSource::AwaitDesugar)
|
||||
hir::ExprKind::Match(
|
||||
into_future_expr,
|
||||
arena_vec![self; pinned_arm],
|
||||
hir::MatchSource::AwaitDesugar,
|
||||
)
|
||||
}
|
||||
|
||||
fn lower_expr_closure(
|
||||
|
@ -416,22 +416,30 @@ impl<'tcx, Tag> Scalar<Tag> {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_unsigned_with_bit_width(self, bits: u64) -> InterpResult<'static, u128> {
|
||||
let sz = Size::from_bits(bits);
|
||||
self.to_bits(sz)
|
||||
}
|
||||
|
||||
/// Converts the scalar to produce an `u8`. Fails if the scalar is a pointer.
|
||||
pub fn to_u8(self) -> InterpResult<'static, u8> {
|
||||
let sz = Size::from_bits(8);
|
||||
let b = self.to_bits(sz)?;
|
||||
Ok(b as u8)
|
||||
self.to_unsigned_with_bit_width(8).map(|v| v as u8)
|
||||
}
|
||||
|
||||
/// Converts the scalar to produce an `u16`. Fails if the scalar is a pointer.
|
||||
pub fn to_u16(self) -> InterpResult<'static, u16> {
|
||||
self.to_unsigned_with_bit_width(16).map(|v| v as u16)
|
||||
}
|
||||
|
||||
/// Converts the scalar to produce an `u32`. Fails if the scalar is a pointer.
|
||||
pub fn to_u32(self) -> InterpResult<'static, u32> {
|
||||
let sz = Size::from_bits(32);
|
||||
let b = self.to_bits(sz)?;
|
||||
Ok(b as u32)
|
||||
self.to_unsigned_with_bit_width(32).map(|v| v as u32)
|
||||
}
|
||||
|
||||
/// Converts the scalar to produce an `u64`. Fails if the scalar is a pointer.
|
||||
pub fn to_u64(self) -> InterpResult<'static, u64> {
|
||||
let sz = Size::from_bits(64);
|
||||
let b = self.to_bits(sz)?;
|
||||
Ok(b as u64)
|
||||
self.to_unsigned_with_bit_width(64).map(|v| v as u64)
|
||||
}
|
||||
|
||||
pub fn to_machine_usize(self, cx: &impl HasDataLayout) -> InterpResult<'static, u64> {
|
||||
@ -439,25 +447,31 @@ impl<'tcx, Tag> Scalar<Tag> {
|
||||
Ok(b as u64)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_signed_with_bit_width(self, bits: u64) -> InterpResult<'static, i128> {
|
||||
let sz = Size::from_bits(bits);
|
||||
let b = self.to_bits(sz)?;
|
||||
Ok(sign_extend(b, sz) as i128)
|
||||
}
|
||||
|
||||
/// Converts the scalar to produce an `i8`. Fails if the scalar is a pointer.
|
||||
pub fn to_i8(self) -> InterpResult<'static, i8> {
|
||||
let sz = Size::from_bits(8);
|
||||
let b = self.to_bits(sz)?;
|
||||
let b = sign_extend(b, sz) as i128;
|
||||
Ok(b as i8)
|
||||
self.to_signed_with_bit_width(8).map(|v| v as i8)
|
||||
}
|
||||
|
||||
/// Converts the scalar to produce an `i16`. Fails if the scalar is a pointer.
|
||||
pub fn to_i16(self) -> InterpResult<'static, i16> {
|
||||
self.to_signed_with_bit_width(16).map(|v| v as i16)
|
||||
}
|
||||
|
||||
/// Converts the scalar to produce an `i32`. Fails if the scalar is a pointer.
|
||||
pub fn to_i32(self) -> InterpResult<'static, i32> {
|
||||
let sz = Size::from_bits(32);
|
||||
let b = self.to_bits(sz)?;
|
||||
let b = sign_extend(b, sz) as i128;
|
||||
Ok(b as i32)
|
||||
self.to_signed_with_bit_width(32).map(|v| v as i32)
|
||||
}
|
||||
|
||||
/// Converts the scalar to produce an `i64`. Fails if the scalar is a pointer.
|
||||
pub fn to_i64(self) -> InterpResult<'static, i64> {
|
||||
let sz = Size::from_bits(64);
|
||||
let b = self.to_bits(sz)?;
|
||||
let b = sign_extend(b, sz) as i128;
|
||||
Ok(b as i64)
|
||||
self.to_signed_with_bit_width(64).map(|v| v as i64)
|
||||
}
|
||||
|
||||
pub fn to_machine_isize(self, cx: &impl HasDataLayout) -> InterpResult<'static, i64> {
|
||||
|
@ -101,14 +101,14 @@ pub enum ControlFlow<T> {
|
||||
pub enum NodeStatus {
|
||||
/// This node has been examined by the depth-first search but is not yet `Settled`.
|
||||
///
|
||||
/// Also referred to as "gray" or "discovered" nodes in [CLR][].
|
||||
/// Also referred to as "gray" or "discovered" nodes in [CLR].
|
||||
///
|
||||
/// [CLR]: https://en.wikipedia.org/wiki/Introduction_to_Algorithms
|
||||
Visited,
|
||||
|
||||
/// This node and all nodes reachable from it have been examined by the depth-first search.
|
||||
///
|
||||
/// Also referred to as "black" or "finished" nodes in [CLR][].
|
||||
/// Also referred to as "black" or "finished" nodes in [CLR].
|
||||
///
|
||||
/// [CLR]: https://en.wikipedia.org/wiki/Introduction_to_Algorithms
|
||||
Settled,
|
||||
@ -122,13 +122,13 @@ struct Event<N> {
|
||||
/// A depth-first search that also tracks when all successors of a node have been examined.
|
||||
///
|
||||
/// This is based on the DFS described in [Introduction to Algorithms (1st ed.)][CLR], hereby
|
||||
/// referred to as **CLR**. However, we use the terminology in [`NodeStatus`][] above instead of
|
||||
/// referred to as **CLR**. However, we use the terminology in [`NodeStatus`] above instead of
|
||||
/// "discovered"/"finished" or "white"/"grey"/"black". Each node begins the search with no status,
|
||||
/// becomes `Visited` when it is first examined by the DFS and is `Settled` when all nodes
|
||||
/// reachable from it have been examined. This allows us to differentiate between "tree", "back"
|
||||
/// and "forward" edges (see [`TriColorVisitor::node_examined`]).
|
||||
///
|
||||
/// Unlike the pseudocode in [CLR][], this implementation is iterative and does not use timestamps.
|
||||
/// Unlike the pseudocode in [CLR], this implementation is iterative and does not use timestamps.
|
||||
/// We accomplish this by storing `Event`s on the stack that result in a (possible) state change
|
||||
/// for each node. A `Visited` event signifies that we should examine this node if it has not yet
|
||||
/// been `Visited` or `Settled`. When a node is examined for the first time, we mark it as
|
||||
@ -246,7 +246,7 @@ where
|
||||
/// By checking the value of `prior_status`, this visitor can determine whether the edge
|
||||
/// leading to this node was a tree edge (`None`), forward edge (`Some(Settled)`) or back edge
|
||||
/// (`Some(Visited)`). For a full explanation of each edge type, see the "Depth-first Search"
|
||||
/// chapter in [CLR][] or [wikipedia][].
|
||||
/// chapter in [CLR] or [wikipedia].
|
||||
///
|
||||
/// If you want to know *both* nodes linked by each edge, you'll need to modify
|
||||
/// `TriColorDepthFirstSearch` to store a `source` node for each `Visited` event.
|
||||
|
@ -15,7 +15,6 @@
|
||||
#![feature(box_patterns)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(nll)]
|
||||
#![feature(matches_macro)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
#[macro_use]
|
||||
|
@ -10,7 +10,7 @@
|
||||
//! interface, but make `Engine` and `ResultsCursor` the canonical way to perform and inspect a
|
||||
//! dataflow analysis. This requires porting the graphviz debugging logic to this module, deciding
|
||||
//! on a way to handle the `before` methods in `BitDenotation` and creating an adapter so that
|
||||
//! gen-kill problems can still be evaluated efficiently. See the discussion in [#64566][] for more
|
||||
//! gen-kill problems can still be evaluated efficiently. See the discussion in [#64566] for more
|
||||
//! information.
|
||||
//!
|
||||
//! [gk]: https://en.wikipedia.org/wiki/Data-flow_analysis#Bit_vector_problems
|
||||
|
@ -29,7 +29,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
|
||||
#![feature(range_is_empty)]
|
||||
#![feature(stmt_expr_attributes)]
|
||||
#![feature(trait_alias)]
|
||||
#![feature(matches_macro)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
#[macro_use]
|
||||
|
@ -1,6 +1,5 @@
|
||||
//! A copy of the `Qualif` trait in `qualify_consts.rs` that is suitable for the new validator.
|
||||
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::mir::*;
|
||||
use rustc::ty::{self, Ty};
|
||||
use syntax_pos::DUMMY_SP;
|
||||
@ -33,12 +32,6 @@ pub trait Qualif {
|
||||
/// of the type.
|
||||
fn in_any_value_of_ty(_cx: &ConstCx<'_, 'tcx>, _ty: Ty<'tcx>) -> bool;
|
||||
|
||||
fn in_static(cx: &ConstCx<'_, 'tcx>, def_id: DefId) -> bool {
|
||||
// `mir_const_qualif` does return the qualifs in the final value of a `static`, so we could
|
||||
// use value-based qualification here, but we shouldn't do this without a good reason.
|
||||
Self::in_any_value_of_ty(cx, cx.tcx.type_of(def_id))
|
||||
}
|
||||
|
||||
fn in_projection_structurally(
|
||||
cx: &ConstCx<'_, 'tcx>,
|
||||
per_local: &impl Fn(Local) -> bool,
|
||||
@ -101,8 +94,14 @@ pub trait Qualif {
|
||||
}
|
||||
|
||||
Operand::Constant(ref constant) => {
|
||||
if let Some(static_) = constant.check_static_ptr(cx.tcx) {
|
||||
Self::in_static(cx, static_)
|
||||
if constant.check_static_ptr(cx.tcx).is_some() {
|
||||
// `mir_const_qualif` does return the qualifs in the final value of a `static`,
|
||||
// so we could use value-based qualification here, but we shouldn't do this
|
||||
// without a good reason.
|
||||
//
|
||||
// Note: this uses `constant.literal.ty` which is a reference or pointer to the
|
||||
// type of the actual `static` item.
|
||||
Self::in_any_value_of_ty(cx, constant.literal.ty)
|
||||
} else if let ty::ConstKind::Unevaluated(def_id, _) = constant.literal.val {
|
||||
// Don't peek inside trait associated constants.
|
||||
if cx.tcx.trait_of_item(def_id).is_some() {
|
||||
|
@ -1076,7 +1076,7 @@ impl<'a, K, V> IterMut<'a, K, V> {
|
||||
|
||||
/// An owning iterator over the entries of a `HashMap`.
|
||||
///
|
||||
/// This `struct` is created by the [`into_iter`] method on [`HashMap`][`HashMap`]
|
||||
/// This `struct` is created by the [`into_iter`] method on [`HashMap`]
|
||||
/// (provided by the `IntoIterator` trait). See its documentation for more.
|
||||
///
|
||||
/// [`into_iter`]: struct.HashMap.html#method.into_iter
|
||||
|
@ -1101,7 +1101,7 @@ pub struct Iter<'a, K: 'a> {
|
||||
|
||||
/// An owning iterator over the items of a `HashSet`.
|
||||
///
|
||||
/// This `struct` is created by the [`into_iter`] method on [`HashSet`][`HashSet`]
|
||||
/// This `struct` is created by the [`into_iter`] method on [`HashSet`]
|
||||
/// (provided by the `IntoIterator` trait). See its documentation for more.
|
||||
///
|
||||
/// [`HashSet`]: struct.HashSet.html
|
||||
|
@ -10,7 +10,11 @@ use core::task::{Context, Poll};
|
||||
|
||||
#[doc(inline)]
|
||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
pub use core::future::*;
|
||||
pub use core::future::Future;
|
||||
|
||||
#[doc(inline)]
|
||||
#[unstable(feature = "into_future", issue = "67644")]
|
||||
pub use core::future::IntoFuture;
|
||||
|
||||
/// Wrap a generator in a future.
|
||||
///
|
||||
|
@ -269,6 +269,7 @@
|
||||
#![feature(hashmap_internals)]
|
||||
#![feature(int_error_internals)]
|
||||
#![feature(int_error_matching)]
|
||||
#![feature(into_future)]
|
||||
#![feature(integer_atomics)]
|
||||
#![feature(lang_items)]
|
||||
#![feature(libc)]
|
||||
@ -276,7 +277,6 @@
|
||||
#![feature(linkage)]
|
||||
#![feature(log_syntax)]
|
||||
#![feature(manually_drop_take)]
|
||||
#![feature(matches_macro)]
|
||||
#![feature(maybe_uninit_ref)]
|
||||
#![feature(maybe_uninit_slice)]
|
||||
#![feature(needs_panic_runtime)]
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
//! Cross-platform path manipulation.
|
||||
//!
|
||||
//! This module provides two types, [`PathBuf`] and [`Path`][`Path`] (akin to [`String`]
|
||||
//! This module provides two types, [`PathBuf`] and [`Path`] (akin to [`String`]
|
||||
//! and [`str`]), for working with paths abstractly. These types are thin wrappers
|
||||
//! around [`OsString`] and [`OsStr`] respectively, meaning that they work directly
|
||||
//! on strings according to the local platform's path syntax.
|
||||
@ -296,6 +296,13 @@ where
|
||||
}
|
||||
|
||||
// See note at the top of this module to understand why these are used:
|
||||
//
|
||||
// These casts are safe as OsStr is internally a wrapper around [u8] on all
|
||||
// platforms.
|
||||
//
|
||||
// Note that currently this relies on the special knowledge that libstd has;
|
||||
// these types are single-element structs but are not marked repr(transparent)
|
||||
// or repr(C) which would make these casts allowable outside std.
|
||||
fn os_str_as_u8_slice(s: &OsStr) -> &[u8] {
|
||||
unsafe { &*(s as *const OsStr as *const [u8]) }
|
||||
}
|
||||
|
@ -286,7 +286,7 @@ mod sync;
|
||||
|
||||
mod cache_aligned;
|
||||
|
||||
/// The receiving half of Rust's [`channel`][] (or [`sync_channel`]) type.
|
||||
/// The receiving half of Rust's [`channel`] (or [`sync_channel`]) type.
|
||||
/// This half can only be owned by one thread.
|
||||
///
|
||||
/// Messages sent to the channel can be retrieved using [`recv`].
|
||||
@ -558,7 +558,7 @@ pub struct SendError<T>(#[stable(feature = "rust1", since = "1.0.0")] pub T);
|
||||
/// An error returned from the [`recv`] function on a [`Receiver`].
|
||||
///
|
||||
/// The [`recv`] operation can only fail if the sending half of a
|
||||
/// [`channel`][`channel`] (or [`sync_channel`]) is disconnected, implying that no further
|
||||
/// [`channel`] (or [`sync_channel`]) is disconnected, implying that no further
|
||||
/// messages will ever be received.
|
||||
///
|
||||
/// [`recv`]: struct.Receiver.html#method.recv
|
||||
@ -1108,7 +1108,7 @@ impl<T> Receiver<T> {
|
||||
///
|
||||
/// This function will always block the current thread if there is no data
|
||||
/// available and it's possible for more data to be sent. Once a message is
|
||||
/// sent to the corresponding [`Sender`][] (or [`SyncSender`]), then this
|
||||
/// sent to the corresponding [`Sender`] (or [`SyncSender`]), then this
|
||||
/// receiver will wake up and return that message.
|
||||
///
|
||||
/// If the corresponding [`Sender`] has disconnected, or it disconnects while
|
||||
@ -1194,7 +1194,7 @@ impl<T> Receiver<T> {
|
||||
///
|
||||
/// This function will always block the current thread if there is no data
|
||||
/// available and it's possible for more data to be sent. Once a message is
|
||||
/// sent to the corresponding [`Sender`][] (or [`SyncSender`]), then this
|
||||
/// sent to the corresponding [`Sender`] (or [`SyncSender`]), then this
|
||||
/// receiver will wake up and return that message.
|
||||
///
|
||||
/// If the corresponding [`Sender`] has disconnected, or it disconnects while
|
||||
@ -1295,7 +1295,7 @@ impl<T> Receiver<T> {
|
||||
///
|
||||
/// This function will always block the current thread if there is no data
|
||||
/// available and it's possible for more data to be sent. Once a message is
|
||||
/// sent to the corresponding [`Sender`][] (or [`SyncSender`]), then this
|
||||
/// sent to the corresponding [`Sender`] (or [`SyncSender`]), then this
|
||||
/// receiver will wake up and return that message.
|
||||
///
|
||||
/// If the corresponding [`Sender`] has disconnected, or it disconnects while
|
||||
|
@ -25,7 +25,7 @@ use crate::sys_common::rwlock as sys;
|
||||
/// The type parameter `T` represents the data that this lock protects. It is
|
||||
/// required that `T` satisfies [`Send`] to be shared across threads and
|
||||
/// [`Sync`] to allow concurrent access through readers. The RAII guards
|
||||
/// returned from the locking methods implement [`Deref`][] (and [`DerefMut`]
|
||||
/// returned from the locking methods implement [`Deref`] (and [`DerefMut`]
|
||||
/// for the `write` methods) to allow access to the content of the lock.
|
||||
///
|
||||
/// # Poisoning
|
||||
|
@ -11,7 +11,6 @@
|
||||
#![feature(const_transmute)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(label_break_value)]
|
||||
#![feature(matches_macro)]
|
||||
#![feature(nll)]
|
||||
#![feature(try_trait)]
|
||||
#![feature(slice_patterns)]
|
||||
|
@ -379,6 +379,8 @@ symbols! {
|
||||
infer_static_outlives_requirements,
|
||||
inline,
|
||||
intel,
|
||||
into_future,
|
||||
IntoFuture,
|
||||
into_iter,
|
||||
IntoIterator,
|
||||
into_result,
|
||||
|
@ -112,7 +112,7 @@ async fn mixed_sizes() {
|
||||
fn main() {
|
||||
assert_eq!(1028, std::mem::size_of_val(&single()));
|
||||
assert_eq!(1032, std::mem::size_of_val(&single_with_noop()));
|
||||
assert_eq!(3084, std::mem::size_of_val(&joined()));
|
||||
assert_eq!(3084, std::mem::size_of_val(&joined_with_noop()));
|
||||
assert_eq!(7188, std::mem::size_of_val(&mixed_sizes()));
|
||||
assert_eq!(3080, std::mem::size_of_val(&joined()));
|
||||
assert_eq!(3080, std::mem::size_of_val(&joined_with_noop()));
|
||||
assert_eq!(6164, std::mem::size_of_val(&mixed_sizes()));
|
||||
}
|
||||
|
28
src/test/ui/async-await/await-into-future.rs
Normal file
28
src/test/ui/async-await/await-into-future.rs
Normal file
@ -0,0 +1,28 @@
|
||||
// check-pass
|
||||
|
||||
// edition:2018
|
||||
|
||||
#![feature(into_future)]
|
||||
|
||||
use std::{future::{Future, IntoFuture}, pin::Pin};
|
||||
|
||||
struct AwaitMe;
|
||||
|
||||
impl IntoFuture for AwaitMe {
|
||||
type Output = i32;
|
||||
type Future = Pin<Box<dyn Future<Output = i32>>>;
|
||||
|
||||
fn into_future(self) -> Self::Future {
|
||||
Box::pin(me())
|
||||
}
|
||||
}
|
||||
|
||||
async fn me() -> i32 {
|
||||
41
|
||||
}
|
||||
|
||||
async fn run() {
|
||||
assert_eq!(AwaitMe.await, 41);
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -32,11 +32,8 @@ error[E0277]: the trait bound `[closure@$DIR/issue-62009-1.rs:13:5: 13:15]: std:
|
||||
|
|
||||
LL | (|_| 2333).await;
|
||||
| ^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:13:5: 13:15]`
|
||||
|
|
||||
::: $SRC_DIR/libstd/future.rs:LL:COL
|
||||
|
|
||||
LL | F: Future,
|
||||
| ------ required by this bound in `std::future::poll_with_tls_context`
|
||||
= note: required by `std::future::IntoFuture::into_future`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
14
src/test/ui/consts/const-eval/promote-static.rs
Normal file
14
src/test/ui/consts/const-eval/promote-static.rs
Normal file
@ -0,0 +1,14 @@
|
||||
// regression test for #67609.
|
||||
|
||||
// check-pass
|
||||
|
||||
static NONE: Option<String> = None;
|
||||
|
||||
static NONE_REF_REF: &&Option<String> = {
|
||||
let x = &&NONE;
|
||||
x
|
||||
};
|
||||
|
||||
fn main() {
|
||||
println!("{:?}", NONE_REF_REF);
|
||||
}
|
20
src/test/ui/issues/issue-51770.rs
Normal file
20
src/test/ui/issues/issue-51770.rs
Normal file
@ -0,0 +1,20 @@
|
||||
// check-pass
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// In an older version, when NLL was still a feature, the following previously did not compile
|
||||
// #![feature(nll)]
|
||||
|
||||
use std::ops::Index;
|
||||
|
||||
pub struct Test<T> {
|
||||
a: T,
|
||||
}
|
||||
|
||||
impl<T> Index<usize> for Test<T> {
|
||||
type Output = T;
|
||||
|
||||
fn index(&self, _index: usize) -> &Self::Output {
|
||||
&self.a
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user