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:
bors 2019-12-28 00:18:59 +00:00
commit 3a087ad3a9
46 changed files with 267 additions and 174 deletions

View File

@ -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>

View File

@ -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

View File

@ -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",
]

View File

@ -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

View File

@ -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

View File

@ -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;
```

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
}
}

View File

@ -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;

View File

@ -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.

View File

@ -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 {

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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)
}

View File

@ -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(

View File

@ -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> {

View File

@ -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.

View File

@ -15,7 +15,6 @@
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(nll)]
#![feature(matches_macro)]
#![recursion_limit = "256"]
#[macro_use]

View File

@ -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

View File

@ -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]

View File

@ -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() {

View File

@ -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

View File

@ -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

View File

@ -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.
///

View File

@ -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)]

View File

@ -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]) }
}

View File

@ -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

View File

@ -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

View File

@ -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)]

View File

@ -379,6 +379,8 @@ symbols! {
infer_static_outlives_requirements,
inline,
intel,
into_future,
IntoFuture,
into_iter,
IntoIterator,
into_result,

View File

@ -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()));
}

View 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() {}

View File

@ -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

View 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);
}

View 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
}
}