1
Fork 0

Enable drop_tracking_mir by default.

This commit is contained in:
Camille GILLOT 2023-01-28 12:56:04 +00:00
parent a626caaad9
commit 286502c9ed
29 changed files with 114 additions and 2513 deletions

View file

@ -853,60 +853,7 @@ impl StorageConflictVisitor<'_, '_, '_> {
}
}
/// Validates the typeck view of the generator against the actual set of types saved between
/// yield points.
fn sanitize_witness<'tcx>(
tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
witness: Ty<'tcx>,
upvars: &'tcx ty::List<Ty<'tcx>>,
layout: &GeneratorLayout<'tcx>,
) {
let did = body.source.def_id();
let param_env = tcx.param_env(did);
let allowed_upvars = tcx.normalize_erasing_regions(param_env, upvars);
let allowed = match witness.kind() {
&ty::GeneratorWitness(interior_tys) => {
tcx.normalize_erasing_late_bound_regions(param_env, interior_tys)
}
_ => {
tcx.sess.delay_span_bug(
body.span,
format!("unexpected generator witness type {:?}", witness.kind()),
);
return;
}
};
let mut mismatches = Vec::new();
for fty in &layout.field_tys {
if fty.ignore_for_traits {
continue;
}
let decl_ty = tcx.normalize_erasing_regions(param_env, fty.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) {
mismatches.push(decl_ty);
}
}
if !mismatches.is_empty() {
span_bug!(
body.span,
"Broken MIR: generator contains type {:?} in MIR, \
but typeck only knows about {} and {:?}",
mismatches,
allowed,
allowed_upvars
);
}
}
fn compute_layout<'tcx>(
tcx: TyCtxt<'tcx>,
liveness: LivenessInfo,
body: &Body<'tcx>,
) -> (
@ -932,27 +879,20 @@ fn compute_layout<'tcx>(
let decl = &body.local_decls[local];
debug!(?decl);
let ignore_for_traits = if tcx.sess.opts.unstable_opts.drop_tracking_mir {
// Do not `assert_crate_local` here, as post-borrowck cleanup may have already cleared
// the information. This is alright, since `ignore_for_traits` is only relevant when
// this code runs on pre-cleanup MIR, and `ignore_for_traits = false` is the safer
// default.
match decl.local_info {
// Do not include raw pointers created from accessing `static` items, as those could
// well be re-created by another access to the same static.
ClearCrossCrate::Set(box LocalInfo::StaticRef { is_thread_local, .. }) => {
!is_thread_local
}
// Fake borrows are only read by fake reads, so do not have any reality in
// post-analysis MIR.
ClearCrossCrate::Set(box LocalInfo::FakeBorrow) => true,
_ => false,
// Do not `assert_crate_local` here, as post-borrowck cleanup may have already cleared
// the information. This is alright, since `ignore_for_traits` is only relevant when
// this code runs on pre-cleanup MIR, and `ignore_for_traits = false` is the safer
// default.
let ignore_for_traits = match decl.local_info {
// Do not include raw pointers created from accessing `static` items, as those could
// well be re-created by another access to the same static.
ClearCrossCrate::Set(box LocalInfo::StaticRef { is_thread_local, .. }) => {
!is_thread_local
}
} else {
// FIXME(#105084) HIR-based drop tracking does not account for all the temporaries that
// MIR building may introduce. This leads to wrongly ignored types, but this is
// necessary for internal consistency and to avoid ICEs.
decl.internal
// Fake borrows are only read by fake reads, so do not have any reality in
// post-analysis MIR.
ClearCrossCrate::Set(box LocalInfo::FakeBorrow) => true,
_ => false,
};
let decl =
GeneratorSavedTy { ty: decl.ty, source_info: decl.source_info, ignore_for_traits };
@ -1445,8 +1385,6 @@ pub(crate) fn mir_generator_witnesses<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: LocalDefId,
) -> Option<GeneratorLayout<'tcx>> {
assert!(tcx.sess.opts.unstable_opts.drop_tracking_mir);
let (body, _) = tcx.mir_promoted(def_id);
let body = body.borrow();
let body = &*body;
@ -1469,7 +1407,7 @@ pub(crate) fn mir_generator_witnesses<'tcx>(
// Extract locals which are live across suspension point into `layout`
// `remap` gives a mapping from local indices onto generator struct indices
// `storage_liveness` tells us which locals have live storage at suspension points
let (_, generator_layout, _) = compute_layout(tcx, liveness_info, body);
let (_, generator_layout, _) = compute_layout(liveness_info, body);
check_suspend_tys(tcx, &generator_layout, &body);
@ -1489,15 +1427,10 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
let gen_ty = body.local_decls.raw[1].ty;
// Get the discriminant type and args which typeck computed
let (discr_ty, upvars, interior, movable) = match *gen_ty.kind() {
let (discr_ty, movable) = match *gen_ty.kind() {
ty::Generator(_, args, movability) => {
let args = args.as_generator();
(
args.discr_ty(tcx),
args.upvar_tys(),
args.witness(),
movability == hir::Movability::Movable,
)
(args.discr_ty(tcx), movability == hir::Movability::Movable)
}
_ => {
tcx.sess.delay_span_bug(body.span, format!("unexpected generator type {gen_ty}"));
@ -1574,13 +1507,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
// Extract locals which are live across suspension point into `layout`
// `remap` gives a mapping from local indices onto generator struct indices
// `storage_liveness` tells us which locals have live storage at suspension points
let (remap, layout, storage_liveness) = compute_layout(tcx, liveness_info, body);
if tcx.sess.opts.unstable_opts.validate_mir
&& !tcx.sess.opts.unstable_opts.drop_tracking_mir
{
sanitize_witness(tcx, body, interior, upvars, &layout);
}
let (remap, layout, storage_liveness) = compute_layout(liveness_info, body);
let can_return = can_return(tcx, body, tcx.param_env(body.source.def_id()));

View file

@ -358,9 +358,7 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
/// mir borrowck *before* doing so in order to ensure that borrowck can be run and doesn't
/// end up missing the source MIR due to stealing happening.
fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> {
if tcx.sess.opts.unstable_opts.drop_tracking_mir
&& let DefKind::Generator = tcx.def_kind(def)
{
if let DefKind::Generator = tcx.def_kind(def) {
tcx.ensure_with_value().mir_generator_witnesses(def);
}
let mir_borrowck = tcx.mir_borrowck(def);