From e617025e96fa95f074291a1cc284235a80824eaf Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Fri, 5 Apr 2019 14:13:44 -0700 Subject: [PATCH 1/2] Add rustc_allow_const_fn_ptr --- src/librustc/ich/impls_syntax.rs | 1 + src/librustc/middle/stability.rs | 1 + src/librustc/query/mod.rs | 2 ++ src/librustc/ty/constness.rs | 7 +++++++ .../transform/qualify_min_const_fn.rs | 8 ++++++-- src/libsyntax/attr/builtin.rs | 18 ++++++++++++++---- .../consts/min_const_fn/allow_const_fn_ptr.rs | 10 ++++++++++ .../min_const_fn/allow_const_fn_ptr.stderr | 11 +++++++++++ .../allow_const_fn_ptr_feature_gate.rs | 11 +++++++++++ .../allow_const_fn_ptr_feature_gate.stderr | 12 ++++++++++++ .../allow_const_fn_ptr_run_pass.rs | 18 ++++++++++++++++++ 11 files changed, 93 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/consts/min_const_fn/allow_const_fn_ptr.rs create mode 100644 src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr create mode 100644 src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.rs create mode 100644 src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.stderr create mode 100644 src/test/ui/consts/min_const_fn/allow_const_fn_ptr_run_pass.rs diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 496ccc888b61a..40cce8e77c0e0 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -121,6 +121,7 @@ impl_stable_hash_for!(struct ::syntax::attr::Stability { feature, rustc_depr, promotable, + allow_const_fn_ptr, const_stability }); diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index ef1270d304523..8ce86f70a551f 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -441,6 +441,7 @@ impl<'a, 'tcx> Index<'tcx> { rustc_depr: None, const_stability: None, promotable: false, + allow_const_fn_ptr: false, }); annotator.parent_stab = Some(stability); } diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 8c1e345cdaec5..1861420b408b6 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -235,6 +235,8 @@ rustc_queries! { /// constructor function). query is_promotable_const_fn(_: DefId) -> bool {} + query const_fn_is_allowed_fn_ptr(_: DefId) -> bool {} + /// True if this is a foreign item (i.e., linked via `extern { ... }`). query is_foreign_item(_: DefId) -> bool {} diff --git a/src/librustc/ty/constness.rs b/src/librustc/ty/constness.rs index e33d0a74ea013..7298b548f3197 100644 --- a/src/librustc/ty/constness.rs +++ b/src/librustc/ty/constness.rs @@ -95,9 +95,16 @@ pub fn provide<'tcx>(providers: &mut Providers<'tcx>) { } } + fn const_fn_is_allowed_fn_ptr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> bool { + tcx.is_const_fn(def_id) && + tcx.lookup_stability(def_id) + .map(|stab| stab.allow_const_fn_ptr).unwrap_or(false) + } + *providers = Providers { is_const_fn_raw, is_promotable_const_fn, + const_fn_is_allowed_fn_ptr, ..*providers }; } diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index 776985ab79802..d5f04ca64e4c4 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -60,13 +60,14 @@ pub fn is_min_const_fn( } for local in &mir.local_decls { - check_ty(tcx, local.ty, local.source_info.span)?; + check_ty(tcx, local.ty, local.source_info.span, def_id)?; } // impl trait is gone in MIR, so check the return type manually check_ty( tcx, tcx.fn_sig(def_id).output().skip_binder(), mir.local_decls.iter().next().unwrap().source_info.span, + def_id, )?; for bb in mir.basic_blocks() { @@ -82,6 +83,7 @@ fn check_ty( tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: ty::Ty<'tcx>, span: Span, + fn_def_id: DefId, ) -> McfResult { for ty in ty.walk() { match ty.sty { @@ -91,7 +93,9 @@ fn check_ty( )), ty::Opaque(..) => return Err((span, "`impl Trait` in const fn is unstable".into())), ty::FnPtr(..) => { - return Err((span, "function pointers in const fn are unstable".into())) + if !tcx.const_fn_is_allowed_fn_ptr(fn_def_id) { + return Err((span, "function pointers in const fn are unstable".into())) + } } ty::Dynamic(preds, _) => { for pred in preds.iter() { diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index 74c952b076cd7..db821f4e5369d 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -114,6 +114,8 @@ pub struct Stability { pub const_stability: Option, /// whether the function has a `#[rustc_promotable]` attribute pub promotable: bool, + /// whether the function has a `#[rustc_allow_const_fn_ptr]` attribute + pub allow_const_fn_ptr: bool, } /// The available stability levels. @@ -178,6 +180,7 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, let mut rustc_depr: Option = None; let mut rustc_const_unstable: Option = None; let mut promotable = false; + let mut allow_const_fn_ptr = false; let diagnostic = &sess.span_diagnostic; 'outer: for attr in attrs_iter { @@ -187,6 +190,7 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, "unstable", "stable", "rustc_promotable", + "rustc_allow_const_fn_ptr", ].iter().any(|&s| attr.path == s) { continue // not a stability level } @@ -198,6 +202,9 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, if attr.path == "rustc_promotable" { promotable = true; } + if attr.path == "rustc_allow_const_fn_ptr" { + allow_const_fn_ptr = true; + } // attributes with data else if let Some(MetaItem { node: MetaItemKind::List(ref metas), .. }) = meta { let meta = meta.as_ref().unwrap(); @@ -354,6 +361,7 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, rustc_depr: None, const_stability: None, promotable: false, + allow_const_fn_ptr: false, }) } (None, _, _) => { @@ -418,6 +426,7 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, rustc_depr: None, const_stability: None, promotable: false, + allow_const_fn_ptr: false, }) } (None, _) => { @@ -458,13 +467,14 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, } // Merge the const-unstable info into the stability info - if promotable { + if promotable || allow_const_fn_ptr { if let Some(ref mut stab) = stab { - stab.promotable = true; + stab.promotable = promotable; + stab.allow_const_fn_ptr = allow_const_fn_ptr; } else { span_err!(diagnostic, item_sp, E0717, - "rustc_promotable attribute must be paired with \ - either stable or unstable attribute"); + "rustc_promotable and rustc_allow_const_fn_ptr attributes \ + must be paired with either stable or unstable attribute"); } } diff --git a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr.rs b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr.rs new file mode 100644 index 0000000000000..3992607c387e1 --- /dev/null +++ b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr.rs @@ -0,0 +1,10 @@ +#![feature(rustc_attrs, staged_api)] + +#[stable(feature = "rust1", since = "1.0.0")] +const fn error(_: fn()) {} //~ ERROR function pointers in const fn are unstable + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_allow_const_fn_ptr] +const fn compiles(_: fn()) {} + +fn main() {} diff --git a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr new file mode 100644 index 0000000000000..ed9cba9fa2fc4 --- /dev/null +++ b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr @@ -0,0 +1,11 @@ +error[E0723]: function pointers in const fn are unstable (see issue #57563) + --> $DIR/allow_const_fn_ptr.rs:4:16 + | +LL | const fn error(_: fn()) {} + | ^ + | + = help: add #![feature(const_fn)] to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0723`. diff --git a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.rs b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.rs new file mode 100644 index 0000000000000..0395795ef7bfe --- /dev/null +++ b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.rs @@ -0,0 +1,11 @@ +#![feature(staged_api)] + +#[stable(feature = "rust1", since = "1.0.0")] +const fn error(_: fn()) {} + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_allow_const_fn_ptr] +//~^ ERROR unless otherwise specified, attributes with the prefix `rustc_` are reserved +const fn compiles(_: fn()) {} + +fn main() {} diff --git a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.stderr b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.stderr new file mode 100644 index 0000000000000..c934307e918b9 --- /dev/null +++ b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_feature_gate.stderr @@ -0,0 +1,12 @@ +error[E0658]: unless otherwise specified, attributes with the prefix `rustc_` are reserved for internal compiler diagnostics + --> $DIR/allow_const_fn_ptr_feature_gate.rs:7:3 + | +LL | #[rustc_allow_const_fn_ptr] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: for more information, see https://github.com/rust-lang/rust/issues/29642 + = help: add #![feature(rustc_attrs)] to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_run_pass.rs b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_run_pass.rs new file mode 100644 index 0000000000000..1d8b95ab1a2fd --- /dev/null +++ b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr_run_pass.rs @@ -0,0 +1,18 @@ +// run-pass + +#![feature(rustc_attrs, staged_api)] +#![stable(feature = "rust1", since = "1.0.0")] + +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_allow_const_fn_ptr] +const fn takes_fn_ptr(_: fn()) {} + +const FN: fn() = || (); + +const fn gives_fn_ptr() { + takes_fn_ptr(FN) +} + +fn main() { + gives_fn_ptr(); +} From 3f966dcd53faabd8313d29a4e1ba2464995e624a Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Fri, 5 Apr 2019 14:14:19 -0700 Subject: [PATCH 2/2] Stabilize futures_api --- src/liballoc/boxed.rs | 2 +- src/liballoc/lib.rs | 1 - src/libcore/future/future.rs | 9 +++-- src/libcore/future/mod.rs | 5 ++- src/libcore/task/mod.rs | 6 ++-- src/libcore/task/poll.rs | 20 ++++++++--- src/libcore/task/wake.rs | 36 ++++++++++++++----- src/libstd/future.rs | 1 + src/libstd/lib.rs | 10 ++---- src/libstd/panic.rs | 2 +- .../compile-fail/must_use-in-stdlib-traits.rs | 2 +- src/test/run-pass/async-await.rs | 2 +- src/test/run-pass/auxiliary/arc_wake.rs | 2 -- src/test/run-pass/futures-api.rs | 2 -- src/test/run-pass/issue-54716.rs | 2 +- src/test/run-pass/issue-55809.rs | 2 +- src/test/rustdoc/async-fn.rs | 2 +- src/test/ui/async-fn-multiple-lifetimes.rs | 2 +- .../min_const_fn/allow_const_fn_ptr.stderr | 3 +- .../editions/edition-deny-async-fns-2015.rs | 2 +- .../feature-gate-async-await-2015-edition.rs | 2 -- ...ature-gate-async-await-2015-edition.stderr | 8 ++--- .../feature-gates/feature-gate-async-await.rs | 2 -- .../feature-gate-async-await.stderr | 12 +++---- .../recursive-async-impl-trait-type.rs | 2 +- .../impl-trait/recursive-impl-trait-type.rs | 2 +- src/test/ui/issues/issue-54974.rs | 2 +- src/test/ui/issues/issue-55324.rs | 2 +- src/test/ui/issues/issue-58885.rs | 2 +- src/test/ui/issues/issue-59001.rs | 2 +- src/test/ui/no-args-non-move-async-closure.rs | 2 +- src/test/ui/try-poll.rs | 1 - 32 files changed, 86 insertions(+), 66 deletions(-) diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 8a3950718d7d2..207359ed6968f 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -911,7 +911,7 @@ impl Generator for Pin> { } } -#[unstable(feature = "futures_api", issue = "50547")] +#[stable(feature = "futures_api", since = "1.36.0")] impl Future for Box { type Output = F::Output; diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 63b3fbbdaefe1..eb673488170b6 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -85,7 +85,6 @@ #![feature(fmt_internals)] #![feature(fn_traits)] #![feature(fundamental)] -#![feature(futures_api)] #![feature(lang_items)] #![feature(libc)] #![feature(needs_allocator)] diff --git a/src/libcore/future/future.rs b/src/libcore/future/future.rs index e1ab67873a025..504330a023b31 100644 --- a/src/libcore/future/future.rs +++ b/src/libcore/future/future.rs @@ -1,6 +1,4 @@ -#![unstable(feature = "futures_api", - reason = "futures in libcore are unstable", - issue = "50547")] +#![stable(feature = "futures_api", since = "1.36.0")] use crate::marker::Unpin; use crate::ops; @@ -26,8 +24,10 @@ use crate::task::{Context, Poll}; /// `await!` the value. #[doc(spotlight)] #[must_use = "futures do nothing unless polled"] +#[stable(feature = "futures_api", since = "1.36.0")] pub trait Future { /// The type of value produced on completion. + #[stable(feature = "futures_api", since = "1.36.0")] type Output; /// Attempt to resolve the future to a final value, registering @@ -92,9 +92,11 @@ pub trait Future { /// [`Context`]: ../task/struct.Context.html /// [`Waker`]: ../task/struct.Waker.html /// [`Waker::wake`]: ../task/struct.Waker.html#method.wake + #[stable(feature = "futures_api", since = "1.36.0")] fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll; } +#[stable(feature = "futures_api", since = "1.36.0")] impl Future for &mut F { type Output = F::Output; @@ -103,6 +105,7 @@ impl Future for &mut F { } } +#[stable(feature = "futures_api", since = "1.36.0")] impl

Future for Pin

where P: Unpin + ops::DerefMut, diff --git a/src/libcore/future/mod.rs b/src/libcore/future/mod.rs index 6693ecbac41fa..89ea4713cfdaa 100644 --- a/src/libcore/future/mod.rs +++ b/src/libcore/future/mod.rs @@ -1,8 +1,7 @@ -#![unstable(feature = "futures_api", - reason = "futures in libcore are unstable", - issue = "50547")] +#![stable(feature = "futures_api", since = "1.36.0")] //! Asynchronous values. mod future; +#[stable(feature = "futures_api", since = "1.36.0")] pub use self::future::Future; diff --git a/src/libcore/task/mod.rs b/src/libcore/task/mod.rs index 29bae69ea83c1..ef090928392cd 100644 --- a/src/libcore/task/mod.rs +++ b/src/libcore/task/mod.rs @@ -1,11 +1,11 @@ -#![unstable(feature = "futures_api", - reason = "futures in libcore are unstable", - issue = "50547")] +#![stable(feature = "futures_api", since = "1.36.0")] //! Types and Traits for working with asynchronous tasks. mod poll; +#[stable(feature = "futures_api", since = "1.36.0")] pub use self::poll::Poll; mod wake; +#[stable(feature = "futures_api", since = "1.36.0")] pub use self::wake::{Context, Waker, RawWaker, RawWakerVTable}; diff --git a/src/libcore/task/poll.rs b/src/libcore/task/poll.rs index ecf03afb88e2a..3db70d5e7645f 100644 --- a/src/libcore/task/poll.rs +++ b/src/libcore/task/poll.rs @@ -1,6 +1,4 @@ -#![unstable(feature = "futures_api", - reason = "futures in libcore are unstable", - issue = "50547")] +#![stable(feature = "futures_api", since = "1.36.0")] use crate::ops::Try; use crate::result::Result; @@ -9,20 +7,27 @@ use crate::result::Result; /// scheduled to receive a wakeup instead. #[must_use = "this `Poll` may be a `Pending` variant, which should be handled"] #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[stable(feature = "futures_api", since = "1.36.0")] pub enum Poll { /// Represents that a value is immediately ready. - Ready(T), + #[stable(feature = "futures_api", since = "1.36.0")] + Ready( + #[stable(feature = "futures_api", since = "1.36.0")] + T + ), /// Represents that a value is not ready yet. /// /// When a function returns `Pending`, the function *must* also /// ensure that the current task is scheduled to be awoken when /// progress can be made. + #[stable(feature = "futures_api", since = "1.36.0")] Pending, } impl Poll { /// Changes the ready value of this `Poll` with the closure provided. + #[stable(feature = "futures_api", since = "1.36.0")] pub fn map(self, f: F) -> Poll where F: FnOnce(T) -> U { @@ -34,6 +39,7 @@ impl Poll { /// Returns `true` if this is `Poll::Ready` #[inline] + #[stable(feature = "futures_api", since = "1.36.0")] pub fn is_ready(&self) -> bool { match *self { Poll::Ready(_) => true, @@ -43,6 +49,7 @@ impl Poll { /// Returns `true` if this is `Poll::Pending` #[inline] + #[stable(feature = "futures_api", since = "1.36.0")] pub fn is_pending(&self) -> bool { !self.is_ready() } @@ -50,6 +57,7 @@ impl Poll { impl Poll> { /// Changes the success value of this `Poll` with the closure provided. + #[stable(feature = "futures_api", since = "1.36.0")] pub fn map_ok(self, f: F) -> Poll> where F: FnOnce(T) -> U { @@ -61,6 +69,7 @@ impl Poll> { } /// Changes the error value of this `Poll` with the closure provided. + #[stable(feature = "futures_api", since = "1.36.0")] pub fn map_err(self, f: F) -> Poll> where F: FnOnce(E) -> U { @@ -72,12 +81,14 @@ impl Poll> { } } +#[stable(feature = "futures_api", since = "1.36.0")] impl From for Poll { fn from(t: T) -> Poll { Poll::Ready(t) } } +#[stable(feature = "futures_api", since = "1.36.0")] impl Try for Poll> { type Ok = Poll; type Error = E; @@ -102,6 +113,7 @@ impl Try for Poll> { } } +#[stable(feature = "futures_api", since = "1.36.0")] impl Try for Poll>> { type Ok = Poll>; type Error = E; diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs index 94e31054a5812..b4e9124983205 100644 --- a/src/libcore/task/wake.rs +++ b/src/libcore/task/wake.rs @@ -1,6 +1,4 @@ -#![unstable(feature = "futures_api", - reason = "futures in libcore are unstable", - issue = "50547")] +#![stable(feature = "futures_api", since = "1.36.0")] use crate::fmt; use crate::marker::{PhantomData, Unpin}; @@ -13,6 +11,7 @@ use crate::marker::{PhantomData, Unpin}; /// It consists of a data pointer and a [virtual function pointer table (vtable)][vtable] that /// customizes the behavior of the `RawWaker`. #[derive(PartialEq, Debug)] +#[stable(feature = "futures_api", since = "1.36.0")] pub struct RawWaker { /// A data pointer, which can be used to store arbitrary data as required /// by the executor. This could be e.g. a type-erased pointer to an `Arc` @@ -37,9 +36,7 @@ impl RawWaker { /// from a `RawWaker`. For each operation on the `Waker`, the associated /// function in the `vtable` of the underlying `RawWaker` will be called. #[rustc_promotable] - #[unstable(feature = "futures_api", - reason = "futures in libcore are unstable", - issue = "50547")] + #[stable(feature = "futures_api", since = "1.36.0")] pub const fn new(data: *const (), vtable: &'static RawWakerVTable) -> RawWaker { RawWaker { data, @@ -58,6 +55,7 @@ impl RawWaker { /// pointer of a properly constructed [`RawWaker`] object from inside the /// [`RawWaker`] implementation. Calling one of the contained functions using /// any other `data` pointer will cause undefined behavior. +#[stable(feature = "futures_api", since = "1.36.0")] #[derive(PartialEq, Copy, Clone, Debug)] pub struct RawWakerVTable { /// This function will be called when the [`RawWaker`] gets cloned, e.g. when @@ -131,9 +129,14 @@ impl RawWakerVTable { /// resources that are associated with this instance of a [`RawWaker`] and /// associated task. #[rustc_promotable] - #[unstable(feature = "futures_api", - reason = "futures in libcore are unstable", - issue = "50547")] + #[cfg_attr(stage0, unstable(feature = "futures_api_const_fn_ptr", issue = "50547"))] + #[cfg_attr(not(stage0), stable(feature = "futures_api", since = "1.36.0"))] + // `rustc_allow_const_fn_ptr` is a hack that should not be used anywhere else + // without first consulting with T-Lang. + // + // FIXME: remove whenever we have a stable way to accept fn pointers from const fn + // (see https://github.com/rust-rfcs/const-eval/issues/19#issuecomment-472799062) + #[cfg_attr(not(stage0), rustc_allow_const_fn_ptr)] pub const fn new( clone: unsafe fn(*const ()) -> RawWaker, wake: unsafe fn(*const ()), @@ -153,6 +156,7 @@ impl RawWakerVTable { /// /// Currently, `Context` only serves to provide access to a `&Waker` /// which can be used to wake the current task. +#[stable(feature = "futures_api", since = "1.36.0")] pub struct Context<'a> { waker: &'a Waker, // Ensure we future-proof against variance changes by forcing @@ -164,6 +168,7 @@ pub struct Context<'a> { impl<'a> Context<'a> { /// Create a new `Context` from a `&Waker`. + #[stable(feature = "futures_api", since = "1.36.0")] #[inline] pub fn from_waker(waker: &'a Waker) -> Self { Context { @@ -173,12 +178,14 @@ impl<'a> Context<'a> { } /// Returns a reference to the `Waker` for the current task. + #[stable(feature = "futures_api", since = "1.36.0")] #[inline] pub fn waker(&self) -> &'a Waker { &self.waker } } +#[stable(feature = "futures_api", since = "1.36.0")] impl fmt::Debug for Context<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Context") @@ -195,17 +202,22 @@ impl fmt::Debug for Context<'_> { /// /// Implements [`Clone`], [`Send`], and [`Sync`]. #[repr(transparent)] +#[stable(feature = "futures_api", since = "1.36.0")] pub struct Waker { waker: RawWaker, } +#[stable(feature = "futures_api", since = "1.36.0")] impl Unpin for Waker {} +#[stable(feature = "futures_api", since = "1.36.0")] unsafe impl Send for Waker {} +#[stable(feature = "futures_api", since = "1.36.0")] unsafe impl Sync for Waker {} impl Waker { /// Wake up the task associated with this `Waker`. #[inline] + #[stable(feature = "futures_api", since = "1.36.0")] pub fn wake(self) { // The actual wakeup call is delegated through a virtual function call // to the implementation which is defined by the executor. @@ -227,6 +239,7 @@ impl Waker { /// where an owned `Waker` is available. This method should be preferred to /// calling `waker.clone().wake()`. #[inline] + #[stable(feature = "futures_api", since = "1.36.0")] pub fn wake_by_ref(&self) { // The actual wakeup call is delegated through a virtual function call // to the implementation which is defined by the executor. @@ -243,6 +256,7 @@ impl Waker { /// /// This function is primarily used for optimization purposes. #[inline] + #[stable(feature = "futures_api", since = "1.36.0")] pub fn will_wake(&self, other: &Waker) -> bool { self.waker == other.waker } @@ -253,6 +267,7 @@ impl Waker { /// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld. /// Therefore this method is unsafe. #[inline] + #[stable(feature = "futures_api", since = "1.36.0")] pub unsafe fn from_raw(waker: RawWaker) -> Waker { Waker { waker, @@ -260,6 +275,7 @@ impl Waker { } } +#[stable(feature = "futures_api", since = "1.36.0")] impl Clone for Waker { #[inline] fn clone(&self) -> Self { @@ -272,6 +288,7 @@ impl Clone for Waker { } } +#[stable(feature = "futures_api", since = "1.36.0")] impl Drop for Waker { #[inline] fn drop(&mut self) { @@ -282,6 +299,7 @@ impl Drop for Waker { } } +#[stable(feature = "futures_api", since = "1.36.0")] impl fmt::Debug for Waker { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let vtable_ptr = self.waker.vtable as *const RawWakerVTable; diff --git a/src/libstd/future.rs b/src/libstd/future.rs index 898387cb9f56d..c18a314116bf0 100644 --- a/src/libstd/future.rs +++ b/src/libstd/future.rs @@ -9,6 +9,7 @@ use core::task::{Context, Poll}; use core::ops::{Drop, Generator, GeneratorState}; #[doc(inline)] +#[stable(feature = "futures_api", since = "1.36.0")] pub use core::future::*; /// Wrap a generator in a future. diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 62bc1991cc93c..bdec0c347f546 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -263,7 +263,6 @@ #![feature(fixed_size_array)] #![feature(fn_traits)] #![feature(fnbox)] -#![feature(futures_api)] #![feature(generator_trait)] #![feature(hash_raw_entry)] #![feature(hashmap_internals)] @@ -458,18 +457,15 @@ pub mod process; pub mod sync; pub mod time; -#[unstable(feature = "futures_api", - reason = "futures in libcore are unstable", - issue = "50547")] +#[stable(feature = "futures_api", since = "1.36.0")] pub mod task { //! Types and Traits for working with asynchronous tasks. #[doc(inline)] + #[stable(feature = "futures_api", since = "1.36.0")] pub use core::task::*; } -#[unstable(feature = "futures_api", - reason = "futures in libcore are unstable", - issue = "50547")] +#[stable(feature = "futures_api", since = "1.36.0")] pub mod future; // Platform-abstraction modules diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs index 5a8101e230119..7a3b5d30500a9 100644 --- a/src/libstd/panic.rs +++ b/src/libstd/panic.rs @@ -319,7 +319,7 @@ impl fmt::Debug for AssertUnwindSafe { } } -#[unstable(feature = "futures_api", issue = "50547")] +#[stable(feature = "futures_api", since = "1.36.0")] impl Future for AssertUnwindSafe { type Output = F::Output; diff --git a/src/test/compile-fail/must_use-in-stdlib-traits.rs b/src/test/compile-fail/must_use-in-stdlib-traits.rs index 503b39e181ab7..39472ae11fbc5 100644 --- a/src/test/compile-fail/must_use-in-stdlib-traits.rs +++ b/src/test/compile-fail/must_use-in-stdlib-traits.rs @@ -1,5 +1,5 @@ #![deny(unused_must_use)] -#![feature(arbitrary_self_types, futures_api)] +#![feature(arbitrary_self_types)] use std::iter::Iterator; use std::future::Future; diff --git a/src/test/run-pass/async-await.rs b/src/test/run-pass/async-await.rs index 518452aefc152..e1b4328debd9a 100644 --- a/src/test/run-pass/async-await.rs +++ b/src/test/run-pass/async-await.rs @@ -1,7 +1,7 @@ // edition:2018 // aux-build:arc_wake.rs -#![feature(async_await, await_macro, futures_api)] +#![feature(async_await, await_macro)] extern crate arc_wake; diff --git a/src/test/run-pass/auxiliary/arc_wake.rs b/src/test/run-pass/auxiliary/arc_wake.rs index 93e074e7ee55c..c21886f26f467 100644 --- a/src/test/run-pass/auxiliary/arc_wake.rs +++ b/src/test/run-pass/auxiliary/arc_wake.rs @@ -1,7 +1,5 @@ // edition:2018 -#![feature(futures_api)] - use std::sync::Arc; use std::task::{ Waker, RawWaker, RawWakerVTable, diff --git a/src/test/run-pass/futures-api.rs b/src/test/run-pass/futures-api.rs index 6094f15569bb6..ee77053fd5b6a 100644 --- a/src/test/run-pass/futures-api.rs +++ b/src/test/run-pass/futures-api.rs @@ -1,7 +1,5 @@ // aux-build:arc_wake.rs -#![feature(futures_api)] - extern crate arc_wake; use std::future::Future; diff --git a/src/test/run-pass/issue-54716.rs b/src/test/run-pass/issue-54716.rs index ea4f5e076b005..961c412f5ecb2 100644 --- a/src/test/run-pass/issue-54716.rs +++ b/src/test/run-pass/issue-54716.rs @@ -3,7 +3,7 @@ // run-pass #![allow(unused_variables)] -#![feature(async_await, await_macro, futures_api)] +#![feature(async_await, await_macro)] extern crate arc_wake; diff --git a/src/test/run-pass/issue-55809.rs b/src/test/run-pass/issue-55809.rs index 86b0977bebe1d..12be6582a21e8 100644 --- a/src/test/run-pass/issue-55809.rs +++ b/src/test/run-pass/issue-55809.rs @@ -1,7 +1,7 @@ // edition:2018 // run-pass -#![feature(async_await, await_macro, futures_api)] +#![feature(async_await, await_macro)] trait Foo { } diff --git a/src/test/rustdoc/async-fn.rs b/src/test/rustdoc/async-fn.rs index ba4997a7f9b5b..7384f7027d185 100644 --- a/src/test/rustdoc/async-fn.rs +++ b/src/test/rustdoc/async-fn.rs @@ -1,6 +1,6 @@ // edition:2018 -#![feature(async_await, futures_api)] +#![feature(async_await)] // @has async_fn/fn.foo.html '//pre[@class="rust fn"]' 'pub async fn foo() -> Option' pub async fn foo() -> Option { diff --git a/src/test/ui/async-fn-multiple-lifetimes.rs b/src/test/ui/async-fn-multiple-lifetimes.rs index fccc4fdb91725..e3ac817b15ca5 100644 --- a/src/test/ui/async-fn-multiple-lifetimes.rs +++ b/src/test/ui/async-fn-multiple-lifetimes.rs @@ -1,6 +1,6 @@ // edition:2018 -#![feature(arbitrary_self_types, async_await, await_macro, futures_api, pin)] +#![feature(arbitrary_self_types, async_await, await_macro, pin)] use std::ops::Add; diff --git a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr index ed9cba9fa2fc4..e6e1ced6592a2 100644 --- a/src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr +++ b/src/test/ui/consts/min_const_fn/allow_const_fn_ptr.stderr @@ -1,9 +1,10 @@ -error[E0723]: function pointers in const fn are unstable (see issue #57563) +error[E0723]: function pointers in const fn are unstable --> $DIR/allow_const_fn_ptr.rs:4:16 | LL | const fn error(_: fn()) {} | ^ | + = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563 = help: add #![feature(const_fn)] to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/editions/edition-deny-async-fns-2015.rs b/src/test/ui/editions/edition-deny-async-fns-2015.rs index 2105aa5835d0d..e1111f9e0e4b9 100644 --- a/src/test/ui/editions/edition-deny-async-fns-2015.rs +++ b/src/test/ui/editions/edition-deny-async-fns-2015.rs @@ -1,6 +1,6 @@ // edition:2015 -#![feature(futures_api, async_await)] +#![feature(async_await)] async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition diff --git a/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.rs b/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.rs index b6ab8ae0a9bc7..801aeb82aa266 100644 --- a/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.rs +++ b/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.rs @@ -1,7 +1,5 @@ // edition:2015 -#![feature(futures_api)] - async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition //~^ ERROR async fn is unstable diff --git a/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.stderr b/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.stderr index cec211fef1351..b419f1232dfab 100644 --- a/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.stderr +++ b/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.stderr @@ -1,23 +1,23 @@ error[E0670]: `async fn` is not permitted in the 2015 edition - --> $DIR/feature-gate-async-await-2015-edition.rs:5:1 + --> $DIR/feature-gate-async-await-2015-edition.rs:3:1 | LL | async fn foo() {} | ^^^^^ error[E0422]: cannot find struct, variant or union type `async` in this scope - --> $DIR/feature-gate-async-await-2015-edition.rs:9:13 + --> $DIR/feature-gate-async-await-2015-edition.rs:7:13 | LL | let _ = async {}; | ^^^^^ not found in this scope error[E0425]: cannot find value `async` in this scope - --> $DIR/feature-gate-async-await-2015-edition.rs:10:13 + --> $DIR/feature-gate-async-await-2015-edition.rs:8:13 | LL | let _ = async || { true }; | ^^^^^ not found in this scope error[E0658]: async fn is unstable - --> $DIR/feature-gate-async-await-2015-edition.rs:5:1 + --> $DIR/feature-gate-async-await-2015-edition.rs:3:1 | LL | async fn foo() {} | ^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/feature-gates/feature-gate-async-await.rs b/src/test/ui/feature-gates/feature-gate-async-await.rs index 1fdaec75e9d5a..9cfefef4129de 100644 --- a/src/test/ui/feature-gates/feature-gate-async-await.rs +++ b/src/test/ui/feature-gates/feature-gate-async-await.rs @@ -1,7 +1,5 @@ // edition:2018 -#![feature(futures_api)] - struct S; impl S { diff --git a/src/test/ui/feature-gates/feature-gate-async-await.stderr b/src/test/ui/feature-gates/feature-gate-async-await.stderr index 1fa21f52045fc..43e41b4545869 100644 --- a/src/test/ui/feature-gates/feature-gate-async-await.stderr +++ b/src/test/ui/feature-gates/feature-gate-async-await.stderr @@ -1,11 +1,11 @@ error[E0706]: trait fns cannot be declared `async` - --> $DIR/feature-gate-async-await.rs:12:5 + --> $DIR/feature-gate-async-await.rs:10:5 | LL | async fn foo(); | ^^^^^^^^^^^^^^^ error[E0658]: async fn is unstable - --> $DIR/feature-gate-async-await.rs:8:5 + --> $DIR/feature-gate-async-await.rs:6:5 | LL | async fn foo() {} | ^^^^^^^^^^^^^^^^^ @@ -14,7 +14,7 @@ LL | async fn foo() {} = help: add #![feature(async_await)] to the crate attributes to enable error[E0658]: async fn is unstable - --> $DIR/feature-gate-async-await.rs:12:5 + --> $DIR/feature-gate-async-await.rs:10:5 | LL | async fn foo(); | ^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | async fn foo(); = help: add #![feature(async_await)] to the crate attributes to enable error[E0658]: async fn is unstable - --> $DIR/feature-gate-async-await.rs:16:1 + --> $DIR/feature-gate-async-await.rs:14:1 | LL | async fn foo() {} | ^^^^^^^^^^^^^^^^^ @@ -32,7 +32,7 @@ LL | async fn foo() {} = help: add #![feature(async_await)] to the crate attributes to enable error[E0658]: async blocks are unstable - --> $DIR/feature-gate-async-await.rs:19:13 + --> $DIR/feature-gate-async-await.rs:17:13 | LL | let _ = async {}; | ^^^^^^^^ @@ -41,7 +41,7 @@ LL | let _ = async {}; = help: add #![feature(async_await)] to the crate attributes to enable error[E0658]: async closures are unstable - --> $DIR/feature-gate-async-await.rs:20:13 + --> $DIR/feature-gate-async-await.rs:18:13 | LL | let _ = async || {}; | ^^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/recursive-async-impl-trait-type.rs b/src/test/ui/impl-trait/recursive-async-impl-trait-type.rs index 40642523be255..a4e080119345e 100644 --- a/src/test/ui/impl-trait/recursive-async-impl-trait-type.rs +++ b/src/test/ui/impl-trait/recursive-async-impl-trait-type.rs @@ -2,7 +2,7 @@ // Test that impl trait does not allow creating recursive types that are // otherwise forbidden when using `async` and `await`. -#![feature(await_macro, async_await, futures_api, generators)] +#![feature(await_macro, async_await, generators)] async fn recursive_async_function() -> () { //~ ERROR await!(recursive_async_function()); diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type.rs b/src/test/ui/impl-trait/recursive-impl-trait-type.rs index 869876dc6a88a..2428b560b7001 100644 --- a/src/test/ui/impl-trait/recursive-impl-trait-type.rs +++ b/src/test/ui/impl-trait/recursive-impl-trait-type.rs @@ -1,7 +1,7 @@ // Test that impl trait does not allow creating recursive types that are // otherwise forbidden. -#![feature(futures_api, generators)] +#![feature(generators)] fn option(i: i32) -> impl Sized { //~ ERROR if i < 0 { diff --git a/src/test/ui/issues/issue-54974.rs b/src/test/ui/issues/issue-54974.rs index b2624ec92a184..d6f18875c9e3a 100644 --- a/src/test/ui/issues/issue-54974.rs +++ b/src/test/ui/issues/issue-54974.rs @@ -1,7 +1,7 @@ // compile-pass // edition:2018 -#![feature(async_await, await_macro, futures_api)] +#![feature(async_await, await_macro)] use std::sync::Arc; diff --git a/src/test/ui/issues/issue-55324.rs b/src/test/ui/issues/issue-55324.rs index 6160fbabd96d7..4572e543f22de 100644 --- a/src/test/ui/issues/issue-55324.rs +++ b/src/test/ui/issues/issue-55324.rs @@ -1,7 +1,7 @@ // compile-pass // edition:2018 -#![feature(async_await, await_macro, futures_api)] +#![feature(async_await, await_macro)] use std::future::Future; diff --git a/src/test/ui/issues/issue-58885.rs b/src/test/ui/issues/issue-58885.rs index 559899194fbe7..99d87b2273c2f 100644 --- a/src/test/ui/issues/issue-58885.rs +++ b/src/test/ui/issues/issue-58885.rs @@ -1,7 +1,7 @@ // compile-pass // edition:2018 -#![feature(async_await, await_macro, futures_api)] +#![feature(async_await, await_macro)] struct Xyz { a: u64, diff --git a/src/test/ui/issues/issue-59001.rs b/src/test/ui/issues/issue-59001.rs index a310653fbce48..c758244002ff6 100644 --- a/src/test/ui/issues/issue-59001.rs +++ b/src/test/ui/issues/issue-59001.rs @@ -1,7 +1,7 @@ // compile-pass // edition:2018 -#![feature(async_await, await_macro, futures_api)] +#![feature(async_await, await_macro)] use std::future::Future; diff --git a/src/test/ui/no-args-non-move-async-closure.rs b/src/test/ui/no-args-non-move-async-closure.rs index 4f5b2ea3783aa..345f19b06233b 100644 --- a/src/test/ui/no-args-non-move-async-closure.rs +++ b/src/test/ui/no-args-non-move-async-closure.rs @@ -1,6 +1,6 @@ // edition:2018 -#![feature(arbitrary_self_types, async_await, await_macro, futures_api, pin)] +#![feature(async_await, await_macro)] fn main() { let _ = async |x: u8| {}; diff --git a/src/test/ui/try-poll.rs b/src/test/ui/try-poll.rs index 3d7115c522346..f63950ad5e905 100644 --- a/src/test/ui/try-poll.rs +++ b/src/test/ui/try-poll.rs @@ -1,7 +1,6 @@ // compile-pass #![allow(dead_code, unused)] -#![feature(futures_api)] use std::task::Poll;