Add new Deinit
statement kind
This commit is contained in:
parent
d00e77078c
commit
9b6b1a625b
27 changed files with 141 additions and 66 deletions
|
@ -386,6 +386,7 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
|
||||||
|
|
||||||
mir::StatementKind::FakeRead(..)
|
mir::StatementKind::FakeRead(..)
|
||||||
| mir::StatementKind::SetDiscriminant { .. }
|
| mir::StatementKind::SetDiscriminant { .. }
|
||||||
|
| mir::StatementKind::Deinit(..)
|
||||||
| mir::StatementKind::StorageLive(..)
|
| mir::StatementKind::StorageLive(..)
|
||||||
| mir::StatementKind::Retag { .. }
|
| mir::StatementKind::Retag { .. }
|
||||||
| mir::StatementKind::AscribeUserType(..)
|
| mir::StatementKind::AscribeUserType(..)
|
||||||
|
|
|
@ -63,9 +63,6 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
|
||||||
StatementKind::FakeRead(box (_, _)) => {
|
StatementKind::FakeRead(box (_, _)) => {
|
||||||
// Only relevant for initialized/liveness/safety checks.
|
// Only relevant for initialized/liveness/safety checks.
|
||||||
}
|
}
|
||||||
StatementKind::SetDiscriminant { place, variant_index: _ } => {
|
|
||||||
self.mutate_place(location, **place, Shallow(None));
|
|
||||||
}
|
|
||||||
StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping {
|
StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping {
|
||||||
ref src,
|
ref src,
|
||||||
ref dst,
|
ref dst,
|
||||||
|
@ -91,6 +88,9 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
|
||||||
LocalMutationIsAllowed::Yes,
|
LocalMutationIsAllowed::Yes,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
StatementKind::Deinit(..) | StatementKind::SetDiscriminant { .. } => {
|
||||||
|
bug!("Statement not allowed in this MIR phase")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.super_statement(statement, location);
|
self.super_statement(statement, location);
|
||||||
|
|
|
@ -626,9 +626,6 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
|
||||||
flow_state,
|
flow_state,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
StatementKind::SetDiscriminant { place, variant_index: _ } => {
|
|
||||||
self.mutate_place(location, (**place, span), Shallow(None), flow_state);
|
|
||||||
}
|
|
||||||
StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping {
|
StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping {
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
|
@ -654,6 +651,9 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
|
||||||
flow_state,
|
flow_state,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
StatementKind::Deinit(..) | StatementKind::SetDiscriminant { .. } => {
|
||||||
|
bug!("Statement not allowed in this MIR phase")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1303,28 +1303,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StatementKind::SetDiscriminant { ref place, variant_index } => {
|
|
||||||
let place_type = place.ty(body, tcx).ty;
|
|
||||||
let adt = match place_type.kind() {
|
|
||||||
ty::Adt(adt, _) if adt.is_enum() => adt,
|
|
||||||
_ => {
|
|
||||||
span_bug!(
|
|
||||||
stmt.source_info.span,
|
|
||||||
"bad set discriminant ({:?} = {:?}): lhs is not an enum",
|
|
||||||
place,
|
|
||||||
variant_index
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if variant_index.as_usize() >= adt.variants().len() {
|
|
||||||
span_bug!(
|
|
||||||
stmt.source_info.span,
|
|
||||||
"bad set discriminant ({:?} = {:?}): value of of range",
|
|
||||||
place,
|
|
||||||
variant_index
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
StatementKind::AscribeUserType(box (ref place, ref projection), variance) => {
|
StatementKind::AscribeUserType(box (ref place, ref projection), variance) => {
|
||||||
let place_ty = place.ty(body, tcx).ty;
|
let place_ty = place.ty(body, tcx).ty;
|
||||||
if let Err(terr) = self.relate_type_and_user_type(
|
if let Err(terr) = self.relate_type_and_user_type(
|
||||||
|
@ -1358,6 +1336,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
| StatementKind::Retag { .. }
|
| StatementKind::Retag { .. }
|
||||||
| StatementKind::Coverage(..)
|
| StatementKind::Coverage(..)
|
||||||
| StatementKind::Nop => {}
|
| StatementKind::Nop => {}
|
||||||
|
StatementKind::Deinit(..) | StatementKind::SetDiscriminant { .. } => {
|
||||||
|
bug!("Statement not allowed in this MIR phase")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -772,6 +772,7 @@ fn codegen_stmt<'tcx>(
|
||||||
}
|
}
|
||||||
StatementKind::StorageLive(_)
|
StatementKind::StorageLive(_)
|
||||||
| StatementKind::StorageDead(_)
|
| StatementKind::StorageDead(_)
|
||||||
|
| StatementKind::Deinit(_)
|
||||||
| StatementKind::Nop
|
| StatementKind::Nop
|
||||||
| StatementKind::FakeRead(..)
|
| StatementKind::FakeRead(..)
|
||||||
| StatementKind::Retag { .. }
|
| StatementKind::Retag { .. }
|
||||||
|
|
|
@ -518,6 +518,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
|
||||||
StatementKind::Assign(_)
|
StatementKind::Assign(_)
|
||||||
| StatementKind::FakeRead(_)
|
| StatementKind::FakeRead(_)
|
||||||
| StatementKind::SetDiscriminant { .. }
|
| StatementKind::SetDiscriminant { .. }
|
||||||
|
| StatementKind::Deinit(_)
|
||||||
| StatementKind::StorageLive(_)
|
| StatementKind::StorageLive(_)
|
||||||
| StatementKind::StorageDead(_)
|
| StatementKind::StorageDead(_)
|
||||||
| StatementKind::Retag(_, _)
|
| StatementKind::Retag(_, _)
|
||||||
|
|
|
@ -48,6 +48,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
.codegen_set_discr(&mut bx, variant_index);
|
.codegen_set_discr(&mut bx, variant_index);
|
||||||
bx
|
bx
|
||||||
}
|
}
|
||||||
|
mir::StatementKind::Deinit(..) => {
|
||||||
|
// For now, don't codegen this to anything. In the future it may be worth
|
||||||
|
// experimenting with what kind of information we can emit to LLVM without hurting
|
||||||
|
// perf here
|
||||||
|
bx
|
||||||
|
}
|
||||||
mir::StatementKind::StorageLive(local) => {
|
mir::StatementKind::StorageLive(local) => {
|
||||||
if let LocalRef::Place(cg_place) = self.locals[local] {
|
if let LocalRef::Place(cg_place) = self.locals[local] {
|
||||||
cg_place.storage_live(&mut bx);
|
cg_place.storage_live(&mut bx);
|
||||||
|
|
|
@ -890,6 +890,11 @@ impl<'tcx, 'a, Tag: Provenance, Extra> AllocRefMut<'a, 'tcx, Tag, Extra> {
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
self.write_scalar(alloc_range(offset, self.tcx.data_layout().pointer_size), val)
|
self.write_scalar(alloc_range(offset, self.tcx.data_layout().pointer_size), val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Mark the entire referenced range as uninitalized
|
||||||
|
pub fn write_uninit(&mut self) {
|
||||||
|
self.alloc.mark_init(self.range, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, 'a, Tag: Provenance, Extra> AllocRef<'a, 'tcx, Tag, Extra> {
|
impl<'tcx, 'a, Tag: Provenance, Extra> AllocRef<'a, 'tcx, Tag, Extra> {
|
||||||
|
|
|
@ -791,6 +791,42 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn write_uninit(&mut self, dest: &PlaceTy<'tcx, M::PointerTag>) -> InterpResult<'tcx> {
|
||||||
|
let mplace = match dest.place {
|
||||||
|
Place::Ptr(mplace) => MPlaceTy { mplace, layout: dest.layout },
|
||||||
|
Place::Local { frame, local } => {
|
||||||
|
match M::access_local_mut(self, frame, local)? {
|
||||||
|
Ok(local) => match dest.layout.abi {
|
||||||
|
Abi::Scalar(_) => {
|
||||||
|
*local = LocalValue::Live(Operand::Immediate(Immediate::Scalar(
|
||||||
|
ScalarMaybeUninit::Uninit,
|
||||||
|
)));
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
Abi::ScalarPair(..) => {
|
||||||
|
*local = LocalValue::Live(Operand::Immediate(Immediate::ScalarPair(
|
||||||
|
ScalarMaybeUninit::Uninit,
|
||||||
|
ScalarMaybeUninit::Uninit,
|
||||||
|
)));
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
_ => self.force_allocation(dest)?,
|
||||||
|
},
|
||||||
|
Err(mplace) => {
|
||||||
|
// The local is in memory, go on below.
|
||||||
|
MPlaceTy { mplace, layout: dest.layout }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let Some(mut alloc) = self.get_place_alloc_mut(&mplace)? else {
|
||||||
|
// Zero-sized access
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
alloc.write_uninit();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Copies the data from an operand to a place. This does not support transmuting!
|
/// Copies the data from an operand to a place. This does not support transmuting!
|
||||||
/// Use `copy_op_transmute` if the layouts could disagree.
|
/// Use `copy_op_transmute` if the layouts could disagree.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|
|
@ -90,6 +90,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
self.write_discriminant(*variant_index, &dest)?;
|
self.write_discriminant(*variant_index, &dest)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Deinit(place) => {
|
||||||
|
let dest = self.eval_place(**place)?;
|
||||||
|
self.write_uninit(&dest)?;
|
||||||
|
}
|
||||||
|
|
||||||
// Mark locals as alive
|
// Mark locals as alive
|
||||||
StorageLive(local) => {
|
StorageLive(local) => {
|
||||||
self.storage_live(*local)?;
|
self.storage_live(*local)?;
|
||||||
|
|
|
@ -692,6 +692,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
match statement.kind {
|
match statement.kind {
|
||||||
StatementKind::Assign(..)
|
StatementKind::Assign(..)
|
||||||
| StatementKind::SetDiscriminant { .. }
|
| StatementKind::SetDiscriminant { .. }
|
||||||
|
| StatementKind::Deinit(..)
|
||||||
| StatementKind::FakeRead(..)
|
| StatementKind::FakeRead(..)
|
||||||
| StatementKind::StorageLive(_)
|
| StatementKind::StorageLive(_)
|
||||||
| StatementKind::StorageDead(_)
|
| StatementKind::StorageDead(_)
|
||||||
|
|
|
@ -346,9 +346,24 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||||
self.fail(location, format!("bad arg ({:?} != usize)", op_cnt_ty))
|
self.fail(location, format!("bad arg ({:?} != usize)", op_cnt_ty))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StatementKind::SetDiscriminant { .. } => {
|
StatementKind::SetDiscriminant { place, .. } => {
|
||||||
if self.mir_phase < MirPhase::DropsLowered {
|
if self.mir_phase < MirPhase::Deaggregated {
|
||||||
self.fail(location, "`SetDiscriminant` is not allowed until drop elaboration");
|
self.fail(location, "`SetDiscriminant`is not allowed until deaggregation");
|
||||||
|
}
|
||||||
|
let pty = place.ty(&self.body.local_decls, self.tcx).ty.kind();
|
||||||
|
if !matches!(pty, ty::Adt(..) | ty::Generator(..) | ty::Opaque(..)) {
|
||||||
|
self.fail(
|
||||||
|
location,
|
||||||
|
format!(
|
||||||
|
"`SetDiscriminant` is only allowed on ADTs and generators, not {:?}",
|
||||||
|
pty
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StatementKind::Deinit(..) => {
|
||||||
|
if self.mir_phase < MirPhase::Deaggregated {
|
||||||
|
self.fail(location, "`Deinit`is not allowed until deaggregation");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StatementKind::Retag(_, _) => {
|
StatementKind::Retag(_, _) => {
|
||||||
|
|
|
@ -14,22 +14,26 @@ use std::iter::TrustedLen;
|
||||||
/// (lhs as Variant).field1 = arg1;
|
/// (lhs as Variant).field1 = arg1;
|
||||||
/// discriminant(lhs) = variant_index; // If lhs is an enum or generator.
|
/// discriminant(lhs) = variant_index; // If lhs is an enum or generator.
|
||||||
pub fn expand_aggregate<'tcx>(
|
pub fn expand_aggregate<'tcx>(
|
||||||
mut lhs: Place<'tcx>,
|
orig_lhs: Place<'tcx>,
|
||||||
operands: impl Iterator<Item = (Operand<'tcx>, Ty<'tcx>)> + TrustedLen,
|
operands: impl Iterator<Item = (Operand<'tcx>, Ty<'tcx>)> + TrustedLen,
|
||||||
kind: AggregateKind<'tcx>,
|
kind: AggregateKind<'tcx>,
|
||||||
source_info: SourceInfo,
|
source_info: SourceInfo,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
) -> impl Iterator<Item = Statement<'tcx>> + TrustedLen {
|
) -> impl Iterator<Item = Statement<'tcx>> + TrustedLen {
|
||||||
|
let mut lhs = orig_lhs;
|
||||||
let mut set_discriminant = None;
|
let mut set_discriminant = None;
|
||||||
let active_field_index = match kind {
|
let active_field_index = match kind {
|
||||||
AggregateKind::Adt(adt_did, variant_index, _, _, active_field_index) => {
|
AggregateKind::Adt(adt_did, variant_index, _, _, active_field_index) => {
|
||||||
let adt_def = tcx.adt_def(adt_did);
|
let adt_def = tcx.adt_def(adt_did);
|
||||||
if adt_def.is_enum() {
|
if adt_def.is_enum() {
|
||||||
set_discriminant = Some(Statement {
|
set_discriminant = Some(Statement {
|
||||||
kind: StatementKind::SetDiscriminant { place: Box::new(lhs), variant_index },
|
kind: StatementKind::SetDiscriminant {
|
||||||
|
place: Box::new(orig_lhs),
|
||||||
|
variant_index,
|
||||||
|
},
|
||||||
source_info,
|
source_info,
|
||||||
});
|
});
|
||||||
lhs = tcx.mk_place_downcast(lhs, adt_def, variant_index);
|
lhs = tcx.mk_place_downcast(orig_lhs, adt_def, variant_index);
|
||||||
}
|
}
|
||||||
active_field_index
|
active_field_index
|
||||||
}
|
}
|
||||||
|
@ -38,7 +42,7 @@ pub fn expand_aggregate<'tcx>(
|
||||||
// variant 0 (Unresumed).
|
// variant 0 (Unresumed).
|
||||||
let variant_index = VariantIdx::new(0);
|
let variant_index = VariantIdx::new(0);
|
||||||
set_discriminant = Some(Statement {
|
set_discriminant = Some(Statement {
|
||||||
kind: StatementKind::SetDiscriminant { place: Box::new(lhs), variant_index },
|
kind: StatementKind::SetDiscriminant { place: Box::new(orig_lhs), variant_index },
|
||||||
source_info,
|
source_info,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -50,18 +54,12 @@ pub fn expand_aggregate<'tcx>(
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
operands
|
let operands = operands.enumerate().map(move |(i, (op, ty))| {
|
||||||
.enumerate()
|
|
||||||
.map(move |(i, (op, ty))| {
|
|
||||||
let lhs_field = if let AggregateKind::Array(_) = kind {
|
let lhs_field = if let AggregateKind::Array(_) = kind {
|
||||||
let offset = u64::try_from(i).unwrap();
|
let offset = u64::try_from(i).unwrap();
|
||||||
tcx.mk_place_elem(
|
tcx.mk_place_elem(
|
||||||
lhs,
|
lhs,
|
||||||
ProjectionElem::ConstantIndex {
|
ProjectionElem::ConstantIndex { offset, min_length: offset + 1, from_end: false },
|
||||||
offset,
|
|
||||||
min_length: offset + 1,
|
|
||||||
from_end: false,
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
let field = Field::new(active_field_index.unwrap_or(i));
|
let field = Field::new(active_field_index.unwrap_or(i));
|
||||||
|
@ -71,6 +69,9 @@ pub fn expand_aggregate<'tcx>(
|
||||||
source_info,
|
source_info,
|
||||||
kind: StatementKind::Assign(Box::new((lhs_field, Rvalue::Use(op)))),
|
kind: StatementKind::Assign(Box::new((lhs_field, Rvalue::Use(op)))),
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
[Statement { source_info, kind: StatementKind::Deinit(Box::new(orig_lhs)) }]
|
||||||
|
.into_iter()
|
||||||
|
.chain(operands)
|
||||||
.chain(set_discriminant)
|
.chain(set_discriminant)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1590,6 +1590,8 @@ pub enum StatementKind<'tcx> {
|
||||||
/// Write the discriminant for a variant to the enum Place.
|
/// Write the discriminant for a variant to the enum Place.
|
||||||
SetDiscriminant { place: Box<Place<'tcx>>, variant_index: VariantIdx },
|
SetDiscriminant { place: Box<Place<'tcx>>, variant_index: VariantIdx },
|
||||||
|
|
||||||
|
Deinit(Box<Place<'tcx>>),
|
||||||
|
|
||||||
/// Start a live range for the storage of the local.
|
/// Start a live range for the storage of the local.
|
||||||
StorageLive(Local),
|
StorageLive(Local),
|
||||||
|
|
||||||
|
@ -1739,6 +1741,7 @@ impl Debug for Statement<'_> {
|
||||||
SetDiscriminant { ref place, variant_index } => {
|
SetDiscriminant { ref place, variant_index } => {
|
||||||
write!(fmt, "discriminant({:?}) = {:?}", place, variant_index)
|
write!(fmt, "discriminant({:?}) = {:?}", place, variant_index)
|
||||||
}
|
}
|
||||||
|
Deinit(ref place) => write!(fmt, "Deinit({:?})", place),
|
||||||
AscribeUserType(box (ref place, ref c_ty), ref variance) => {
|
AscribeUserType(box (ref place, ref c_ty), ref variance) => {
|
||||||
write!(fmt, "AscribeUserType({:?}, {:?}, {:?})", place, variance, c_ty)
|
write!(fmt, "AscribeUserType({:?}, {:?}, {:?})", place, variance, c_ty)
|
||||||
}
|
}
|
||||||
|
|
|
@ -243,6 +243,7 @@ pub fn statement_kind_name(statement: &Statement<'_>) -> &'static str {
|
||||||
Assign(..) => "Assign",
|
Assign(..) => "Assign",
|
||||||
FakeRead(..) => "FakeRead",
|
FakeRead(..) => "FakeRead",
|
||||||
SetDiscriminant { .. } => "SetDiscriminant",
|
SetDiscriminant { .. } => "SetDiscriminant",
|
||||||
|
Deinit(..) => "Deinit",
|
||||||
StorageLive(..) => "StorageLive",
|
StorageLive(..) => "StorageLive",
|
||||||
StorageDead(..) => "StorageDead",
|
StorageDead(..) => "StorageDead",
|
||||||
Retag(..) => "Retag",
|
Retag(..) => "Retag",
|
||||||
|
|
|
@ -399,6 +399,13 @@ macro_rules! make_mir_visitor {
|
||||||
location
|
location
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
StatementKind::Deinit(place) => {
|
||||||
|
self.visit_place(
|
||||||
|
place,
|
||||||
|
PlaceContext::MutatingUse(MutatingUseContext::Store),
|
||||||
|
location
|
||||||
|
)
|
||||||
|
}
|
||||||
StatementKind::StorageLive(local) => {
|
StatementKind::StorageLive(local) => {
|
||||||
self.visit_local(
|
self.visit_local(
|
||||||
local,
|
local,
|
||||||
|
|
|
@ -131,7 +131,8 @@ impl<'mir, 'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'mir, 'tc
|
||||||
|
|
||||||
// If a place is assigned to in a statement, it needs storage for that statement.
|
// If a place is assigned to in a statement, it needs storage for that statement.
|
||||||
StatementKind::Assign(box (place, _))
|
StatementKind::Assign(box (place, _))
|
||||||
| StatementKind::SetDiscriminant { box place, .. } => {
|
| StatementKind::SetDiscriminant { box place, .. }
|
||||||
|
| StatementKind::Deinit(box place) => {
|
||||||
trans.gen(place.local);
|
trans.gen(place.local);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -296,10 +296,10 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
|
||||||
StatementKind::StorageDead(local) => {
|
StatementKind::StorageDead(local) => {
|
||||||
self.gather_move(Place::from(*local));
|
self.gather_move(Place::from(*local));
|
||||||
}
|
}
|
||||||
StatementKind::SetDiscriminant { .. } => {
|
StatementKind::SetDiscriminant { .. } | StatementKind::Deinit(..) => {
|
||||||
span_bug!(
|
span_bug!(
|
||||||
stmt.source_info.span,
|
stmt.source_info.span,
|
||||||
"SetDiscriminant should not exist during borrowck"
|
"SetDiscriminant/Deinit should not exist during borrowck"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
StatementKind::Retag { .. }
|
StatementKind::Retag { .. }
|
||||||
|
|
|
@ -97,6 +97,7 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> {
|
||||||
StatementKind::Assign(..)
|
StatementKind::Assign(..)
|
||||||
| StatementKind::FakeRead(..)
|
| StatementKind::FakeRead(..)
|
||||||
| StatementKind::SetDiscriminant { .. }
|
| StatementKind::SetDiscriminant { .. }
|
||||||
|
| StatementKind::Deinit(..)
|
||||||
| StatementKind::StorageLive(..)
|
| StatementKind::StorageLive(..)
|
||||||
| StatementKind::StorageDead(..)
|
| StatementKind::StorageDead(..)
|
||||||
| StatementKind::Retag { .. }
|
| StatementKind::Retag { .. }
|
||||||
|
|
|
@ -827,6 +827,7 @@ pub(super) fn filtered_statement_span(statement: &Statement<'_>) -> Option<Span>
|
||||||
| StatementKind::CopyNonOverlapping(..)
|
| StatementKind::CopyNonOverlapping(..)
|
||||||
| StatementKind::Assign(_)
|
| StatementKind::Assign(_)
|
||||||
| StatementKind::SetDiscriminant { .. }
|
| StatementKind::SetDiscriminant { .. }
|
||||||
|
| StatementKind::Deinit(..)
|
||||||
| StatementKind::Retag(_, _)
|
| StatementKind::Retag(_, _)
|
||||||
| StatementKind::AscribeUserType(_, _) => {
|
| StatementKind::AscribeUserType(_, _) => {
|
||||||
Some(statement.source_info.span)
|
Some(statement.source_info.span)
|
||||||
|
|
|
@ -530,6 +530,7 @@ impl<'a> Conflicts<'a> {
|
||||||
StatementKind::Assign(_) => {}
|
StatementKind::Assign(_) => {}
|
||||||
|
|
||||||
StatementKind::SetDiscriminant { .. }
|
StatementKind::SetDiscriminant { .. }
|
||||||
|
| StatementKind::Deinit(..)
|
||||||
| StatementKind::StorageLive(..)
|
| StatementKind::StorageLive(..)
|
||||||
| StatementKind::StorageDead(..)
|
| StatementKind::StorageDead(..)
|
||||||
| StatementKind::Retag(..)
|
| StatementKind::Retag(..)
|
||||||
|
|
|
@ -1441,6 +1441,7 @@ impl<'tcx> Visitor<'tcx> for EnsureGeneratorFieldAssignmentsNeverAlias<'_> {
|
||||||
|
|
||||||
StatementKind::FakeRead(..)
|
StatementKind::FakeRead(..)
|
||||||
| StatementKind::SetDiscriminant { .. }
|
| StatementKind::SetDiscriminant { .. }
|
||||||
|
| StatementKind::Deinit(..)
|
||||||
| StatementKind::StorageLive(_)
|
| StatementKind::StorageLive(_)
|
||||||
| StatementKind::StorageDead(_)
|
| StatementKind::StorageDead(_)
|
||||||
| StatementKind::Retag(..)
|
| StatementKind::Retag(..)
|
||||||
|
|
|
@ -50,6 +50,7 @@ impl RemoveNoopLandingPads {
|
||||||
|
|
||||||
StatementKind::Assign { .. }
|
StatementKind::Assign { .. }
|
||||||
| StatementKind::SetDiscriminant { .. }
|
| StatementKind::SetDiscriminant { .. }
|
||||||
|
| StatementKind::Deinit(..)
|
||||||
| StatementKind::CopyNonOverlapping(..)
|
| StatementKind::CopyNonOverlapping(..)
|
||||||
| StatementKind::Retag { .. } => {
|
| StatementKind::Retag { .. } => {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -21,7 +21,9 @@ impl<'tcx> MirPass<'tcx> for RemoveZsts {
|
||||||
let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
|
let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
|
||||||
for block in basic_blocks.iter_mut() {
|
for block in basic_blocks.iter_mut() {
|
||||||
for statement in block.statements.iter_mut() {
|
for statement in block.statements.iter_mut() {
|
||||||
if let StatementKind::Assign(box (place, _)) = statement.kind {
|
if let StatementKind::Assign(box (place, _)) | StatementKind::Deinit(box place) =
|
||||||
|
statement.kind
|
||||||
|
{
|
||||||
let place_ty = place.ty(local_decls, tcx).ty;
|
let place_ty = place.ty(local_decls, tcx).ty;
|
||||||
if !maybe_zst(place_ty) {
|
if !maybe_zst(place_ty) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -242,6 +242,7 @@ fn is_likely_const<'tcx>(mut tracked_place: Place<'tcx>, block: &BasicBlockData<
|
||||||
// These statements have no influence on the place
|
// These statements have no influence on the place
|
||||||
// we are interested in
|
// we are interested in
|
||||||
StatementKind::FakeRead(_)
|
StatementKind::FakeRead(_)
|
||||||
|
| StatementKind::Deinit(_)
|
||||||
| StatementKind::StorageLive(_)
|
| StatementKind::StorageLive(_)
|
||||||
| StatementKind::Retag(_, _)
|
| StatementKind::Retag(_, _)
|
||||||
| StatementKind::AscribeUserType(_, _)
|
| StatementKind::AscribeUserType(_, _)
|
||||||
|
@ -308,6 +309,7 @@ fn find_determining_place<'tcx>(
|
||||||
// These statements have no influence on the place
|
// These statements have no influence on the place
|
||||||
// we are interested in
|
// we are interested in
|
||||||
StatementKind::FakeRead(_)
|
StatementKind::FakeRead(_)
|
||||||
|
| StatementKind::Deinit(_)
|
||||||
| StatementKind::StorageLive(_)
|
| StatementKind::StorageLive(_)
|
||||||
| StatementKind::StorageDead(_)
|
| StatementKind::StorageDead(_)
|
||||||
| StatementKind::Retag(_, _)
|
| StatementKind::Retag(_, _)
|
||||||
|
|
|
@ -498,7 +498,8 @@ impl<'tcx> Visitor<'tcx> for UsedLocals {
|
||||||
self.visit_rvalue(rvalue, location);
|
self.visit_rvalue(rvalue, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
StatementKind::SetDiscriminant { ref place, variant_index: _ } => {
|
StatementKind::SetDiscriminant { ref place, variant_index: _ }
|
||||||
|
| StatementKind::Deinit(ref place) => {
|
||||||
self.visit_lhs(place, location);
|
self.visit_lhs(place, location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -534,9 +535,8 @@ fn remove_unused_definitions(used_locals: &mut UsedLocals, body: &mut Body<'_>)
|
||||||
}
|
}
|
||||||
StatementKind::Assign(box (place, _)) => used_locals.is_used(place.local),
|
StatementKind::Assign(box (place, _)) => used_locals.is_used(place.local),
|
||||||
|
|
||||||
StatementKind::SetDiscriminant { ref place, .. } => {
|
StatementKind::SetDiscriminant { ref place, .. }
|
||||||
used_locals.is_used(place.local)
|
| StatementKind::Deinit(ref place) => used_locals.is_used(place.local),
|
||||||
}
|
|
||||||
_ => true,
|
_ => true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -211,7 +211,8 @@ fn check_statement<'tcx>(
|
||||||
|
|
||||||
StatementKind::FakeRead(box (_, place)) => check_place(tcx, *place, span, body),
|
StatementKind::FakeRead(box (_, place)) => check_place(tcx, *place, span, body),
|
||||||
// just an assignment
|
// just an assignment
|
||||||
StatementKind::SetDiscriminant { place, .. } => check_place(tcx, **place, span, body),
|
StatementKind::SetDiscriminant { place, .. } | StatementKind::Deinit(place) =>
|
||||||
|
check_place(tcx, **place, span, body),
|
||||||
|
|
||||||
StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping { dst, src, count }) => {
|
StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping { dst, src, count }) => {
|
||||||
check_operand(tcx, dst, span, body)?;
|
check_operand(tcx, dst, span, body)?;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue