From 7f11d6f4bf8c4574b29d683ff72e596e7bcfbb50 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 29 May 2024 14:06:39 -0400 Subject: [PATCH 1/3] Add lang items for AsyncFn's associated types --- compiler/rustc_hir/src/lang_items.rs | 3 +++ compiler/rustc_span/src/symbol.rs | 3 +++ .../src/solve/normalizes_to/mod.rs | 22 ++++++++++++------- library/core/src/ops/async_function.rs | 3 +++ 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index c4be67cdd887f..410c2ed8703b4 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -228,6 +228,9 @@ language_item_table! { AsyncFn, sym::async_fn, async_fn_trait, Target::Trait, GenericRequirement::Exact(1); AsyncFnMut, sym::async_fn_mut, async_fn_mut_trait, Target::Trait, GenericRequirement::Exact(1); AsyncFnOnce, sym::async_fn_once, async_fn_once_trait, Target::Trait, GenericRequirement::Exact(1); + AsyncFnOnceOutput, sym::async_fn_once_output,async_fn_once_output, Target::AssocTy, GenericRequirement::Exact(1); + CallOnceFuture, sym::call_once_future, call_once_future, Target::AssocTy, GenericRequirement::Exact(1); + CallRefFuture, sym::call_ref_future, call_ref_future, Target::AssocTy, GenericRequirement::Exact(2); AsyncFnKindHelper, sym::async_fn_kind_helper,async_fn_kind_helper, Target::Trait, GenericRequirement::Exact(1); FnOnceOutput, sym::fn_once_output, fn_once_output, Target::AssocTy, GenericRequirement::None; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 90da220b3f549..cabd462cc8a6d 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -441,6 +441,7 @@ symbols! { async_fn_kind_helper, async_fn_mut, async_fn_once, + async_fn_once_output, async_fn_track_caller, async_fn_traits, async_for_loop, @@ -498,6 +499,8 @@ symbols! { call, call_mut, call_once, + call_once_future, + call_ref_future, caller_location, capture_disjoint_fields, catch_unwind, diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs index 7fd2a3801cc4c..f9e164e1f3f97 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs @@ -407,16 +407,20 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { output_coroutine_ty, coroutine_return_ty, }| { - let (projection_term, term) = match tcx.item_name(goal.predicate.def_id()) { - sym::CallOnceFuture => ( + let lang_items = tcx.lang_items(); + let (projection_term, term) = if Some(goal.predicate.def_id()) + == lang_items.call_once_future() + { + ( ty::AliasTerm::new( tcx, goal.predicate.def_id(), [goal.predicate.self_ty(), tupled_inputs_ty], ), output_coroutine_ty.into(), - ), - sym::CallRefFuture => ( + ) + } else if Some(goal.predicate.def_id()) == lang_items.call_ref_future() { + ( ty::AliasTerm::new( tcx, goal.predicate.def_id(), @@ -427,8 +431,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { ], ), output_coroutine_ty.into(), - ), - sym::Output => ( + ) + } else if Some(goal.predicate.def_id()) == lang_items.async_fn_once_output() { + ( ty::AliasTerm::new( tcx, goal.predicate.def_id(), @@ -438,8 +443,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> { ], ), coroutine_return_ty.into(), - ), - name => bug!("no such associated type: {name}"), + ) + } else { + bug!("no such associated type in `AsyncFn*`: {:?}", goal.predicate.def_id()) }; ty::ProjectionPredicate { projection_term, term } }, diff --git a/library/core/src/ops/async_function.rs b/library/core/src/ops/async_function.rs index 18bcee5a1c7e0..fc21ffd5246ed 100644 --- a/library/core/src/ops/async_function.rs +++ b/library/core/src/ops/async_function.rs @@ -26,6 +26,7 @@ pub trait AsyncFn: AsyncFnMut { pub trait AsyncFnMut: AsyncFnOnce { /// Future returned by [`AsyncFnMut::async_call_mut`] and [`AsyncFn::async_call`]. #[unstable(feature = "async_fn_traits", issue = "none")] + #[cfg_attr(not(bootstrap), lang = "call_ref_future")] type CallRefFuture<'a>: Future where Self: 'a; @@ -46,10 +47,12 @@ pub trait AsyncFnMut: AsyncFnOnce { pub trait AsyncFnOnce { /// Future returned by [`AsyncFnOnce::async_call_once`]. #[unstable(feature = "async_fn_traits", issue = "none")] + #[cfg_attr(not(bootstrap), lang = "call_once_future")] type CallOnceFuture: Future; /// Output type of the called closure's future. #[unstable(feature = "async_fn_traits", issue = "none")] + #[cfg_attr(not(bootstrap), lang = "async_fn_once_output")] type Output; /// Call the [`AsyncFnOnce`], returning a future which may move out of the called closure. From a9c7e024c08ce4c7172cf3a46d0d16222eb4991f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 29 May 2024 14:22:56 -0400 Subject: [PATCH 2/3] Add lang item for Future::Output --- compiler/rustc_hir/src/lang_items.rs | 1 + compiler/rustc_hir_analysis/src/collect.rs | 2 +- compiler/rustc_span/src/symbol.rs | 2 +- .../src/solve/assembly/structural_traits.rs | 14 ++------------ .../rustc_trait_selection/src/traits/project.rs | 16 ++-------------- library/core/src/future/future.rs | 2 +- 6 files changed, 8 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 410c2ed8703b4..67114a6212c4f 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -238,6 +238,7 @@ language_item_table! { Iterator, sym::iterator, iterator_trait, Target::Trait, GenericRequirement::Exact(0); 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); AsyncIterator, sym::async_iterator, async_iterator_trait, Target::Trait, GenericRequirement::Exact(0); CoroutineState, sym::coroutine_state, coroutine_state, Target::Enum, GenericRequirement::None; diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 75e35e7bf50c9..7e7460061484e 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1478,7 +1478,7 @@ pub fn suggest_impl_trait<'tcx>( ), ( infcx.tcx.lang_items().future_trait(), - infcx.tcx.get_diagnostic_item(sym::FutureOutput), + infcx.tcx.lang_items().future_output(), format_as_assoc, ), ( diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index cabd462cc8a6d..fa4ef923cc018 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -210,7 +210,6 @@ symbols! { FsPermissions, FusedIterator, Future, - FutureOutput, GlobalAlloc, Hash, HashMap, @@ -914,6 +913,7 @@ symbols! { fundamental, fused_iterator, future, + future_output, future_trait, gdb_script_file, ge, diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs index 64d5f725a1f4d..67cf0c3b2fde5 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs @@ -454,12 +454,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<'tc .rebind(ty::TraitRef::new(tcx, future_trait_def_id, [sig.output()])) .upcast(tcx), ]; - let future_output_def_id = tcx - .associated_items(future_trait_def_id) - .filter_by_name_unhygienic(sym::Output) - .next() - .unwrap() - .def_id; + let future_output_def_id = tcx.require_lang_item(LangItem::FutureOutput, None); let future_output_ty = Ty::new_projection(tcx, future_output_def_id, [sig.output()]); Ok(( bound_sig.rebind(AsyncCallableRelevantTypes { @@ -510,12 +505,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<'tc ); } - let future_output_def_id = tcx - .associated_items(future_trait_def_id) - .filter_by_name_unhygienic(sym::Output) - .next() - .unwrap() - .def_id; + let future_output_def_id = tcx.require_lang_item(LangItem::FutureOutput, None); let future_output_ty = Ty::new_projection(tcx, future_output_def_id, [sig.output()]); Ok(( bound_sig.rebind(AsyncCallableRelevantTypes { diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 87c8b1cda5041..c92c8369fedef 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1880,13 +1880,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( let term = match item_name { sym::CallOnceFuture | sym::CallRefFuture => sig.output(), sym::Output => { - let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None); - let future_output_def_id = tcx - .associated_items(future_trait_def_id) - .filter_by_name_unhygienic(sym::Output) - .next() - .unwrap() - .def_id; + let future_output_def_id = tcx.require_lang_item(LangItem::FutureOutput, None); Ty::new_projection(tcx, future_output_def_id, [sig.output()]) } name => bug!("no such associated type: {name}"), @@ -1919,13 +1913,7 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( let term = match item_name { sym::CallOnceFuture | sym::CallRefFuture => sig.output(), sym::Output => { - let future_trait_def_id = tcx.require_lang_item(LangItem::Future, None); - let future_output_def_id = tcx - .associated_items(future_trait_def_id) - .filter_by_name_unhygienic(sym::Output) - .next() - .unwrap() - .def_id; + let future_output_def_id = tcx.require_lang_item(LangItem::FutureOutput, None); Ty::new_projection(tcx, future_output_def_id, [sig.output()]) } name => bug!("no such associated type: {name}"), diff --git a/library/core/src/future/future.rs b/library/core/src/future/future.rs index f965afc8a5937..86963b548b9c6 100644 --- a/library/core/src/future/future.rs +++ b/library/core/src/future/future.rs @@ -35,7 +35,7 @@ use crate::task::{Context, Poll}; pub trait Future { /// The type of value produced on completion. #[stable(feature = "futures_api", since = "1.36.0")] - #[rustc_diagnostic_item = "FutureOutput"] + #[cfg_attr(not(bootstrap), lang = "future_output")] type Output; /// Attempt to resolve the future to a final value, registering From a03ba7fd2d0a94bd29f1ed7618c6e7ceecd3222c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 29 May 2024 14:28:53 -0400 Subject: [PATCH 3/3] Add lang item for AsyncFnKindHelper::Upvars --- compiler/rustc_hir/src/lang_items.rs | 5 +++-- compiler/rustc_span/src/symbol.rs | 1 + .../src/solve/assembly/structural_traits.rs | 9 +-------- .../src/traits/project.rs | 20 ++++--------------- library/core/src/ops/async_function.rs | 1 + 5 files changed, 10 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 67114a6212c4f..f5f7bae11b208 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -228,10 +228,11 @@ language_item_table! { AsyncFn, sym::async_fn, async_fn_trait, Target::Trait, GenericRequirement::Exact(1); AsyncFnMut, sym::async_fn_mut, async_fn_mut_trait, Target::Trait, GenericRequirement::Exact(1); AsyncFnOnce, sym::async_fn_once, async_fn_once_trait, Target::Trait, GenericRequirement::Exact(1); - AsyncFnOnceOutput, sym::async_fn_once_output,async_fn_once_output, Target::AssocTy, GenericRequirement::Exact(1); + AsyncFnOnceOutput, sym::async_fn_once_output, async_fn_once_output, Target::AssocTy, GenericRequirement::Exact(1); CallOnceFuture, sym::call_once_future, call_once_future, Target::AssocTy, GenericRequirement::Exact(1); CallRefFuture, sym::call_ref_future, call_ref_future, Target::AssocTy, GenericRequirement::Exact(2); - AsyncFnKindHelper, sym::async_fn_kind_helper,async_fn_kind_helper, Target::Trait, GenericRequirement::Exact(1); + AsyncFnKindHelper, sym::async_fn_kind_helper, async_fn_kind_helper, Target::Trait, GenericRequirement::Exact(1); + AsyncFnKindUpvars, sym::async_fn_kind_upvars, async_fn_kind_upvars, Target::AssocTy, GenericRequirement::Exact(5); FnOnceOutput, sym::fn_once_output, fn_once_output, Target::AssocTy, GenericRequirement::None; diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index fa4ef923cc018..25ecb9a31c6a2 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -438,6 +438,7 @@ symbols! { async_fn, async_fn_in_trait, async_fn_kind_helper, + async_fn_kind_upvars, async_fn_mut, async_fn_once, async_fn_once_output, diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs index 67cf0c3b2fde5..08796ef3109e4 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs @@ -9,7 +9,6 @@ use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_middle::bug; use rustc_middle::traits::solve::Goal; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, Upcast}; -use rustc_span::sym; use crate::solve::EvalCtxt; @@ -582,13 +581,7 @@ fn coroutine_closure_to_ambiguous_coroutine<'tcx>( args: ty::CoroutineClosureArgs<'tcx>, sig: ty::CoroutineClosureSignature<'tcx>, ) -> Ty<'tcx> { - let async_fn_kind_trait_def_id = tcx.require_lang_item(LangItem::AsyncFnKindHelper, None); - let upvars_projection_def_id = tcx - .associated_items(async_fn_kind_trait_def_id) - .filter_by_name_unhygienic(sym::Upvars) - .next() - .unwrap() - .def_id; + let upvars_projection_def_id = tcx.require_lang_item(LangItem::AsyncFnKindUpvars, None); let tupled_upvars_ty = Ty::new_projection( tcx, upvars_projection_def_id, diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index c92c8369fedef..b6557e6c4eb34 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1680,14 +1680,8 @@ fn confirm_closure_candidate<'cx, 'tcx>( args.coroutine_captures_by_ref_ty(), ) } else { - let async_fn_kind_trait_def_id = - tcx.require_lang_item(LangItem::AsyncFnKindHelper, None); - let upvars_projection_def_id = tcx - .associated_items(async_fn_kind_trait_def_id) - .filter_by_name_unhygienic(sym::Upvars) - .next() - .unwrap() - .def_id; + let upvars_projection_def_id = + tcx.require_lang_item(LangItem::AsyncFnKindUpvars, None); let tupled_upvars_ty = Ty::new_projection( tcx, upvars_projection_def_id, @@ -1816,14 +1810,8 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( args.coroutine_captures_by_ref_ty(), ) } else { - let async_fn_kind_trait_def_id = - tcx.require_lang_item(LangItem::AsyncFnKindHelper, None); - let upvars_projection_def_id = tcx - .associated_items(async_fn_kind_trait_def_id) - .filter_by_name_unhygienic(sym::Upvars) - .next() - .unwrap() - .def_id; + let upvars_projection_def_id = + tcx.require_lang_item(LangItem::AsyncFnKindUpvars, None); // When we don't know the closure kind (and therefore also the closure's upvars, // which are computed at the same time), we must delay the computation of the // generator's upvars. We do this using the `AsyncFnKindHelper`, which as a trait diff --git a/library/core/src/ops/async_function.rs b/library/core/src/ops/async_function.rs index fc21ffd5246ed..f4e9d1a63ac67 100644 --- a/library/core/src/ops/async_function.rs +++ b/library/core/src/ops/async_function.rs @@ -146,6 +146,7 @@ mod internal_implementation_detail { // `for<'env> fn() -> (&'env T, ...)`. This allows us to represent the binder // of the closure's self-capture, and these upvar types will be instantiated with // the `'closure_env` region provided to the associated type. + #[cfg_attr(not(bootstrap), lang = "async_fn_kind_upvars")] type Upvars<'closure_env, Inputs, Upvars, BorrowedUpvarsAsFnPtr>; } }