1
Fork 0

Ban ArrayToPointer and MutToConstPointer from runtime MIR

Apparently MIR borrowck cares about at least one of these for checking variance.

In runtime MIR, though, there's no need for them as `PtrToPtr` does the same thing.

(Banning them simplifies passes like GVN that no longer need to handle multiple cast possibilities.)
This commit is contained in:
Scott McMurray 2024-06-12 01:22:31 -07:00
parent 894f7a4ba6
commit 4630d1b23b
21 changed files with 60 additions and 32 deletions

View file

@ -18,7 +18,8 @@
use crate::MirPass;
use rustc_middle::mir::coverage::CoverageKind;
use rustc_middle::mir::{Body, BorrowKind, Rvalue, StatementKind, TerminatorKind};
use rustc_middle::mir::{Body, BorrowKind, CastKind, Rvalue, StatementKind, TerminatorKind};
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::TyCtxt;
pub struct CleanupPostBorrowck;
@ -36,6 +37,22 @@ impl<'tcx> MirPass<'tcx> for CleanupPostBorrowck {
CoverageKind::BlockMarker { .. } | CoverageKind::SpanMarker { .. },
)
| StatementKind::FakeRead(..) => statement.make_nop(),
StatementKind::Assign(box (
_,
Rvalue::Cast(
ref mut cast_kind @ CastKind::PointerCoercion(
PointerCoercion::ArrayToPointer
| PointerCoercion::MutToConstPointer,
),
..,
),
)) => {
// BorrowCk needed to track whether these cases were coercions or casts,
// to know whether to check lifetimes in their pointees,
// but from now on that distinction doesn't matter,
// so just make them ordinary pointer casts instead.
*cast_kind = CastKind::PtrToPtr;
}
_ => (),
}
}

View file

@ -571,11 +571,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
let ret = self.ecx.ptr_to_ptr(&src, to).ok()?;
ret.into()
}
CastKind::PointerCoercion(
ty::adjustment::PointerCoercion::MutToConstPointer
| ty::adjustment::PointerCoercion::ArrayToPointer
| ty::adjustment::PointerCoercion::UnsafeFnPointer,
) => {
CastKind::PointerCoercion(ty::adjustment::PointerCoercion::UnsafeFnPointer) => {
let src = self.evaluated[value].as_ref()?;
let src = self.ecx.read_immediate(src).ok()?;
let to = self.ecx.layout_of(to).ok()?;
@ -1164,10 +1160,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
}
}
if let PtrToPtr | PointerCoercion(MutToConstPointer) = kind
if let PtrToPtr = kind
&& let Value::Cast { kind: inner_kind, value: inner_value, from: inner_from, to: _ } =
*self.get(value)
&& let PtrToPtr | PointerCoercion(MutToConstPointer) = inner_kind
&& let PtrToPtr = inner_kind
{
from = inner_from;
value = inner_value;

View file

@ -51,11 +51,11 @@ mod abort_unwinding_calls;
mod add_call_guards;
mod add_moves_for_packed_drops;
mod add_retag;
mod add_subtyping_projections;
mod check_alignment;
mod check_const_item_mutation;
mod check_packed_ref;
mod remove_place_mention;
// This pass is public to allow external drivers to perform MIR cleanup
mod add_subtyping_projections;
pub mod cleanup_post_borrowck;
mod copy_prop;
mod coroutine;
@ -94,6 +94,7 @@ mod prettify;
mod promote_consts;
mod ref_prop;
mod remove_noop_landing_pads;
mod remove_place_mention;
mod remove_storage_markers;
mod remove_uninit_drops;
mod remove_unneeded_drops;
@ -103,7 +104,6 @@ mod reveal_all;
mod shim;
mod ssa;
// This pass is public to allow external drivers to perform MIR cleanup
mod check_alignment;
pub mod simplify;
mod simplify_branches;
mod simplify_comparison_integral;

View file

@ -1188,6 +1188,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
"CastKind::{kind:?} output must be a raw const pointer, not {:?}",
ty::RawPtr(_, Mutability::Not)
);
if self.mir_phase >= MirPhase::Analysis(AnalysisPhase::PostCleanup) {
self.fail(location, format!("After borrowck, MIR disallows {kind:?}"));
}
}
CastKind::PointerCoercion(PointerCoercion::ArrayToPointer) => {
// FIXME: Check pointee types
@ -1201,6 +1204,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
"CastKind::{kind:?} output must be a raw pointer, not {:?}",
ty::RawPtr(..)
);
if self.mir_phase >= MirPhase::Analysis(AnalysisPhase::PostCleanup) {
self.fail(location, format!("After borrowck, MIR disallows {kind:?}"));
}
}
CastKind::PointerCoercion(PointerCoercion::Unsize) => {
// This is used for all `CoerceUnsized` types,
@ -1212,7 +1218,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
if !input_valid || !target_valid {
self.fail(
location,
format!("Wrong cast kind {kind:?} for the type {op_ty}",),
format!("Wrong cast kind {kind:?} for the type {op_ty}"),
);
}
}