Skip to content

Commit 9ce3d8a

Browse files
committed
Return value of coroutine_layout fn changed to Result with LayoutError
1 parent 16c1c54 commit 9ce3d8a

File tree

10 files changed

+61
-36
lines changed

10 files changed

+61
-36
lines changed

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -721,10 +721,14 @@ fn build_union_fields_for_direct_tag_coroutine<'ll, 'tcx>(
721721
_ => unreachable!(),
722722
};
723723

724-
let coroutine_layout = cx.tcx.coroutine_layout(coroutine_def_id, coroutine_args.args).unwrap();
724+
let coroutine_layout = cx
725+
.tcx
726+
.coroutine_layout(coroutine_type_and_layout.ty, coroutine_def_id, coroutine_args.args)
727+
.unwrap();
725728

726729
let common_upvar_names = cx.tcx.closure_saved_names_of_captured_variables(coroutine_def_id);
727-
let variant_range = coroutine_args.variant_range(coroutine_def_id, cx.tcx);
730+
let variant_range =
731+
coroutine_args.variant_range(coroutine_type_and_layout.ty, coroutine_def_id, cx.tcx);
728732
let variant_count = (variant_range.start.as_u32()..variant_range.end.as_u32()).len();
729733

730734
let tag_base_type = tag_base_type(cx.tcx, coroutine_type_and_layout);
@@ -743,7 +747,8 @@ fn build_union_fields_for_direct_tag_coroutine<'ll, 'tcx>(
743747
);
744748

745749
let discriminants: IndexVec<VariantIdx, DiscrResult> = {
746-
let discriminants_iter = coroutine_args.discriminants(coroutine_def_id, cx.tcx);
750+
let discriminants_iter =
751+
coroutine_args.discriminants(coroutine_type_and_layout.ty, coroutine_def_id, cx.tcx);
747752
let mut discriminants: IndexVec<VariantIdx, DiscrResult> =
748753
IndexVec::with_capacity(variant_count);
749754
for (variant_index, discr) in discriminants_iter {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ pub(super) fn build_coroutine_di_node<'ll, 'tcx>(
175175
),
176176
|cx, coroutine_type_di_node| {
177177
let coroutine_layout =
178-
cx.tcx.coroutine_layout(coroutine_def_id, coroutine_args).unwrap();
178+
cx.tcx.coroutine_layout(coroutine_type, coroutine_def_id, coroutine_args).unwrap();
179179

180180
let Variants::Multiple { tag_encoding: TagEncoding::Direct, ref variants, .. } =
181181
coroutine_type_and_layout.variants

compiler/rustc_const_eval/src/interpret/discriminant.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
123123
}
124124
ty::Coroutine(def_id, args) => {
125125
let args = args.as_coroutine();
126-
args.discriminants(def_id, *self.tcx).find(|(_, var)| var.val == discr_bits)
126+
args.discriminants(ty, def_id, *self.tcx)
127+
.find(|(_, var)| var.val == discr_bits)
127128
}
128129
_ => span_bug!(self.cur_span(), "tagged layout for non-adt non-coroutine"),
129130
}

compiler/rustc_middle/src/mir/statement.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ impl<'tcx> PlaceTy<'tcx> {
9595
adt_def.variant(variant_index).fields[f].ty(tcx, args)
9696
}
9797
ty::Coroutine(def_id, args) => {
98-
let mut variants = args.as_coroutine().state_tys(def_id, tcx);
98+
let mut variants = args.as_coroutine().state_tys(self.ty, def_id, tcx);
9999
let Some(mut variant) = variants.nth(variant_index.into()) else {
100100
bug!("variant {variant_index:?} of coroutine out of range: {self:?}");
101101
};

compiler/rustc_middle/src/ty/layout.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -927,7 +927,7 @@ where
927927
Variants::Empty => unreachable!(),
928928
Variants::Single { index } => TyMaybeWithLayout::Ty(
929929
args.as_coroutine()
930-
.state_tys(def_id, tcx)
930+
.state_tys(this.ty, def_id, tcx)
931931
.nth(index.as_usize())
932932
.unwrap()
933933
.nth(i)

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ use crate::ty;
120120
use crate::ty::codec::{TyDecoder, TyEncoder};
121121
pub use crate::ty::diagnostics::*;
122122
use crate::ty::fast_reject::SimplifiedType;
123+
use crate::ty::layout::LayoutError;
123124
use crate::ty::util::Discr;
124125
use crate::ty::walk::TypeWalker;
125126

@@ -1877,20 +1878,26 @@ impl<'tcx> TyCtxt<'tcx> {
18771878
self.def_kind(trait_def_id) == DefKind::TraitAlias
18781879
}
18791880

1881+
/// Arena-alloc of LayoutError for coroutine layout
1882+
fn layout_error(self, err: LayoutError<'tcx>) -> &'tcx LayoutError<'tcx> {
1883+
self.arena.alloc(err)
1884+
}
1885+
18801886
/// Returns layout of a non-async-drop coroutine. Layout might be unavailable if the
18811887
/// coroutine is tainted by errors.
18821888
///
18831889
/// Takes `coroutine_kind` which can be acquired from the `CoroutineArgs::kind_ty`,
18841890
/// e.g. `args.as_coroutine().kind_ty()`.
18851891
fn ordinary_coroutine_layout(
18861892
self,
1893+
ty: Ty<'tcx>,
18871894
def_id: DefId,
18881895
coroutine_kind_ty: Ty<'tcx>,
1889-
) -> Option<&'tcx CoroutineLayout<'tcx>> {
1896+
) -> Result<&'tcx CoroutineLayout<'tcx>, &'tcx LayoutError<'tcx>> {
18901897
let mir = self.optimized_mir(def_id);
18911898
// Regular coroutine
18921899
if coroutine_kind_ty.is_unit() {
1893-
mir.coroutine_layout_raw()
1900+
mir.coroutine_layout_raw().ok_or_else(|| self.layout_error(LayoutError::Unknown(ty)))
18941901
} else {
18951902
// If we have a `Coroutine` that comes from an coroutine-closure,
18961903
// then it may be a by-move or by-ref body.
@@ -1904,6 +1911,7 @@ impl<'tcx> TyCtxt<'tcx> {
19041911
// a by-ref coroutine.
19051912
if identity_kind_ty == coroutine_kind_ty {
19061913
mir.coroutine_layout_raw()
1914+
.ok_or_else(|| self.layout_error(LayoutError::Unknown(ty)))
19071915
} else {
19081916
assert_matches!(coroutine_kind_ty.to_opt_closure_kind(), Some(ClosureKind::FnOnce));
19091917
assert_matches!(
@@ -1912,6 +1920,7 @@ impl<'tcx> TyCtxt<'tcx> {
19121920
);
19131921
self.optimized_mir(self.coroutine_by_move_body_def_id(def_id))
19141922
.coroutine_layout_raw()
1923+
.ok_or_else(|| self.layout_error(LayoutError::Unknown(ty)))
19151924
}
19161925
}
19171926
}
@@ -1921,23 +1930,27 @@ impl<'tcx> TyCtxt<'tcx> {
19211930
/// Layout might be unavailable if the coroutine is tainted by errors.
19221931
fn async_drop_coroutine_layout(
19231932
self,
1933+
ty: Ty<'tcx>,
19241934
def_id: DefId,
19251935
args: GenericArgsRef<'tcx>,
1926-
) -> Option<&'tcx CoroutineLayout<'tcx>> {
1936+
) -> Result<&'tcx CoroutineLayout<'tcx>, &'tcx LayoutError<'tcx>> {
19271937
if args[0].has_placeholders() || args[0].has_non_region_param() {
1928-
return None;
1938+
return Err(self.layout_error(LayoutError::TooGeneric(ty)));
19291939
}
19301940
let instance = InstanceKind::AsyncDropGlue(def_id, Ty::new_coroutine(self, def_id, args));
1931-
self.mir_shims(instance).coroutine_layout_raw()
1941+
self.mir_shims(instance)
1942+
.coroutine_layout_raw()
1943+
.ok_or_else(|| self.layout_error(LayoutError::Unknown(ty)))
19321944
}
19331945

19341946
/// Returns layout of a coroutine. Layout might be unavailable if the
19351947
/// coroutine is tainted by errors.
19361948
pub fn coroutine_layout(
19371949
self,
1950+
ty: Ty<'tcx>,
19381951
def_id: DefId,
19391952
args: GenericArgsRef<'tcx>,
1940-
) -> Option<&'tcx CoroutineLayout<'tcx>> {
1953+
) -> Result<&'tcx CoroutineLayout<'tcx>, &'tcx LayoutError<'tcx>> {
19411954
if self.is_async_drop_in_place_coroutine(def_id) {
19421955
// layout of `async_drop_in_place<T>::{closure}` in case,
19431956
// when T is a coroutine, contains this internal coroutine's ptr in upvars
@@ -1959,12 +1972,12 @@ impl<'tcx> TyCtxt<'tcx> {
19591972
variant_source_info,
19601973
storage_conflicts: BitMatrix::new(0, 0),
19611974
};
1962-
return Some(self.arena.alloc(proxy_layout));
1975+
return Ok(self.arena.alloc(proxy_layout));
19631976
} else {
1964-
self.async_drop_coroutine_layout(def_id, args)
1977+
self.async_drop_coroutine_layout(ty, def_id, args)
19651978
}
19661979
} else {
1967-
self.ordinary_coroutine_layout(def_id, args.as_coroutine().kind_ty())
1980+
self.ordinary_coroutine_layout(ty, def_id, args.as_coroutine().kind_ty())
19681981
}
19691982
}
19701983

compiler/rustc_middle/src/ty/sty.rs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,23 +75,25 @@ impl<'tcx> ty::CoroutineArgs<TyCtxt<'tcx>> {
7575

7676
/// The valid variant indices of this coroutine.
7777
#[inline]
78-
fn variant_range(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> Range<VariantIdx> {
78+
fn variant_range(&self, ty: Ty<'tcx>, def_id: DefId, tcx: TyCtxt<'tcx>) -> Range<VariantIdx> {
7979
// FIXME requires optimized MIR
80-
FIRST_VARIANT..tcx.coroutine_layout(def_id, self.args).unwrap().variant_fields.next_index()
80+
FIRST_VARIANT
81+
..tcx.coroutine_layout(ty, def_id, self.args).unwrap().variant_fields.next_index()
8182
}
8283

8384
/// The discriminant for the given variant. Panics if the `variant_index` is
8485
/// out of range.
8586
#[inline]
8687
fn discriminant_for_variant(
8788
&self,
89+
ty: Ty<'tcx>,
8890
def_id: DefId,
8991
tcx: TyCtxt<'tcx>,
9092
variant_index: VariantIdx,
9193
) -> Discr<'tcx> {
9294
// Coroutines don't support explicit discriminant values, so they are
9395
// the same as the variant index.
94-
assert!(self.variant_range(def_id, tcx).contains(&variant_index));
96+
assert!(self.variant_range(ty, def_id, tcx).contains(&variant_index));
9597
Discr { val: variant_index.as_usize() as u128, ty: self.discr_ty(tcx) }
9698
}
9799

@@ -100,10 +102,11 @@ impl<'tcx> ty::CoroutineArgs<TyCtxt<'tcx>> {
100102
#[inline]
101103
fn discriminants(
102104
self,
105+
ty: Ty<'tcx>,
103106
def_id: DefId,
104107
tcx: TyCtxt<'tcx>,
105108
) -> impl Iterator<Item = (VariantIdx, Discr<'tcx>)> {
106-
self.variant_range(def_id, tcx).map(move |index| {
109+
self.variant_range(ty, def_id, tcx).map(move |index| {
107110
(index, Discr { val: index.as_usize() as u128, ty: self.discr_ty(tcx) })
108111
})
109112
}
@@ -134,10 +137,11 @@ impl<'tcx> ty::CoroutineArgs<TyCtxt<'tcx>> {
134137
#[inline]
135138
fn state_tys(
136139
self,
140+
ty: Ty<'tcx>,
137141
def_id: DefId,
138142
tcx: TyCtxt<'tcx>,
139143
) -> impl Iterator<Item: Iterator<Item = Ty<'tcx>>> {
140-
let layout = tcx.coroutine_layout(def_id, self.args).unwrap();
144+
let layout = tcx.coroutine_layout(ty, def_id, self.args).unwrap();
141145
layout.variant_fields.iter().map(move |variant| {
142146
variant.iter().map(move |field| {
143147
if tcx.is_async_drop_in_place_coroutine(def_id) {
@@ -1515,7 +1519,7 @@ impl<'tcx> Ty<'tcx> {
15151519
match self.kind() {
15161520
TyKind::Adt(adt, _) => Some(adt.variant_range()),
15171521
TyKind::Coroutine(def_id, args) => {
1518-
Some(args.as_coroutine().variant_range(*def_id, tcx))
1522+
Some(args.as_coroutine().variant_range(self, *def_id, tcx))
15191523
}
15201524
_ => None,
15211525
}
@@ -1535,9 +1539,12 @@ impl<'tcx> Ty<'tcx> {
15351539
TyKind::Adt(adt, _) if adt.is_enum() => {
15361540
Some(adt.discriminant_for_variant(tcx, variant_index))
15371541
}
1538-
TyKind::Coroutine(def_id, args) => {
1539-
Some(args.as_coroutine().discriminant_for_variant(*def_id, tcx, variant_index))
1540-
}
1542+
TyKind::Coroutine(def_id, args) => Some(args.as_coroutine().discriminant_for_variant(
1543+
self,
1544+
*def_id,
1545+
tcx,
1546+
variant_index,
1547+
)),
15411548
_ => None,
15421549
}
15431550
}

compiler/rustc_mir_transform/src/shim.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -
554554
ty::Tuple(..) => builder.tuple_like_shim(dest, src, self_ty.tuple_fields()),
555555
ty::Coroutine(coroutine_def_id, args) => {
556556
assert_eq!(tcx.coroutine_movability(*coroutine_def_id), hir::Movability::Movable);
557-
builder.coroutine_shim(dest, src, *coroutine_def_id, args.as_coroutine())
557+
builder.coroutine_shim(dest, src, self_ty, *coroutine_def_id, args.as_coroutine())
558558
}
559559
_ => bug!("clone shim for `{:?}` which is not `Copy` and is not an aggregate", self_ty),
560560
};
@@ -754,6 +754,7 @@ impl<'tcx> CloneShimBuilder<'tcx> {
754754
&mut self,
755755
dest: Place<'tcx>,
756756
src: Place<'tcx>,
757+
ty: Ty<'tcx>,
757758
coroutine_def_id: DefId,
758759
args: CoroutineArgs<TyCtxt<'tcx>>,
759760
) {
@@ -764,8 +765,8 @@ impl<'tcx> CloneShimBuilder<'tcx> {
764765
let unwind = self.clone_fields(dest, src, switch, unwind, args.upvar_tys());
765766
let target = self.block(vec![], TerminatorKind::Return, false);
766767
let unreachable = self.block(vec![], TerminatorKind::Unreachable, false);
767-
let mut cases = Vec::with_capacity(args.state_tys(coroutine_def_id, self.tcx).count());
768-
for (index, state_tys) in args.state_tys(coroutine_def_id, self.tcx).enumerate() {
768+
let mut cases = Vec::with_capacity(args.state_tys(ty, coroutine_def_id, self.tcx).count());
769+
for (index, state_tys) in args.state_tys(ty, coroutine_def_id, self.tcx).enumerate() {
769770
let variant_index = VariantIdx::new(index);
770771
let dest = self.tcx.mk_place_downcast_unnamed(dest, variant_index);
771772
let src = self.tcx.mk_place_downcast_unnamed(src, variant_index);

compiler/rustc_mir_transform/src/validate.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -750,9 +750,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
750750
// since we may be in the process of computing this MIR in the
751751
// first place.
752752
let layout = if def_id == self.caller_body.source.def_id() {
753-
self.caller_body
754-
.coroutine_layout_raw()
755-
.or_else(|| self.tcx.coroutine_layout(def_id, args))
753+
self.caller_body.coroutine_layout_raw().or_else(|| {
754+
self.tcx.coroutine_layout(parent_ty.ty, def_id, args).ok()
755+
})
756756
} else if self.tcx.needs_coroutine_by_move_body_def_id(def_id)
757757
&& let ty::ClosureKind::FnOnce =
758758
args.as_coroutine().kind_ty().to_opt_closure_kind().unwrap()
@@ -762,7 +762,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
762762
// Same if this is the by-move body of a coroutine-closure.
763763
self.caller_body.coroutine_layout_raw()
764764
} else {
765-
self.tcx.coroutine_layout(def_id, args)
765+
self.tcx.coroutine_layout(parent_ty.ty, def_id, args).ok()
766766
};
767767

768768
let Some(layout) = layout else {

compiler/rustc_ty_utils/src/layout.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -492,9 +492,7 @@ fn layout_of_uncached<'tcx>(
492492
ty::Coroutine(def_id, args) => {
493493
use rustc_middle::ty::layout::PrimitiveExt as _;
494494

495-
let Some(info) = tcx.coroutine_layout(def_id, args) else {
496-
return Err(error(cx, LayoutError::Unknown(ty)));
497-
};
495+
let info = tcx.coroutine_layout(ty, def_id, args)?;
498496

499497
let local_layouts = info
500498
.field_tys
@@ -856,7 +854,7 @@ fn variant_info_for_coroutine<'tcx>(
856854
return (vec![], None);
857855
};
858856

859-
let coroutine = cx.tcx().coroutine_layout(def_id, args).unwrap();
857+
let coroutine = cx.tcx().coroutine_layout(layout.ty, def_id, args).unwrap();
860858
let upvar_names = cx.tcx().closure_saved_names_of_captured_variables(def_id);
861859

862860
let mut upvars_size = Size::ZERO;

0 commit comments

Comments
 (0)