Skip to content

Commit ce06df2

Browse files
authored
Rollup merge of #81008 - tmiasko:generator-layout-err, r=tmandry
Don't ICE when computing a layout of a generator tainted by errors Fixes #80998.
2 parents a584d87 + 5ea1d0e commit ce06df2

File tree

6 files changed

+50
-8
lines changed

6 files changed

+50
-8
lines changed

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1832,8 +1832,9 @@ impl<'tcx> VariantInfo<'_, 'tcx> {
18321832
fn source_info(&self, cx: &CodegenCx<'ll, 'tcx>) -> Option<SourceInfo<'ll>> {
18331833
match self {
18341834
VariantInfo::Generator { def_id, variant_index, .. } => {
1835-
let span =
1836-
cx.tcx.generator_layout(*def_id).variant_source_info[*variant_index].span;
1835+
let span = cx.tcx.generator_layout(*def_id).unwrap().variant_source_info
1836+
[*variant_index]
1837+
.span;
18371838
if !span.is_dummy() {
18381839
let loc = cx.lookup_debug_loc(span.lo());
18391840
return Some(SourceInfo {

compiler/rustc_middle/src/ty/layout.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1466,10 +1466,12 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
14661466
) -> Result<&'tcx Layout, LayoutError<'tcx>> {
14671467
use SavedLocalEligibility::*;
14681468
let tcx = self.tcx;
1469-
14701469
let subst_field = |ty: Ty<'tcx>| ty.subst(tcx, substs);
14711470

1472-
let info = tcx.generator_layout(def_id);
1471+
let info = match tcx.generator_layout(def_id) {
1472+
None => return Err(LayoutError::Unknown(ty)),
1473+
Some(info) => info,
1474+
};
14731475
let (ineligible_locals, assignments) = self.generator_saved_local_eligibility(&info);
14741476

14751477
// Build a prefix layout, including "promoting" all ineligible

compiler/rustc_middle/src/ty/mod.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -3068,8 +3068,10 @@ impl<'tcx> TyCtxt<'tcx> {
30683068
self.trait_def(trait_def_id).has_auto_impl
30693069
}
30703070

3071-
pub fn generator_layout(self, def_id: DefId) -> &'tcx GeneratorLayout<'tcx> {
3072-
self.optimized_mir(def_id).generator_layout.as_ref().unwrap()
3071+
/// Returns layout of a generator. Layout might be unavailable if the
3072+
/// generator is tainted by errors.
3073+
pub fn generator_layout(self, def_id: DefId) -> Option<&'tcx GeneratorLayout<'tcx>> {
3074+
self.optimized_mir(def_id).generator_layout.as_ref()
30733075
}
30743076

30753077
/// Given the `DefId` of an impl, returns the `DefId` of the trait it implements.

compiler/rustc_middle/src/ty/sty.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ impl<'tcx> GeneratorSubsts<'tcx> {
605605
#[inline]
606606
pub fn variant_range(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> Range<VariantIdx> {
607607
// FIXME requires optimized MIR
608-
let num_variants = tcx.generator_layout(def_id).variant_fields.len();
608+
let num_variants = tcx.generator_layout(def_id).unwrap().variant_fields.len();
609609
VariantIdx::new(0)..VariantIdx::new(num_variants)
610610
}
611611

@@ -666,7 +666,7 @@ impl<'tcx> GeneratorSubsts<'tcx> {
666666
def_id: DefId,
667667
tcx: TyCtxt<'tcx>,
668668
) -> impl Iterator<Item = impl Iterator<Item = Ty<'tcx>> + Captures<'tcx>> {
669-
let layout = tcx.generator_layout(def_id);
669+
let layout = tcx.generator_layout(def_id).unwrap();
670670
layout.variant_fields.iter().map(move |variant| {
671671
variant.iter().map(move |field| layout.field_tys[*field].subst(tcx, self.substs))
672672
})

src/test/ui/generator/layout-error.rs

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Verifies that computing a layout of a generator tainted by type errors
2+
// doesn't ICE. Regression test for #80998.
3+
//
4+
// edition:2018
5+
6+
#![feature(type_alias_impl_trait)]
7+
use std::future::Future;
8+
9+
pub struct Task<F: Future>(F);
10+
impl<F: Future> Task<F> {
11+
fn new() -> Self {
12+
todo!()
13+
}
14+
fn spawn(&self, _: impl FnOnce() -> F) {
15+
todo!()
16+
}
17+
}
18+
19+
fn main() {
20+
async fn cb() {
21+
let a = Foo; //~ ERROR cannot find value `Foo` in this scope
22+
}
23+
24+
type F = impl Future;
25+
// Check that statics are inhabited computes they layout.
26+
static POOL: Task<F> = Task::new();
27+
Task::spawn(&POOL, || cb());
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0425]: cannot find value `Foo` in this scope
2+
--> $DIR/layout-error.rs:21:17
3+
|
4+
LL | let a = Foo;
5+
| ^^^ not found in this scope
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0425`.

0 commit comments

Comments
 (0)