Skip to content

Commit

Permalink
Relax CallOnceFuture/CallRefFuture bound from Future to IntoFuture
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Jul 1, 2024
1 parent cf2df68 commit c35e984
Show file tree
Hide file tree
Showing 10 changed files with 28 additions and 15 deletions.
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")]
#[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

0 comments on commit c35e984

Please sign in to comment.