diff options
| author | Michael Goulet <michael@errs.io> | 2024-01-25 03:50:23 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2024-02-06 02:22:58 +0000 |
| commit | 881b6b5149e882434a8df80a829bcfde0a2e9d37 (patch) | |
| tree | a929ae3c67bf3df264beb0407bccd2e28b2f1a64 /compiler | |
| parent | 427896dd7e39f1aaf3e3cbc15e5ddf77d45a6aec (diff) | |
| download | rust-881b6b5149e882434a8df80a829bcfde0a2e9d37.tar.gz rust-881b6b5149e882434a8df80a829bcfde0a2e9d37.zip | |
Bless tests, add comments
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_borrowck/src/type_check/input_output.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_borrowck/src/universal_regions.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/mod.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/query/mod.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/traits/select.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/instance.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/print/pretty.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/sty.rs | 36 | ||||
| -rw-r--r-- | compiler/rustc_smir/src/rustc_smir/convert/mir.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_smir/src/rustc_smir/convert/ty.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_span/src/symbol.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/solve/assembly/mod.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs | 13 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/project.rs | 14 | ||||
| -rw-r--r-- | compiler/rustc_type_ir/src/ty_kind.rs | 6 |
16 files changed, 88 insertions, 27 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs index ace9c5ae71d..46fd0ce2b39 100644 --- a/compiler/rustc_borrowck/src/type_check/input_output.rs +++ b/compiler/rustc_borrowck/src/type_check/input_output.rs @@ -47,8 +47,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { user_provided_sig, ); - // FIXME(async_closures): We must apply the same transformation to our - // signature here as we do during closure checking. + // FIXME(async_closures): It's kind of wacky that we must apply this + // transformation here, since we do the same thing in HIR typeck. + // Maybe we could just fix up the canonicalized signature during HIR typeck? if let DefiningTy::CoroutineClosure(_, args) = self.borrowck_context.universal_regions.defining_ty { diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 9c266d123b3..d696e624823 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -98,7 +98,10 @@ pub enum DefiningTy<'tcx> { Coroutine(DefId, GenericArgsRef<'tcx>), /// The MIR is a special kind of closure that returns coroutines. - /// TODO: describe how to make the sig... + /// + /// See the documentation on `CoroutineClosureSignature` for details + /// on how to construct the callable signature of the coroutine from + /// its args. CoroutineClosure(DefId, GenericArgsRef<'tcx>), /// The MIR is a fn item with the given `DefId` and args. The signature diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index d30c7a4fb38..23fb7eba656 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -335,7 +335,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { continue; } - // For this check, we do *not* want to treat async coroutine closures (async blocks) + // For this check, we do *not* want to treat async coroutine-closures (async blocks) // as proper closures. Doing so would regress type inference when feeding // the return value of an argument-position async block to an argument-position // closure wrapped in a block. diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index d88e9261e5a..3d6c28088ad 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -262,8 +262,16 @@ pub struct CoroutineInfo<'tcx> { /// Coroutine drop glue. This field is populated after the state transform pass. pub coroutine_drop: Option<Body<'tcx>>, - /// The body of the coroutine, modified to take its upvars by move. - /// TODO: + /// The body of the coroutine, modified to take its upvars by move rather than by ref. + /// + /// This is used by coroutine-closures, which must return a different flavor of coroutine + /// when called using `AsyncFnOnce::call_once`. It is produced by the `ByMoveBody` which + /// is run right after building the initial MIR, and will only be populated for coroutines + /// which come out of the async closure desugaring. + /// + /// This body should be processed in lockstep with the containing body -- any optimization + /// passes, etc, should be applied to this body as well. This is done automatically if + /// using `run_passes`. pub by_move_body: Option<Body<'tcx>>, /// The layout of a coroutine. This field is populated after the state transform pass. diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index f9ab32b16f5..938fba0ed09 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -756,7 +756,7 @@ rustc_queries! { } query coroutine_for_closure(def_id: DefId) -> DefId { - desc { |_tcx| "TODO" } + desc { |_tcx| "Given a coroutine-closure def id, return the def id of the coroutine returned by it" } separate_provide_extern } diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs index 4e11575cf98..28eba133c76 100644 --- a/compiler/rustc_middle/src/traits/select.rs +++ b/compiler/rustc_middle/src/traits/select.rs @@ -138,7 +138,9 @@ pub enum SelectionCandidate<'tcx> { /// generated for an `async ||` expression. AsyncClosureCandidate, - // TODO: + /// Implementation of the the `AsyncFnKindHelper` helper trait, which + /// is used internally to delay computation for async closures until after + /// upvar analysis is performed in HIR typeck. AsyncFnKindHelperCandidate, /// Implementation of a `Coroutine` trait by one of the anonymous types diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 44bf3c32b48..2c80dd02145 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -101,7 +101,10 @@ pub enum InstanceDef<'tcx> { target_kind: ty::ClosureKind, }, - /// TODO: + /// `<[coroutine] as Future>::poll`, but for coroutines produced when `AsyncFnOnce` + /// is called on a coroutine-closure whose closure kind is not `FnOnce`. This + /// will select the body that is produced by the `ByMoveBody` transform, and thus + /// take and use all of its upvars by-move rather than by-ref. CoroutineByMoveShim { coroutine_def_id: DefId }, /// Compiler-generated accessor for thread locals which returns a reference to the thread local diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index be6b887ba7d..c0bfd2380ad 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -877,7 +877,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { ty::CoroutineClosure(did, args) => { p!(write("{{")); if !self.should_print_verbose() { - p!(write("coroutine closure")); + p!(write("coroutine-closure")); // FIXME(eddyb) should use `def_span`. if let Some(did) = did.as_local() { if self.tcx().sess.opts.unstable_opts.span_free_formats { diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 8918a3735d6..3bbebaddbdd 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -276,11 +276,31 @@ pub struct CoroutineClosureArgs<'tcx> { } pub struct CoroutineClosureArgsParts<'tcx> { + /// This is the args of the typeck root. pub parent_args: &'tcx [GenericArg<'tcx>], + /// Represents the maximum calling capability of the closure. pub closure_kind_ty: Ty<'tcx>, + /// Represents all of the relevant parts of the coroutine returned by this + /// coroutine-closure. This signature parts type will have the general + /// shape of `fn(tupled_inputs, resume_ty) -> (return_ty, yield_ty)`, where + /// `resume_ty`, `return_ty`, and `yield_ty` are the respective types for the + /// coroutine returned by the coroutine-closure. + /// + /// Use `coroutine_closure_sig` to break up this type rather than using it + /// yourself. pub signature_parts_ty: Ty<'tcx>, + /// The upvars captured by the closure. Remains an inference variable + /// until the upvar analysis, which happens late in HIR typeck. pub tupled_upvars_ty: Ty<'tcx>, + /// a function pointer that has the shape `for<'env> fn() -> (&'env T, ...)`. + /// This allows us to represent the binder of the self-captures of the closure. + /// + /// For example, if the coroutine returned by the closure borrows `String` + /// from the closure's upvars, this will be `for<'env> fn() -> (&'env String,)`, + /// while the `tupled_upvars_ty`, representing the by-move version of the same + /// captures, will be `(String,)`. pub coroutine_captures_by_ref_ty: Ty<'tcx>, + /// Witness type returned by the generator produced by this coroutine-closure. pub coroutine_witness_ty: Ty<'tcx>, } @@ -496,15 +516,27 @@ pub struct CoroutineArgs<'tcx> { pub struct CoroutineArgsParts<'tcx> { /// This is the args of the typeck root. pub parent_args: &'tcx [GenericArg<'tcx>], - // TODO: why + + /// The coroutines returned by a coroutine-closure's `AsyncFnOnce`/`AsyncFnMut` + /// implementations must be distinguished since the former takes the closure's + /// upvars by move, and the latter takes the closure's upvars by ref. + /// + /// This field distinguishes these fields so that codegen can select the right + /// body for the coroutine. This has the same type representation as the closure + /// kind: `i8`/`i16`/`i32`. + /// + /// For regular coroutines, this field will always just be `()`. pub kind_ty: Ty<'tcx>, + pub resume_ty: Ty<'tcx>, pub yield_ty: Ty<'tcx>, pub return_ty: Ty<'tcx>, + /// The interior type of the coroutine. /// Represents all types that are stored in locals /// in the coroutine's body. pub witness: Ty<'tcx>, + /// The upvars captured by the closure. Remains an inference variable /// until the upvar analysis, which happens late in HIR typeck. pub tupled_upvars_ty: Ty<'tcx>, @@ -556,7 +588,7 @@ impl<'tcx> CoroutineArgs<'tcx> { self.split().parent_args } - // TODO: + // Returns the kind of the coroutine. See docs on the `kind_ty` field. pub fn kind_ty(self) -> Ty<'tcx> { self.split().kind_ty } diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs index 65ff85a9669..41a4edfc03b 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs @@ -539,7 +539,7 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> { ) } mir::AggregateKind::CoroutineClosure(..) => { - todo!("FIXME(async_closure): Lower these to SMIR") + todo!("FIXME(async_closures): Lower these to SMIR") } } } diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index 3c1858e920b..066348dcb67 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -383,7 +383,7 @@ impl<'tcx> Stable<'tcx> for ty::TyKind<'tcx> { tables.closure_def(*def_id), generic_args.stable(tables), )), - ty::CoroutineClosure(..) => todo!("/* TODO */"), + ty::CoroutineClosure(..) => todo!("FIXME(async_closures): Lower these to SMIR"), ty::Coroutine(def_id, generic_args) => TyKind::RigidTy(RigidTy::Coroutine( tables.coroutine_def(*def_id), generic_args.stable(tables), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 587eb1c7cc5..4203cb29db6 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -321,6 +321,7 @@ symbols! { TyCtxt, TyKind, Unknown, + Upvars, Vec, VecDeque, Wrapper, diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs index 8451fbcc434..7052fd776b0 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs @@ -190,7 +190,9 @@ pub(super) trait GoalKind<'tcx>: kind: ty::ClosureKind, ) -> QueryResult<'tcx>; - /// TODO: + /// Compute the built-in logic of the `AsyncFnKindHelper` helper trait, which + /// is used internally to delay computation for async closures until after + /// upvar analysis is performed in HIR typeck. fn consider_builtin_async_fn_kind_helper_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, 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 0699026117d..dbf3e4876a9 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs @@ -8,6 +8,7 @@ use rustc_middle::traits::solve::Goal; use rustc_middle::ty::{ self, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; +use rustc_span::sym; use crate::solve::EvalCtxt; @@ -274,7 +275,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<'tcx>( Ok(Some(closure_args.sig().map_bound(|sig| (sig.inputs()[0], sig.output())))) } - // Coroutine closures don't implement `Fn` traits the normal way. + // Coroutine-closures don't implement `Fn` traits the normal way. ty::CoroutineClosure(..) => Err(NoSolution), ty::Bool @@ -341,11 +342,11 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<'tc vec![], )) } else { - let helper_trait_def_id = tcx.require_lang_item(LangItem::AsyncFnKindHelper, None); - // FIXME(async_closures): Make this into a lang item. + let async_fn_kind_trait_def_id = + tcx.require_lang_item(LangItem::AsyncFnKindHelper, None); let upvars_projection_def_id = tcx - .associated_items(helper_trait_def_id) - .in_definition_order() + .associated_items(async_fn_kind_trait_def_id) + .filter_by_name_unhygienic(sym::Upvars) .next() .unwrap() .def_id; @@ -375,7 +376,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_async_callable<'tc vec![ ty::TraitRef::new( tcx, - helper_trait_def_id, + async_fn_kind_trait_def_id, [kind_ty, Ty::from_closure_kind(tcx, goal_kind)], ) .to_predicate(tcx), diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index db1e89ae72f..a8d6b9812be 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -2461,12 +2461,13 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( let goal_kind = tcx.async_fn_trait_kind_from_def_id(obligation.predicate.trait_def_id(tcx)).unwrap(); - let helper_trait_def_id = tcx.require_lang_item(LangItem::AsyncFnKindHelper, None); + let async_fn_kind_helper_trait_def_id = + tcx.require_lang_item(LangItem::AsyncFnKindHelper, None); nested.push(obligation.with( tcx, ty::TraitRef::new( tcx, - helper_trait_def_id, + async_fn_kind_helper_trait_def_id, [kind_ty, Ty::from_closure_kind(tcx, goal_kind)], ), )); @@ -2476,9 +2477,12 @@ fn confirm_async_closure_candidate<'cx, 'tcx>( ty::ClosureKind::FnOnce => tcx.lifetimes.re_static, }; - // FIXME(async_closures): Make this into a lang item. - let upvars_projection_def_id = - tcx.associated_items(helper_trait_def_id).in_definition_order().next().unwrap().def_id; + let upvars_projection_def_id = tcx + .associated_items(async_fn_kind_helper_trait_def_id) + .filter_by_name_unhygienic(sym::Upvars) + .next() + .unwrap() + .def_id; // FIXME(async_closures): Confirmation is kind of a mess here. Ideally, // we'd short-circuit when we know that the goal_kind >= closure_kind, and not diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 5941fce8825..a4fe572067b 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -202,7 +202,11 @@ pub enum TyKind<I: Interner> { /// `ClosureArgs` for more details. Closure(I::DefId, I::GenericArgs), - /// TODO + /// The anonymous type of a closure. Used to represent the type of `async |a| a`. + /// + /// Coroutine-closure args contain both the - potentially substituted - generic + /// parameters of its parent and some synthetic parameters. See the documentation + /// for `CoroutineClosureArgs` for more details. CoroutineClosure(I::DefId, I::GenericArgs), /// The anonymous type of a coroutine. Used to represent the type of |
