Rollup merge of #123021 - compiler-errors:coroutine-layout-lol, r=oli-obk
Make `TyCtxt::coroutine_layout` take coroutine's kind parameter For coroutines that come from coroutine-closures (i.e. async closures), we may have two kinds of bodies stored in the coroutine; one that takes the closure's captures by reference, and one that takes the captures by move. These currently have identical layouts, but if we do any optimization for these layouts that are related to the upvars, then they will diverge -- e.g. https://github.com/rust-lang/rust/pull/120168#discussion_r1536943728. This PR relaxes the assertion I added in #121122, and instead make the `TyCtxt::coroutine_layout` method take the `coroutine_kind_ty` argument from the coroutine, which will allow us to differentiate these by-move and by-ref bodies.
This commit is contained in:
commit
bffeb052d1
8 changed files with 61 additions and 23 deletions
|
@ -101,18 +101,17 @@ impl<'tcx> MirPass<'tcx> for Validator {
|
|||
}
|
||||
|
||||
// Enforce that coroutine-closure layouts are identical.
|
||||
if let Some(layout) = body.coroutine_layout()
|
||||
if let Some(layout) = body.coroutine_layout_raw()
|
||||
&& let Some(by_move_body) = body.coroutine_by_move_body()
|
||||
&& let Some(by_move_layout) = by_move_body.coroutine_layout()
|
||||
&& let Some(by_move_layout) = by_move_body.coroutine_layout_raw()
|
||||
{
|
||||
if layout != by_move_layout {
|
||||
// If this turns out not to be true, please let compiler-errors know.
|
||||
// It is possible to support, but requires some changes to the layout
|
||||
// computation code.
|
||||
// FIXME(async_closures): We could do other validation here?
|
||||
if layout.variant_fields.len() != by_move_layout.variant_fields.len() {
|
||||
cfg_checker.fail(
|
||||
Location::START,
|
||||
format!(
|
||||
"Coroutine layout differs from by-move coroutine layout:\n\
|
||||
"Coroutine layout has different number of variant fields from \
|
||||
by-move coroutine layout:\n\
|
||||
layout: {layout:#?}\n\
|
||||
by_move_layout: {by_move_layout:#?}",
|
||||
),
|
||||
|
@ -715,13 +714,14 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||
// args of the coroutine. Otherwise, we prefer to use this body
|
||||
// since we may be in the process of computing this MIR in the
|
||||
// first place.
|
||||
let gen_body = if def_id == self.caller_body.source.def_id() {
|
||||
self.caller_body
|
||||
let layout = if def_id == self.caller_body.source.def_id() {
|
||||
// FIXME: This is not right for async closures.
|
||||
self.caller_body.coroutine_layout_raw()
|
||||
} else {
|
||||
self.tcx.optimized_mir(def_id)
|
||||
self.tcx.coroutine_layout(def_id, args.as_coroutine().kind_ty())
|
||||
};
|
||||
|
||||
let Some(layout) = gen_body.coroutine_layout() else {
|
||||
let Some(layout) = layout else {
|
||||
self.fail(
|
||||
location,
|
||||
format!("No coroutine layout for {parent_ty:?}"),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue