Skip to content

Commit c5f2de0

Browse files
authored
Rollup merge of rust-lang#72764 - jonas-schievink:mind-the-tyerr, r=estebank
Be more careful around ty::Error in generators cc rust-lang#72685 (doesn't close it because it's missing a reproduction to use as a test case) r? @estebank
2 parents 78e7b45 + 7242bda commit c5f2de0

File tree

2 files changed

+51
-28
lines changed

2 files changed

+51
-28
lines changed

src/librustc_mir/transform/generator.rs

+43-26
Original file line numberDiff line numberDiff line change
@@ -669,40 +669,33 @@ fn compute_storage_conflicts(
669669
storage_conflicts
670670
}
671671

672-
fn compute_layout<'tcx>(
672+
/// Validates the typeck view of the generator against the actual set of types retained between
673+
/// yield points.
674+
fn sanitize_witness<'tcx>(
673675
tcx: TyCtxt<'tcx>,
674-
source: MirSource<'tcx>,
676+
body: &Body<'tcx>,
677+
did: DefId,
678+
witness: Ty<'tcx>,
675679
upvars: &Vec<Ty<'tcx>>,
676-
interior: Ty<'tcx>,
677-
always_live_locals: &storage::AlwaysLiveLocals,
678-
movable: bool,
679-
body: &mut Body<'tcx>,
680-
) -> (
681-
FxHashMap<Local, (Ty<'tcx>, VariantIdx, usize)>,
682-
GeneratorLayout<'tcx>,
683-
IndexVec<BasicBlock, Option<BitSet<Local>>>,
680+
retained: &BitSet<Local>,
684681
) {
685-
// Use a liveness analysis to compute locals which are live across a suspension point
686-
let LivenessInfo {
687-
live_locals,
688-
live_locals_at_suspension_points,
689-
storage_conflicts,
690-
storage_liveness,
691-
} = locals_live_across_suspend_points(tcx, body, source, always_live_locals, movable);
692-
693-
// Erase regions from the types passed in from typeck so we can compare them with
694-
// MIR types
695682
let allowed_upvars = tcx.erase_regions(upvars);
696-
let allowed = match interior.kind {
683+
let allowed = match witness.kind {
697684
ty::GeneratorWitness(s) => tcx.erase_late_bound_regions(&s),
698-
_ => bug!(),
685+
_ => {
686+
tcx.sess.delay_span_bug(
687+
body.span,
688+
&format!("unexpected generator witness type {:?}", witness.kind),
689+
);
690+
return;
691+
}
699692
};
700693

701-
let param_env = tcx.param_env(source.def_id());
694+
let param_env = tcx.param_env(did);
702695

703696
for (local, decl) in body.local_decls.iter_enumerated() {
704-
// Ignore locals which are internal or not live
705-
if !live_locals.contains(local) || decl.internal {
697+
// Ignore locals which are internal or not retained between yields.
698+
if !retained.contains(local) || decl.internal {
706699
continue;
707700
}
708701
let decl_ty = tcx.normalize_erasing_regions(param_env, decl.ty);
@@ -715,10 +708,34 @@ fn compute_layout<'tcx>(
715708
"Broken MIR: generator contains type {} in MIR, \
716709
but typeck only knows about {}",
717710
decl.ty,
718-
interior
711+
witness,
719712
);
720713
}
721714
}
715+
}
716+
717+
fn compute_layout<'tcx>(
718+
tcx: TyCtxt<'tcx>,
719+
source: MirSource<'tcx>,
720+
upvars: &Vec<Ty<'tcx>>,
721+
interior: Ty<'tcx>,
722+
always_live_locals: &storage::AlwaysLiveLocals,
723+
movable: bool,
724+
body: &mut Body<'tcx>,
725+
) -> (
726+
FxHashMap<Local, (Ty<'tcx>, VariantIdx, usize)>,
727+
GeneratorLayout<'tcx>,
728+
IndexVec<BasicBlock, Option<BitSet<Local>>>,
729+
) {
730+
// Use a liveness analysis to compute locals which are live across a suspension point
731+
let LivenessInfo {
732+
live_locals,
733+
live_locals_at_suspension_points,
734+
storage_conflicts,
735+
storage_liveness,
736+
} = locals_live_across_suspend_points(tcx, body, source, always_live_locals, movable);
737+
738+
sanitize_witness(tcx, body, source.def_id(), interior, upvars, &live_locals);
722739

723740
// Gather live local types and their indices.
724741
let mut locals = IndexVec::<GeneratorSavedLocal, _>::new();

src/librustc_ty/needs_drop.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ where
9999
}
100100
}
101101

102-
ty::Generator(_, substs, _) => {
102+
ty::Generator(def_id, substs, _) => {
103103
let substs = substs.as_generator();
104104
for upvar_ty in substs.upvar_tys() {
105105
queue_type(self, upvar_ty);
@@ -108,7 +108,13 @@ where
108108
let witness = substs.witness();
109109
let interior_tys = match &witness.kind {
110110
ty::GeneratorWitness(tys) => tcx.erase_late_bound_regions(tys),
111-
_ => bug!(),
111+
_ => {
112+
tcx.sess.delay_span_bug(
113+
tcx.hir().span_if_local(def_id).unwrap_or(DUMMY_SP),
114+
&format!("unexpected generator witness type {:?}", witness),
115+
);
116+
return Some(Err(AlwaysRequiresDrop));
117+
}
112118
};
113119

114120
for interior_ty in interior_tys {

0 commit comments

Comments
 (0)