Rollup merge of #72764 - jonas-schievink:mind-the-tyerr, r=estebank
Be more careful around ty::Error in generators cc https://github.com/rust-lang/rust/issues/72685 (doesn't close it because it's missing a reproduction to use as a test case) r? @estebank
This commit is contained in:
commit
2cab88a33e
2 changed files with 54 additions and 31 deletions
|
|
@ -669,6 +669,51 @@ fn compute_storage_conflicts(
|
|||
storage_conflicts
|
||||
}
|
||||
|
||||
/// Validates the typeck view of the generator against the actual set of types retained between
|
||||
/// yield points.
|
||||
fn sanitize_witness<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
did: DefId,
|
||||
witness: Ty<'tcx>,
|
||||
upvars: &Vec<Ty<'tcx>>,
|
||||
retained: &BitSet<Local>,
|
||||
) {
|
||||
let allowed_upvars = tcx.erase_regions(upvars);
|
||||
let allowed = match witness.kind {
|
||||
ty::GeneratorWitness(s) => tcx.erase_late_bound_regions(&s),
|
||||
_ => {
|
||||
tcx.sess.delay_span_bug(
|
||||
body.span,
|
||||
&format!("unexpected generator witness type {:?}", witness.kind),
|
||||
);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let param_env = tcx.param_env(did);
|
||||
|
||||
for (local, decl) in body.local_decls.iter_enumerated() {
|
||||
// Ignore locals which are internal or not retained between yields.
|
||||
if !retained.contains(local) || decl.internal {
|
||||
continue;
|
||||
}
|
||||
let decl_ty = tcx.normalize_erasing_regions(param_env, decl.ty);
|
||||
|
||||
// Sanity check that typeck knows about the type of locals which are
|
||||
// live across a suspension point
|
||||
if !allowed.contains(&decl_ty) && !allowed_upvars.contains(&decl_ty) {
|
||||
span_bug!(
|
||||
body.span,
|
||||
"Broken MIR: generator contains type {} in MIR, \
|
||||
but typeck only knows about {}",
|
||||
decl.ty,
|
||||
witness,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_layout<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
source: MirSource<'tcx>,
|
||||
|
|
@ -690,35 +735,7 @@ fn compute_layout<'tcx>(
|
|||
storage_liveness,
|
||||
} = locals_live_across_suspend_points(tcx, body, source, always_live_locals, movable);
|
||||
|
||||
// Erase regions from the types passed in from typeck so we can compare them with
|
||||
// MIR types
|
||||
let allowed_upvars = tcx.erase_regions(upvars);
|
||||
let allowed = match interior.kind {
|
||||
ty::GeneratorWitness(s) => tcx.erase_late_bound_regions(&s),
|
||||
_ => bug!(),
|
||||
};
|
||||
|
||||
let param_env = tcx.param_env(source.def_id());
|
||||
|
||||
for (local, decl) in body.local_decls.iter_enumerated() {
|
||||
// Ignore locals which are internal or not live
|
||||
if !live_locals.contains(local) || decl.internal {
|
||||
continue;
|
||||
}
|
||||
let decl_ty = tcx.normalize_erasing_regions(param_env, decl.ty);
|
||||
|
||||
// Sanity check that typeck knows about the type of locals which are
|
||||
// live across a suspension point
|
||||
if !allowed.contains(&decl_ty) && !allowed_upvars.contains(&decl_ty) {
|
||||
span_bug!(
|
||||
body.span,
|
||||
"Broken MIR: generator contains type {} in MIR, \
|
||||
but typeck only knows about {}",
|
||||
decl.ty,
|
||||
interior
|
||||
);
|
||||
}
|
||||
}
|
||||
sanitize_witness(tcx, body, source.def_id(), interior, upvars, &live_locals);
|
||||
|
||||
// Gather live local types and their indices.
|
||||
let mut locals = IndexVec::<GeneratorSavedLocal, _>::new();
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
ty::Generator(_, substs, _) => {
|
||||
ty::Generator(def_id, substs, _) => {
|
||||
let substs = substs.as_generator();
|
||||
for upvar_ty in substs.upvar_tys() {
|
||||
queue_type(self, upvar_ty);
|
||||
|
|
@ -108,7 +108,13 @@ where
|
|||
let witness = substs.witness();
|
||||
let interior_tys = match &witness.kind {
|
||||
ty::GeneratorWitness(tys) => tcx.erase_late_bound_regions(tys),
|
||||
_ => bug!(),
|
||||
_ => {
|
||||
tcx.sess.delay_span_bug(
|
||||
tcx.hir().span_if_local(def_id).unwrap_or(DUMMY_SP),
|
||||
&format!("unexpected generator witness type {:?}", witness),
|
||||
);
|
||||
return Some(Err(AlwaysRequiresDrop));
|
||||
}
|
||||
};
|
||||
|
||||
for interior_ty in interior_tys {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue