Skip to content

Return value of coroutine_layout fn changed to Result with LayoutError #140926

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 22 additions & 9 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ use crate::ty;
use crate::ty::codec::{TyDecoder, TyEncoder};
pub use crate::ty::diagnostics::*;
use crate::ty::fast_reject::SimplifiedType;
use crate::ty::layout::LayoutError;
use crate::ty::util::Discr;
use crate::ty::walk::TypeWalker;

Expand Down Expand Up @@ -1877,6 +1878,11 @@ impl<'tcx> TyCtxt<'tcx> {
self.def_kind(trait_def_id) == DefKind::TraitAlias
}

/// Arena-alloc of LayoutError for coroutine layout
fn layout_error(self, err: LayoutError<'tcx>) -> &'tcx LayoutError<'tcx> {
self.arena.alloc(err)
}

/// Returns layout of a non-async-drop coroutine. Layout might be unavailable if the
/// coroutine is tainted by errors.
///
Expand All @@ -1885,12 +1891,14 @@ impl<'tcx> TyCtxt<'tcx> {
fn ordinary_coroutine_layout(
self,
def_id: DefId,
coroutine_kind_ty: Ty<'tcx>,
) -> Option<&'tcx CoroutineLayout<'tcx>> {
args: GenericArgsRef<'tcx>,
) -> Result<&'tcx CoroutineLayout<'tcx>, &'tcx LayoutError<'tcx>> {
let coroutine_kind_ty = args.as_coroutine().kind_ty();
let mir = self.optimized_mir(def_id);
let ty = || Ty::new_coroutine(self, def_id, args);
// Regular coroutine
if coroutine_kind_ty.is_unit() {
mir.coroutine_layout_raw()
mir.coroutine_layout_raw().ok_or_else(|| self.layout_error(LayoutError::Unknown(ty())))
} else {
// If we have a `Coroutine` that comes from an coroutine-closure,
// then it may be a by-move or by-ref body.
Expand All @@ -1904,6 +1912,7 @@ impl<'tcx> TyCtxt<'tcx> {
// a by-ref coroutine.
if identity_kind_ty == coroutine_kind_ty {
mir.coroutine_layout_raw()
.ok_or_else(|| self.layout_error(LayoutError::Unknown(ty())))
} else {
assert_matches!(coroutine_kind_ty.to_opt_closure_kind(), Some(ClosureKind::FnOnce));
assert_matches!(
Expand All @@ -1912,6 +1921,7 @@ impl<'tcx> TyCtxt<'tcx> {
);
self.optimized_mir(self.coroutine_by_move_body_def_id(def_id))
.coroutine_layout_raw()
.ok_or_else(|| self.layout_error(LayoutError::Unknown(ty())))
}
}
}
Expand All @@ -1923,12 +1933,15 @@ impl<'tcx> TyCtxt<'tcx> {
self,
def_id: DefId,
args: GenericArgsRef<'tcx>,
) -> Option<&'tcx CoroutineLayout<'tcx>> {
) -> Result<&'tcx CoroutineLayout<'tcx>, &'tcx LayoutError<'tcx>> {
let ty = || Ty::new_coroutine(self, def_id, args);
if args[0].has_placeholders() || args[0].has_non_region_param() {
return None;
return Err(self.layout_error(LayoutError::TooGeneric(ty())));
}
let instance = InstanceKind::AsyncDropGlue(def_id, Ty::new_coroutine(self, def_id, args));
self.mir_shims(instance).coroutine_layout_raw()
self.mir_shims(instance)
.coroutine_layout_raw()
.ok_or_else(|| self.layout_error(LayoutError::Unknown(ty())))
}

/// Returns layout of a coroutine. Layout might be unavailable if the
Expand All @@ -1937,7 +1950,7 @@ impl<'tcx> TyCtxt<'tcx> {
self,
def_id: DefId,
args: GenericArgsRef<'tcx>,
) -> Option<&'tcx CoroutineLayout<'tcx>> {
) -> Result<&'tcx CoroutineLayout<'tcx>, &'tcx LayoutError<'tcx>> {
if self.is_async_drop_in_place_coroutine(def_id) {
// layout of `async_drop_in_place<T>::{closure}` in case,
// when T is a coroutine, contains this internal coroutine's ptr in upvars
Expand All @@ -1959,12 +1972,12 @@ impl<'tcx> TyCtxt<'tcx> {
variant_source_info,
storage_conflicts: BitMatrix::new(0, 0),
};
return Some(self.arena.alloc(proxy_layout));
return Ok(self.arena.alloc(proxy_layout));
} else {
self.async_drop_coroutine_layout(def_id, args)
}
} else {
self.ordinary_coroutine_layout(def_id, args.as_coroutine().kind_ty())
self.ordinary_coroutine_layout(def_id, args)
}
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_transform/src/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
let layout = if def_id == self.caller_body.source.def_id() {
self.caller_body
.coroutine_layout_raw()
.or_else(|| self.tcx.coroutine_layout(def_id, args))
.or_else(|| self.tcx.coroutine_layout(def_id, args).ok())
} else if self.tcx.needs_coroutine_by_move_body_def_id(def_id)
&& let ty::ClosureKind::FnOnce =
args.as_coroutine().kind_ty().to_opt_closure_kind().unwrap()
Expand All @@ -762,7 +762,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
// Same if this is the by-move body of a coroutine-closure.
self.caller_body.coroutine_layout_raw()
} else {
self.tcx.coroutine_layout(def_id, args)
self.tcx.coroutine_layout(def_id, args).ok()
};

let Some(layout) = layout else {
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_ty_utils/src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,9 +492,7 @@ fn layout_of_uncached<'tcx>(
ty::Coroutine(def_id, args) => {
use rustc_middle::ty::layout::PrimitiveExt as _;

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

let local_layouts = info
.field_tys
Expand Down
Loading