diff options
| author | bors <bors@rust-lang.org> | 2024-08-27 23:30:24 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-08-27 23:30:24 +0000 |
| commit | d9a2cc4daee38c63b2f69710ed61d40acc32b709 (patch) | |
| tree | 162b0e6df4096f7362fb449fb3f61ab86bd6aff7 /compiler/rustc_middle/src/ty | |
| parent | 1f12b9b0fdbe735968ac002792a720f0ba4faca6 (diff) | |
| parent | 93295ff6dc48782ea3114e98313836b266f3e54a (diff) | |
| download | rust-d9a2cc4daee38c63b2f69710ed61d40acc32b709.tar.gz rust-d9a2cc4daee38c63b2f69710ed61d40acc32b709.zip | |
Auto merge of #128506 - compiler-errors:by-move-body, r=cjgillot
Stop storing a special inner body for the coroutine by-move body for async closures ...and instead, just synthesize an item which is treated mostly normally by the MIR pipeline. This PR does a few things: * We synthesize a new `DefId` for the by-move body of a closure, which has its `mir_built` fed with the output of the `ByMoveBody` MIR transformation, and some other relevant queries. * This has the `DefKind::ByMoveBody`, which we use to distinguish it from "real" bodies (that come from HIR) which need to be borrowck'd. Introduce `TyCtxt::is_synthetic_mir` to skip over `mir_borrowck` which is called by `mir_promoted`; borrowck isn't really possible to make work ATM since it heavily relies being called on a body generated from HIR, and is redundant by the construction of the by-move-body. * Remove the special `PassManager` hacks for handling the inner `by_move_body` stored within the coroutine's mir body. Instead, this body is fed like a regular MIR body, so it's goes through all of the `tcx.*_mir` stages normally (build -> promoted -> ...etc... -> optimized) ✨. * Remove the `InstanceKind::ByMoveBody` shim, since now we have a "regular" def id, we can just use `InstanceKind::Item`. This also allows us to remove the corresponding hacks from codegen, such as in `fn_sig_for_fn_abi` ✨. Notable remarks: * ~~I know it's kind of weird to be using `DefKind::Closure` here, since it's not a distinct closure but just a new MIR body. I don't believe it really matters, but I could also use a different `DefKind`... maybe one that we could use for synthetic MIR bodies in general?~~ edit: We're doing this now.
Diffstat (limited to 'compiler/rustc_middle/src/ty')
| -rw-r--r-- | compiler/rustc_middle/src/ty/context.rs | 18 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/instance.rs | 16 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/mod.rs | 4 |
3 files changed, 23 insertions, 15 deletions
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index cad3515f068..8effb67a1f6 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1579,6 +1579,12 @@ impl<'tcx> TyCtxt<'tcx> { ) } + // Whether the body owner is synthetic, which in this case means it does not correspond to + // meaningful HIR. This is currently used to skip over MIR borrowck. + pub fn is_synthetic_mir(self, def_id: impl Into<DefId>) -> bool { + matches!(self.def_kind(def_id.into()), DefKind::SyntheticCoroutineBody) + } + /// Returns `true` if the node pointed to by `def_id` is a general coroutine that implements `Coroutine`. /// This means it is neither an `async` or `gen` construct. pub fn is_general_coroutine(self, def_id: DefId) -> bool { @@ -3168,6 +3174,18 @@ impl<'tcx> TyCtxt<'tcx> { self.impl_trait_header(def_id).map_or(ty::ImplPolarity::Positive, |h| h.polarity) } + pub fn needs_coroutine_by_move_body_def_id(self, def_id: LocalDefId) -> bool { + if let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) = + self.coroutine_kind(def_id) + && let ty::Coroutine(_, args) = self.type_of(def_id).instantiate_identity().kind() + && args.as_coroutine().kind_ty().to_opt_closure_kind() != Some(ty::ClosureKind::FnOnce) + { + true + } else { + false + } + } + /// Whether this is a trait implementation that has `#[diagnostic::do_not_recommend]` pub fn do_not_recommend_impl(self, def_id: DefId) -> bool { matches!(self.def_kind(def_id), DefKind::Impl { of_trait: true }) diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index ecb3943e788..7d5f0f1e9c4 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -141,14 +141,6 @@ pub enum InstanceKind<'tcx> { receiver_by_ref: bool, }, - /// `<[coroutine] as Future>::poll`, but for coroutines produced when `AsyncFnOnce` - /// is called on a coroutine-closure whose closure kind greater than `FnOnce`, or - /// similarly for `AsyncFnMut`. - /// - /// 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. - CoroutineKindShim { coroutine_def_id: DefId }, - /// Compiler-generated accessor for thread locals which returns a reference to the thread local /// the `DefId` defines. This is used to export thread locals from dylibs on platforms lacking /// native support. @@ -248,7 +240,6 @@ impl<'tcx> InstanceKind<'tcx> { coroutine_closure_def_id: def_id, receiver_by_ref: _, } - | ty::InstanceKind::CoroutineKindShim { coroutine_def_id: def_id } | InstanceKind::DropGlue(def_id, _) | InstanceKind::CloneShim(def_id, _) | InstanceKind::FnPtrAddrShim(def_id, _) @@ -270,7 +261,6 @@ impl<'tcx> InstanceKind<'tcx> { | InstanceKind::Intrinsic(..) | InstanceKind::ClosureOnceShim { .. } | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } - | ty::InstanceKind::CoroutineKindShim { .. } | InstanceKind::DropGlue(..) | InstanceKind::AsyncDropGlueCtorShim(..) | InstanceKind::CloneShim(..) @@ -377,7 +367,6 @@ impl<'tcx> InstanceKind<'tcx> { | InstanceKind::AsyncDropGlueCtorShim(_, Some(_)) => false, InstanceKind::ClosureOnceShim { .. } | InstanceKind::ConstructCoroutineInClosureShim { .. } - | InstanceKind::CoroutineKindShim { .. } | InstanceKind::DropGlue(..) | InstanceKind::AsyncDropGlueCtorShim(..) | InstanceKind::Item(_) @@ -452,7 +441,6 @@ pub fn fmt_instance( InstanceKind::FnPtrShim(_, ty) => write!(f, " - shim({ty})"), InstanceKind::ClosureOnceShim { .. } => write!(f, " - shim"), InstanceKind::ConstructCoroutineInClosureShim { .. } => write!(f, " - shim"), - InstanceKind::CoroutineKindShim { .. } => write!(f, " - shim"), InstanceKind::DropGlue(_, None) => write!(f, " - shim(None)"), InstanceKind::DropGlue(_, Some(ty)) => write!(f, " - shim(Some({ty}))"), InstanceKind::CloneShim(_, ty) => write!(f, " - shim({ty})"), @@ -850,7 +838,9 @@ impl<'tcx> Instance<'tcx> { Some(Instance { def: ty::InstanceKind::Item(coroutine_def_id), args }) } else { Some(Instance { - def: ty::InstanceKind::CoroutineKindShim { coroutine_def_id }, + def: ty::InstanceKind::Item( + tcx.coroutine_by_move_body_def_id(coroutine_def_id), + ), args, }) } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 1e3b5800cba..e41ea7507ef 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1756,7 +1756,6 @@ impl<'tcx> TyCtxt<'tcx> { | ty::InstanceKind::Virtual(..) | ty::InstanceKind::ClosureOnceShim { .. } | ty::InstanceKind::ConstructCoroutineInClosureShim { .. } - | ty::InstanceKind::CoroutineKindShim { .. } | ty::InstanceKind::DropGlue(..) | ty::InstanceKind::CloneShim(..) | ty::InstanceKind::ThreadLocalShim(..) @@ -1874,7 +1873,8 @@ impl<'tcx> TyCtxt<'tcx> { identity_kind_ty.to_opt_closure_kind(), Some(ClosureKind::Fn | ClosureKind::FnMut) ); - mir.coroutine_by_move_body().unwrap().coroutine_layout_raw() + self.optimized_mir(self.coroutine_by_move_body_def_id(def_id)) + .coroutine_layout_raw() } } } |
