Skip to content

Commit 3af0c43

Browse files
authored
Rollup merge of #140926 - azhogin:azhogin/async-drop-coroutine-layout-returns-layout-error, r=oli-obk
Return value of coroutine_layout fn changed to Result with LayoutError Continue of #140902: `coroutine_layout` fn is now returns `Result` with `LayoutError` to have consistent error with `layout_of_uncached`. `async_drop_coroutine_layout` fn is now return `LayoutError::TooGeneric` in case of not-fully-specialized `async_drop_in_place<T>::{closure}` coroutine.
2 parents 4e5b1aa + ba80d82 commit 3af0c43

File tree

3 files changed

+25
-14
lines changed

3 files changed

+25
-14
lines changed

compiler/rustc_middle/src/ty/mod.rs

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

@@ -1878,6 +1879,11 @@ impl<'tcx> TyCtxt<'tcx> {
18781879
self.def_kind(trait_def_id) == DefKind::TraitAlias
18791880
}
18801881

1882+
/// Arena-alloc of LayoutError for coroutine layout
1883+
fn layout_error(self, err: LayoutError<'tcx>) -> &'tcx LayoutError<'tcx> {
1884+
self.arena.alloc(err)
1885+
}
1886+
18811887
/// Returns layout of a non-async-drop coroutine. Layout might be unavailable if the
18821888
/// coroutine is tainted by errors.
18831889
///
@@ -1886,12 +1892,14 @@ impl<'tcx> TyCtxt<'tcx> {
18861892
fn ordinary_coroutine_layout(
18871893
self,
18881894
def_id: DefId,
1889-
coroutine_kind_ty: Ty<'tcx>,
1890-
) -> Option<&'tcx CoroutineLayout<'tcx>> {
1895+
args: GenericArgsRef<'tcx>,
1896+
) -> Result<&'tcx CoroutineLayout<'tcx>, &'tcx LayoutError<'tcx>> {
1897+
let coroutine_kind_ty = args.as_coroutine().kind_ty();
18911898
let mir = self.optimized_mir(def_id);
1899+
let ty = || Ty::new_coroutine(self, def_id, args);
18921900
// Regular coroutine
18931901
if coroutine_kind_ty.is_unit() {
1894-
mir.coroutine_layout_raw()
1902+
mir.coroutine_layout_raw().ok_or_else(|| self.layout_error(LayoutError::Unknown(ty())))
18951903
} else {
18961904
// If we have a `Coroutine` that comes from an coroutine-closure,
18971905
// then it may be a by-move or by-ref body.
@@ -1905,6 +1913,7 @@ impl<'tcx> TyCtxt<'tcx> {
19051913
// a by-ref coroutine.
19061914
if identity_kind_ty == coroutine_kind_ty {
19071915
mir.coroutine_layout_raw()
1916+
.ok_or_else(|| self.layout_error(LayoutError::Unknown(ty())))
19081917
} else {
19091918
assert_matches!(coroutine_kind_ty.to_opt_closure_kind(), Some(ClosureKind::FnOnce));
19101919
assert_matches!(
@@ -1913,6 +1922,7 @@ impl<'tcx> TyCtxt<'tcx> {
19131922
);
19141923
self.optimized_mir(self.coroutine_by_move_body_def_id(def_id))
19151924
.coroutine_layout_raw()
1925+
.ok_or_else(|| self.layout_error(LayoutError::Unknown(ty())))
19161926
}
19171927
}
19181928
}
@@ -1924,12 +1934,15 @@ impl<'tcx> TyCtxt<'tcx> {
19241934
self,
19251935
def_id: DefId,
19261936
args: GenericArgsRef<'tcx>,
1927-
) -> Option<&'tcx CoroutineLayout<'tcx>> {
1937+
) -> Result<&'tcx CoroutineLayout<'tcx>, &'tcx LayoutError<'tcx>> {
1938+
let ty = || Ty::new_coroutine(self, def_id, args);
19281939
if args[0].has_placeholders() || args[0].has_non_region_param() {
1929-
return None;
1940+
return Err(self.layout_error(LayoutError::TooGeneric(ty())));
19301941
}
19311942
let instance = InstanceKind::AsyncDropGlue(def_id, Ty::new_coroutine(self, def_id, args));
1932-
self.mir_shims(instance).coroutine_layout_raw()
1943+
self.mir_shims(instance)
1944+
.coroutine_layout_raw()
1945+
.ok_or_else(|| self.layout_error(LayoutError::Unknown(ty())))
19331946
}
19341947

19351948
/// Returns layout of a coroutine. Layout might be unavailable if the
@@ -1938,7 +1951,7 @@ impl<'tcx> TyCtxt<'tcx> {
19381951
self,
19391952
def_id: DefId,
19401953
args: GenericArgsRef<'tcx>,
1941-
) -> Option<&'tcx CoroutineLayout<'tcx>> {
1954+
) -> Result<&'tcx CoroutineLayout<'tcx>, &'tcx LayoutError<'tcx>> {
19421955
if self.is_async_drop_in_place_coroutine(def_id) {
19431956
// layout of `async_drop_in_place<T>::{closure}` in case,
19441957
// when T is a coroutine, contains this internal coroutine's ptr in upvars
@@ -1960,12 +1973,12 @@ impl<'tcx> TyCtxt<'tcx> {
19601973
variant_source_info,
19611974
storage_conflicts: BitMatrix::new(0, 0),
19621975
};
1963-
return Some(self.arena.alloc(proxy_layout));
1976+
return Ok(self.arena.alloc(proxy_layout));
19641977
} else {
19651978
self.async_drop_coroutine_layout(def_id, args)
19661979
}
19671980
} else {
1968-
self.ordinary_coroutine_layout(def_id, args.as_coroutine().kind_ty())
1981+
self.ordinary_coroutine_layout(def_id, args)
19691982
}
19701983
}
19711984

compiler/rustc_mir_transform/src/validate.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
752752
let layout = if def_id == self.caller_body.source.def_id() {
753753
self.caller_body
754754
.coroutine_layout_raw()
755-
.or_else(|| self.tcx.coroutine_layout(def_id, args))
755+
.or_else(|| self.tcx.coroutine_layout(def_id, args).ok())
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(def_id, args).ok()
766766
};
767767

768768
let Some(layout) = layout else {

compiler/rustc_ty_utils/src/layout.rs

Lines changed: 1 addition & 3 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(def_id, args)?;
498496

499497
let local_layouts = info
500498
.field_tys

0 commit comments

Comments
 (0)