Skip to content

Commit f3945a1

Browse files
relocate upvars onto Unresumed state
1 parent 033becf commit f3945a1

File tree

60 files changed

+1079
-432
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+1079
-432
lines changed

compiler/rustc_abi/src/lib.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1523,8 +1523,7 @@ pub struct LayoutS<FieldIdx: Idx, VariantIdx: Idx> {
15231523

15241524
/// Encodes information about multi-variant layouts.
15251525
/// Even with `Multiple` variants, a layout still has its own fields! Those are then
1526-
/// shared between all variants. One of them will be the discriminant,
1527-
/// but e.g. coroutines can have more.
1526+
/// shared between all variants. One of them will be the discriminant.
15281527
///
15291528
/// To access all fields of this layout, both `fields` and the fields of the active variant
15301529
/// must be taken into account.

compiler/rustc_borrowck/src/type_check/mod.rs

+13-18
Original file line numberDiff line numberDiff line change
@@ -816,22 +816,18 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
816816
}),
817817
};
818818
}
819-
ty::CoroutineClosure(_, args) => {
820-
return match args.as_coroutine_closure().upvar_tys().get(field.index()) {
819+
ty::CoroutineClosure(_def_id, args) => {
820+
let upvar_tys = args.as_coroutine_closure().upvar_tys();
821+
return match upvar_tys.get(field.index()) {
821822
Some(&ty) => Ok(ty),
822-
None => Err(FieldAccessError::OutOfRange {
823-
field_count: args.as_coroutine_closure().upvar_tys().len(),
824-
}),
823+
None => Err(FieldAccessError::OutOfRange { field_count: upvar_tys.len() }),
825824
};
826825
}
827-
ty::Coroutine(_, args) => {
828-
// Only prefix fields (upvars and current state) are
829-
// accessible without a variant index.
830-
return match args.as_coroutine().prefix_tys().get(field.index()) {
831-
Some(ty) => Ok(*ty),
832-
None => Err(FieldAccessError::OutOfRange {
833-
field_count: args.as_coroutine().prefix_tys().len(),
834-
}),
826+
ty::Coroutine(_def_id, args) => {
827+
let upvar_tys = args.as_coroutine().upvar_tys();
828+
return match upvar_tys.get(field.index()) {
829+
Some(&ty) => Ok(ty),
830+
None => Err(FieldAccessError::OutOfRange { field_count: upvar_tys.len() }),
835831
};
836832
}
837833
ty::Tuple(tys) => {
@@ -1905,11 +1901,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
19051901
// It doesn't make sense to look at a field beyond the prefix;
19061902
// these require a variant index, and are not initialized in
19071903
// aggregate rvalues.
1908-
match args.as_coroutine().prefix_tys().get(field_index.as_usize()) {
1904+
let upvar_tys = args.as_coroutine().upvar_tys();
1905+
match upvar_tys.get(field_index.as_usize()) {
19091906
Some(ty) => Ok(*ty),
1910-
None => Err(FieldAccessError::OutOfRange {
1911-
field_count: args.as_coroutine().prefix_tys().len(),
1912-
}),
1907+
None => Err(FieldAccessError::OutOfRange { field_count: upvar_tys.len() }),
19131908
}
19141909
}
19151910
AggregateKind::CoroutineClosure(_, args) => {
@@ -2534,7 +2529,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
25342529

25352530
self.prove_aggregate_predicates(aggregate_kind, location);
25362531

2537-
if *aggregate_kind == AggregateKind::Tuple {
2532+
if matches!(aggregate_kind, AggregateKind::Tuple) {
25382533
// tuple rvalue field type is always the type of the op. Nothing to check here.
25392534
return;
25402535
}

compiler/rustc_codegen_cranelift/src/base.rs

+3
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,9 @@ fn codegen_stmt<'tcx>(
810810
let variant_dest = lval.downcast_variant(fx, variant_index);
811811
(variant_index, variant_dest, active_field_index)
812812
}
813+
mir::AggregateKind::Coroutine(_, _) => {
814+
(FIRST_VARIANT, lval.downcast_variant(fx, FIRST_VARIANT), None)
815+
}
813816
_ => (FIRST_VARIANT, lval, None),
814817
};
815818
if active_field_index.is_some() {

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1080,7 +1080,7 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>(
10801080
closure_or_coroutine_di_node: &'ll DIType,
10811081
) -> SmallVec<&'ll DIType> {
10821082
let (&def_id, up_var_tys) = match closure_or_coroutine_ty.kind() {
1083-
ty::Coroutine(def_id, args) => (def_id, args.as_coroutine().prefix_tys()),
1083+
ty::Coroutine(def_id, args) => (def_id, args.as_coroutine().upvar_tys()),
10841084
ty::Closure(def_id, args) => (def_id, args.as_closure().upvar_tys()),
10851085
ty::CoroutineClosure(def_id, args) => (def_id, args.as_coroutine_closure().upvar_tys()),
10861086
_ => {

compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -686,12 +686,12 @@ fn build_union_fields_for_direct_tag_coroutine<'ll, 'tcx>(
686686
let coroutine_layout =
687687
cx.tcx.coroutine_layout(coroutine_def_id, coroutine_args.kind_ty()).unwrap();
688688

689-
let common_upvar_names = cx.tcx.closure_saved_names_of_captured_variables(coroutine_def_id);
690689
let variant_range = coroutine_args.variant_range(coroutine_def_id, cx.tcx);
691690
let variant_count = (variant_range.start.as_u32()..variant_range.end.as_u32()).len();
692691

693692
let tag_base_type = tag_base_type(cx, coroutine_type_and_layout);
694693

694+
let common_upvar_names = cx.tcx.closure_saved_names_of_captured_variables(coroutine_def_id);
695695
let variant_names_type_di_node = build_variant_names_type_di_node(
696696
cx,
697697
coroutine_type_di_node,

compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs

+4-25
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ pub fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>(
326326
coroutine_type_and_layout: TyAndLayout<'tcx>,
327327
coroutine_type_di_node: &'ll DIType,
328328
coroutine_layout: &CoroutineLayout<'tcx>,
329-
common_upvar_names: &IndexSlice<FieldIdx, Symbol>,
329+
_common_upvar_names: &IndexSlice<FieldIdx, Symbol>,
330330
) -> &'ll DIType {
331331
let variant_name = CoroutineArgs::variant_name(variant_index);
332332
let unique_type_id = UniqueTypeId::for_enum_variant_struct_type(
@@ -337,7 +337,7 @@ pub fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>(
337337

338338
let variant_layout = coroutine_type_and_layout.for_variant(cx, variant_index);
339339

340-
let coroutine_args = match coroutine_type_and_layout.ty.kind() {
340+
let _coroutine_args = match coroutine_type_and_layout.ty.kind() {
341341
ty::Coroutine(_, args) => args.as_coroutine(),
342342
_ => unreachable!(),
343343
};
@@ -355,7 +355,7 @@ pub fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>(
355355
),
356356
|cx, variant_struct_type_di_node| {
357357
// Fields that just belong to this variant/state
358-
let state_specific_fields: SmallVec<_> = (0..variant_layout.fields.count())
358+
(0..variant_layout.fields.count())
359359
.map(|field_index| {
360360
let coroutine_saved_local = coroutine_layout.variant_fields[variant_index]
361361
[FieldIdx::from_usize(field_index)];
@@ -377,28 +377,7 @@ pub fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>(
377377
type_di_node(cx, field_type),
378378
)
379379
})
380-
.collect();
381-
382-
// Fields that are common to all states
383-
let common_fields: SmallVec<_> = coroutine_args
384-
.prefix_tys()
385-
.iter()
386-
.zip(common_upvar_names)
387-
.enumerate()
388-
.map(|(index, (upvar_ty, upvar_name))| {
389-
build_field_di_node(
390-
cx,
391-
variant_struct_type_di_node,
392-
upvar_name.as_str(),
393-
cx.size_and_align_of(upvar_ty),
394-
coroutine_type_and_layout.fields.offset(index),
395-
DIFlags::FlagZero,
396-
type_di_node(cx, upvar_ty),
397-
)
398-
})
399-
.collect();
400-
401-
state_specific_fields.into_iter().chain(common_fields).collect()
380+
.collect()
402381
},
403382
|cx| build_generic_type_param_di_nodes(cx, coroutine_type_and_layout.ty),
404383
)

compiler/rustc_codegen_ssa/src/mir/rvalue.rs

+3
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
126126
let variant_dest = dest.project_downcast(bx, variant_index);
127127
(variant_index, variant_dest, active_field_index)
128128
}
129+
mir::AggregateKind::Coroutine(_, _) => {
130+
(FIRST_VARIANT, dest.project_downcast(bx, FIRST_VARIANT), None)
131+
}
129132
_ => (FIRST_VARIANT, dest, None),
130133
};
131134
if active_field_index.is_some() {

compiler/rustc_const_eval/src/interpret/step.rs

+3
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
303303
let variant_dest = self.project_downcast(dest, variant_index)?;
304304
(variant_index, variant_dest, active_field_index)
305305
}
306+
mir::AggregateKind::Coroutine(_def_id, _args) => {
307+
(FIRST_VARIANT, self.project_downcast(dest, FIRST_VARIANT)?, None)
308+
}
306309
_ => (FIRST_VARIANT, dest.clone(), None),
307310
};
308311
if active_field_index.is_some() {

compiler/rustc_const_eval/src/transform/validate.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -743,14 +743,12 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
743743
};
744744

745745
ty::EarlyBinder::bind(f_ty.ty).instantiate(self.tcx, args)
746+
} else if let Some(&ty) = args.as_coroutine().upvar_tys().get(f.as_usize())
747+
{
748+
ty
746749
} else {
747-
let Some(&f_ty) = args.as_coroutine().prefix_tys().get(f.index())
748-
else {
749-
fail_out_of_bounds(self, location);
750-
return;
751-
};
752-
753-
f_ty
750+
fail_out_of_bounds(self, location);
751+
return;
754752
};
755753

756754
check_equal(self, location, f_ty);

compiler/rustc_middle/src/mir/query.rs

+9
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ pub struct CoroutineLayout<'tcx> {
5151
/// await).
5252
pub variant_source_info: IndexVec<VariantIdx, SourceInfo>,
5353

54+
/// The starting index of upvars.
55+
pub upvar_start: CoroutineSavedLocal,
56+
5457
/// Which saved locals are storage-live at the same time. Locals that do not
5558
/// have conflicts with each other are allowed to overlap in the computed
5659
/// layout.
@@ -101,6 +104,7 @@ impl Debug for CoroutineLayout<'_> {
101104
}
102105

103106
fmt.debug_struct("CoroutineLayout")
107+
.field("upvar_start", &self.upvar_start)
104108
.field("field_tys", &MapPrinter::new(self.field_tys.iter_enumerated()))
105109
.field(
106110
"variant_fields",
@@ -110,7 +114,12 @@ impl Debug for CoroutineLayout<'_> {
110114
.map(|(k, v)| (GenVariantPrinter(k), OneLinePrinter(v))),
111115
),
112116
)
117+
.field("field_names", &MapPrinter::new(self.field_names.iter_enumerated()))
113118
.field("storage_conflicts", &self.storage_conflicts)
119+
.field(
120+
"variant_source_info",
121+
&MapPrinter::new(self.variant_source_info.iter_enumerated()),
122+
)
114123
.finish()
115124
}
116125
}

compiler/rustc_middle/src/mir/tcx.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,11 @@ impl<'tcx> PlaceTy<'tcx> {
7474
T: ::std::fmt::Debug + Copy,
7575
{
7676
if self.variant_index.is_some() && !matches!(elem, ProjectionElem::Field(..)) {
77-
bug!("cannot use non field projection on downcasted place")
77+
bug!(
78+
"cannot use non field projection on downcasted place from {:?} (variant {:?}), got {elem:?}",
79+
self.ty,
80+
self.variant_index
81+
)
7882
}
7983
let answer = match *elem {
8084
ProjectionElem::Deref => {

compiler/rustc_middle/src/ty/layout.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -856,7 +856,7 @@ where
856856
if i == tag_field {
857857
return TyMaybeWithLayout::TyAndLayout(tag_layout(tag));
858858
}
859-
TyMaybeWithLayout::Ty(args.as_coroutine().prefix_tys()[i])
859+
bug!("coroutine has no prefix field");
860860
}
861861
},
862862

compiler/rustc_middle/src/ty/sty.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,7 @@ impl<'tcx> CoroutineArgs<'tcx> {
609609
witness: witness.expect_ty(),
610610
tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
611611
},
612-
_ => bug!("coroutine args missing synthetics"),
612+
_ => bug!("coroutine args missing synthetics, got {:?}", self.args),
613613
}
614614
}
615615

@@ -762,13 +762,6 @@ impl<'tcx> CoroutineArgs<'tcx> {
762762
})
763763
})
764764
}
765-
766-
/// This is the types of the fields of a coroutine which are not stored in a
767-
/// variant.
768-
#[inline]
769-
pub fn prefix_tys(self) -> &'tcx List<Ty<'tcx>> {
770-
self.upvar_tys()
771-
}
772765
}
773766

774767
#[derive(Debug, Copy, Clone, HashStable)]

compiler/rustc_mir_dataflow/src/framework/engine.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ where
288288
}
289289

290290
None if dump_enabled(tcx, A::NAME, def_id) => {
291-
create_dump_file(tcx, ".dot", false, A::NAME, &pass_name.unwrap_or("-----"), body)?
291+
create_dump_file(tcx, ".dot", true, A::NAME, &pass_name.unwrap_or("-----"), body)?
292292
}
293293

294294
_ => return (Ok(()), results),

0 commit comments

Comments
 (0)