Skip to content

For async closures, cap closure kind, get rid of by_mut_body #120717

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

Merged
merged 3 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Add a few more comments
  • Loading branch information
compiler-errors committed Mar 19, 2024
commit 541858ed787a66bbb00a4edd21f924ed0f208a9d
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ pub enum InstanceDef<'tcx> {
// because the signature of `<{async fn} as FnMut>::call_mut` is:
// `fn(&mut self, args: A) -> <Self as FnOnce>::Output`, that is to say
// that it returns the `FnOnce`-flavored coroutine but takes the closure
// by ref (and similarly for `Fn::call`).
// by mut ref (and similarly for `Fn::call`).
receiver_by_ref: bool,
},

Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2461,6 +2461,10 @@ impl<'tcx> Ty<'tcx> {
/// `AsyncFn`/`AsyncFnMut`/`AsyncFnOnce`, we only need to distinguish two coroutine
/// bodies: by-ref and by-value.
///
/// See the definition of `AsyncFn` and `AsyncFnMut` and the `CallRefFuture`
/// associated type for why we don't distinguish [`ty::ClosureKind::Fn`] and
/// [`ty::ClosureKind::FnMut`] for the purpose of the generated MIR bodies.
///
/// This method should be used when constructing a `Coroutine` out of a
/// `CoroutineClosure`, when the `Coroutine`'s `kind` field is being populated
/// directly from the `CoroutineClosure`'s `kind`.
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_mir_transform/src/shim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1023,7 +1023,16 @@ fn build_construct_coroutine_by_move_shim<'tcx>(
bug!();
};

// We use `*mut Self` here because we only need to emit an ABI-compatible shim body,
// rather than match the signature exactly.
//
// The self type here is a coroutine-closure, not a coroutine, and we never read from
// it because it never has any captures, because this is only true in the Fn/FnMut
// implementation, not the AsyncFn/AsyncFnMut implementation, which is implemented only
// if the coroutine-closure has no captures.
if receiver_by_ref {
// Triple-check that there's no captures here.
assert_eq!(args.as_coroutine_closure().tupled_upvars_ty(), tcx.types.unit);
self_ty = Ty::new_mut_ptr(tcx, self_ty);
}

Expand Down