diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 3c44acb16577a..7835b5f09b359 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -241,6 +241,9 @@ language_item_table! { FusedIterator, sym::fused_iterator, fused_iterator_trait, Target::Trait, GenericRequirement::Exact(0); Future, sym::future_trait, future_trait, Target::Trait, GenericRequirement::Exact(0); FutureOutput, sym::future_output, future_output, Target::AssocTy, GenericRequirement::Exact(0); + IntoFuture, sym::into_future, into_future_trait, Target::Trait, GenericRequirement::Exact(0); + IntoFutureOutput, sym::into_future_output, into_future_output, Target::AssocTy, GenericRequirement::Exact(0); + IntoFutureIntoFuture, sym::into_future_into_future, into_future_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None; AsyncIterator, sym::async_iterator, async_iterator_trait, Target::Trait, GenericRequirement::Exact(0); CoroutineState, sym::coroutine_state, coroutine_state, Target::Enum, GenericRequirement::None; @@ -377,7 +380,6 @@ language_item_table! { ControlFlowContinue, sym::Continue, cf_continue_variant, Target::Variant, GenericRequirement::None; ControlFlowBreak, sym::Break, cf_break_variant, Target::Variant, GenericRequirement::None; - IntoFutureIntoFuture, sym::into_future, into_future_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None; IntoIterIntoIter, sym::into_iter, into_iter_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None; IteratorNext, sym::next, next_fn, Target::Method(MethodKind::Trait { body: false}), GenericRequirement::None; diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 9225ae6300fc6..e507c609faef6 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -610,6 +610,8 @@ fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem { TraitSolverLangItem::FusedIterator => LangItem::FusedIterator, TraitSolverLangItem::Future => LangItem::Future, TraitSolverLangItem::FutureOutput => LangItem::FutureOutput, + TraitSolverLangItem::IntoFuture => LangItem::IntoFuture, + TraitSolverLangItem::IntoFutureOutput => LangItem::IntoFutureOutput, TraitSolverLangItem::Iterator => LangItem::Iterator, TraitSolverLangItem::Metadata => LangItem::Metadata, TraitSolverLangItem::Option => LangItem::Option, diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs index 69d21a63f557b..cae5077366e59 100644 --- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs +++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs @@ -31,10 +31,10 @@ //! However, what happens when we call `closure` with `AsyncFnOnce` (or `FnOnce`, //! since all async closures implement that too)? Well, recall the signature: //! ``` -//! use std::future::Future; +//! use std::future::IntoFuture; //! pub trait AsyncFnOnce //! { -//! type CallOnceFuture: Future; +//! type CallOnceFuture: IntoFuture; //! type Output; //! fn async_call_once( //! self, diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs index 3447b39fa5b40..b7e80a07fac2e 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs @@ -458,7 +458,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable { let bound_sig = self_ty.fn_sig(cx); let sig = bound_sig.skip_binder(); - let future_trait_def_id = cx.require_lang_item(TraitSolverLangItem::Future); + let future_trait_def_id = cx.require_lang_item(TraitSolverLangItem::IntoFuture); // `FnDef` and `FnPtr` only implement `AsyncFn*` when their // return type implements `Future`. let nested = vec![ @@ -466,7 +466,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable( let term = match item_name { sym::CallOnceFuture | sym::CallRefFuture => sig.output(), sym::Output => { - let future_output_def_id = tcx.require_lang_item(LangItem::FutureOutput, None); + let future_output_def_id = + tcx.require_lang_item(LangItem::IntoFutureOutput, None); Ty::new_projection(tcx, future_output_def_id, [sig.output()]) } name => bug!("no such associated type: {name}"), @@ -1910,7 +1911,8 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( let term = match item_name { sym::CallOnceFuture | sym::CallRefFuture => sig.output(), sym::Output => { - let future_output_def_id = tcx.require_lang_item(LangItem::FutureOutput, None); + let future_output_def_id = + tcx.require_lang_item(LangItem::IntoFutureOutput, None); Ty::new_projection(tcx, future_output_def_id, [sig.output()]) } name => bug!("no such associated type: {name}"), diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 9508a3e8e1509..58aa45494c6ed 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -951,7 +951,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // traits expressly allow the user to write. To fix this correctly, // we'd need to instantiate trait bounds before we get to selection, // like the new trait solver does. - let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None); + let future_trait_def_id = tcx.require_lang_item(LangItem::IntoFuture, None); let placeholder_output_ty = self.infcx.enter_forall_and_leak_universe(sig.output()); nested.push(obligation.with( tcx, @@ -973,7 +973,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // We must additionally check that the return type impls `Future`. // See FIXME in last branch for why we instantiate the binder eagerly. - let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None); + let future_trait_def_id = tcx.require_lang_item(LangItem::IntoFuture, None); let placeholder_output_ty = self.infcx.enter_forall_and_leak_universe(sig.output()); nested.push(obligation.with( tcx, diff --git a/compiler/rustc_type_ir/src/lang_items.rs b/compiler/rustc_type_ir/src/lang_items.rs index cf00c37caa287..9c26c56a315b8 100644 --- a/compiler/rustc_type_ir/src/lang_items.rs +++ b/compiler/rustc_type_ir/src/lang_items.rs @@ -26,6 +26,8 @@ pub enum TraitSolverLangItem { FusedIterator, Future, FutureOutput, + IntoFuture, + IntoFutureOutput, Iterator, Metadata, Option, diff --git a/library/core/src/future/into_future.rs b/library/core/src/future/into_future.rs index eb5a9b72dd0f2..28a6c06a5dca9 100644 --- a/library/core/src/future/into_future.rs +++ b/library/core/src/future/into_future.rs @@ -105,9 +105,11 @@ use crate::future::Future; message = "`{Self}` is not a future", note = "{Self} must be a future or must implement `IntoFuture` to be awaited" )] +#[cfg_attr(not(bootstrap), lang = "into_future")] pub trait IntoFuture { /// The output that the future will produce on completion. #[stable(feature = "into_future", since = "1.64.0")] + #[cfg_attr(not(bootstrap), lang = "into_future_output")] type Output; /// Which kind of future are we turning this into? @@ -130,7 +132,8 @@ pub trait IntoFuture { /// # } /// ``` #[stable(feature = "into_future", since = "1.64.0")] - #[lang = "into_future"] + #[cfg_attr(not(bootstrap), lang = "into_future_into_future")] + #[cfg_attr(bootstrap, lang = "into_future")] fn into_future(self) -> Self::IntoFuture; } diff --git a/library/core/src/ops/async_function.rs b/library/core/src/ops/async_function.rs index 48d1042d9df4a..737d0b72807ff 100644 --- a/library/core/src/ops/async_function.rs +++ b/library/core/src/ops/async_function.rs @@ -1,4 +1,4 @@ -use crate::future::Future; +use crate::future::IntoFuture; use crate::marker::Tuple; /// An async-aware version of the [`Fn`](crate::ops::Fn) trait. @@ -27,7 +27,7 @@ pub trait AsyncFnMut: AsyncFnOnce { /// Future returned by [`AsyncFnMut::async_call_mut`] and [`AsyncFn::async_call`]. #[unstable(feature = "async_fn_traits", issue = "none")] #[lang = "call_ref_future"] - type CallRefFuture<'a>: Future + type CallRefFuture<'a>: IntoFuture where Self: 'a; @@ -48,7 +48,7 @@ pub trait AsyncFnOnce { /// Future returned by [`AsyncFnOnce::async_call_once`]. #[unstable(feature = "async_fn_traits", issue = "none")] #[lang = "call_once_future"] - type CallOnceFuture: Future; + type CallOnceFuture: IntoFuture; /// Output type of the called closure's future. #[unstable(feature = "async_fn_traits", issue = "none")]