Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Relax CallOnceFuture/CallRefFuture bound from Future to IntoFuture #127225

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion compiler/rustc_hir/src/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Args>
//! {
//! type CallOnceFuture: Future<Output = Self::Output>;
//! type CallOnceFuture: IntoFuture<Output = Self::Output>;
//! type Output;
//! fn async_call_once(
//! self,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -458,15 +458,15 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
ty::FnDef(..) | ty::FnPtr(..) => {
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![
bound_sig
.rebind(ty::TraitRef::new(cx, future_trait_def_id, [sig.output()]))
.upcast(cx),
];
let future_output_def_id = cx.require_lang_item(TraitSolverLangItem::FutureOutput);
let future_output_def_id = cx.require_lang_item(TraitSolverLangItem::IntoFutureOutput);
let future_output_ty = Ty::new_projection(cx, future_output_def_id, [sig.output()]);
Ok((
bound_sig.rebind(AsyncCallableRelevantTypes {
Expand All @@ -481,7 +481,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
let args = args.as_closure();
let bound_sig = args.sig();
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);
// `Closure`s only implement `AsyncFn*` when their return type
// implements `Future`.
let mut nested = vec![
Expand Down Expand Up @@ -517,7 +517,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<I:
);
}

let future_output_def_id = cx.require_lang_item(TraitSolverLangItem::FutureOutput);
let future_output_def_id = cx.require_lang_item(TraitSolverLangItem::IntoFutureOutput);
let future_output_ty = Ty::new_projection(cx, future_output_def_id, [sig.output()]);
Ok((
bound_sig.rebind(AsyncCallableRelevantTypes {
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1042,6 +1042,8 @@ symbols! {
integral,
into_async_iter_into_iter,
into_future,
into_future_into_future,
into_future_output,
into_iter,
intra_doc_pointers,
intrinsics,
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_trait_selection/src/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1877,7 +1877,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}"),
Expand Down Expand Up @@ -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}"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_type_ir/src/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ pub enum TraitSolverLangItem {
FusedIterator,
Future,
FutureOutput,
IntoFuture,
IntoFutureOutput,
Iterator,
Metadata,
Option,
Expand Down
5 changes: 4 additions & 1 deletion library/core/src/future/into_future.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand All @@ -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")]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed the existing lang item to into_future_into_future, and reused that name for the trait name for consistency!

#[cfg_attr(bootstrap, lang = "into_future")]
fn into_future(self) -> Self::IntoFuture;
}

Expand Down
6 changes: 3 additions & 3 deletions library/core/src/ops/async_function.rs
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -27,7 +27,7 @@ pub trait AsyncFnMut<Args: Tuple>: AsyncFnOnce<Args> {
/// 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<Output = Self::Output>
type CallRefFuture<'a>: IntoFuture<Output = Self::Output>
where
Self: 'a;

Expand All @@ -48,7 +48,7 @@ pub trait AsyncFnOnce<Args: Tuple> {
/// Future returned by [`AsyncFnOnce::async_call_once`].
#[unstable(feature = "async_fn_traits", issue = "none")]
#[lang = "call_once_future"]
type CallOnceFuture: Future<Output = Self::Output>;
type CallOnceFuture: IntoFuture<Output = Self::Output>;

/// Output type of the called closure's future.
#[unstable(feature = "async_fn_traits", issue = "none")]
Expand Down
Loading