add new instructions for asserting when values are valid, and to describe when we can rely on them being locked in memory
This commit is contained in:
parent
5c71e4ef90
commit
5264103de4
13 changed files with 49 additions and 4 deletions
|
@ -226,8 +226,12 @@ for mir::StatementKind<'tcx> {
|
|||
mir::StatementKind::StorageDead(ref lvalue) => {
|
||||
lvalue.hash_stable(hcx, hasher);
|
||||
}
|
||||
mir::StatementKind::EndRegion(ref extents) => {
|
||||
extents.hash_stable(hcx, hasher);
|
||||
mir::StatementKind::EndRegion(ref extent) => {
|
||||
extent.hash_stable(hcx, hasher);
|
||||
}
|
||||
mir::StatementKind::Validate(ref op, ref lvalues) => {
|
||||
op.hash_stable(hcx, hasher);
|
||||
lvalues.hash_stable(hcx, hasher);
|
||||
}
|
||||
mir::StatementKind::Nop => {}
|
||||
mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => {
|
||||
|
@ -239,6 +243,8 @@ for mir::StatementKind<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl_stable_hash_for!(enum mir::ValidationOp { Acquire, Release, Suspend(extent) });
|
||||
|
||||
impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for mir::Lvalue<'tcx> {
|
||||
fn hash_stable<W: StableHasherResult>(&self,
|
||||
hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>,
|
||||
|
|
|
@ -818,12 +818,16 @@ pub enum StatementKind<'tcx> {
|
|||
/// End the current live range for the storage of the local.
|
||||
StorageDead(Lvalue<'tcx>),
|
||||
|
||||
/// Execute a piece of inline Assembly.
|
||||
InlineAsm {
|
||||
asm: Box<InlineAsm>,
|
||||
outputs: Vec<Lvalue<'tcx>>,
|
||||
inputs: Vec<Operand<'tcx>>
|
||||
},
|
||||
|
||||
/// Assert the given lvalues to be valid inhabitants of their type.
|
||||
Validate(ValidationOp, Vec<(Ty<'tcx>, Lvalue<'tcx>)>),
|
||||
|
||||
/// Mark one terminating point of an extent (i.e. static region).
|
||||
/// (The starting point(s) arise implicitly from borrows.)
|
||||
EndRegion(CodeExtent),
|
||||
|
@ -832,6 +836,13 @@ pub enum StatementKind<'tcx> {
|
|||
Nop,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, PartialEq, Eq)]
|
||||
pub enum ValidationOp {
|
||||
Acquire,
|
||||
Release,
|
||||
Suspend(CodeExtent),
|
||||
}
|
||||
|
||||
impl<'tcx> Debug for Statement<'tcx> {
|
||||
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
|
||||
use self::StatementKind::*;
|
||||
|
@ -839,6 +850,7 @@ impl<'tcx> Debug for Statement<'tcx> {
|
|||
Assign(ref lv, ref rv) => write!(fmt, "{:?} = {:?}", lv, rv),
|
||||
// (reuse lifetime rendering policy from ppaux.)
|
||||
EndRegion(ref ce) => write!(fmt, "EndRegion({})", ty::ReScope(*ce)),
|
||||
Validate(ref op, ref lvalues) => write!(fmt, "Validate({:?}, {:?})", op, lvalues),
|
||||
StorageLive(ref lv) => write!(fmt, "StorageLive({:?})", lv),
|
||||
StorageDead(ref lv) => write!(fmt, "StorageDead({:?})", lv),
|
||||
SetDiscriminant{lvalue: ref lv, variant_index: index} => {
|
||||
|
@ -1505,6 +1517,10 @@ impl<'tcx> TypeFoldable<'tcx> for Statement<'tcx> {
|
|||
// trait with a `fn fold_extent`.
|
||||
EndRegion(ref extent) => EndRegion(extent.clone()),
|
||||
|
||||
Validate(ref op, ref lvals) =>
|
||||
Validate(op.clone(),
|
||||
lvals.iter().map(|ty_and_lval| ty_and_lval.fold_with(folder)).collect()),
|
||||
|
||||
Nop => Nop,
|
||||
};
|
||||
Statement {
|
||||
|
@ -1530,6 +1546,8 @@ impl<'tcx> TypeFoldable<'tcx> for Statement<'tcx> {
|
|||
// trait with a `fn visit_extent`.
|
||||
EndRegion(ref _extent) => false,
|
||||
|
||||
Validate(ref _op, ref lvalues) => lvalues.iter().any(|ty_and_lvalue| ty_and_lvalue.visit_with(visitor)),
|
||||
|
||||
Nop => false,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -333,6 +333,12 @@ macro_rules! make_mir_visitor {
|
|||
self.visit_assign(block, lvalue, rvalue, location);
|
||||
}
|
||||
StatementKind::EndRegion(_) => {}
|
||||
StatementKind::Validate(_, ref $($mutability)* lvalues) => {
|
||||
for & $($mutability)* (ref $($mutability)* ty, ref $($mutability)* lvalue) in lvalues {
|
||||
self.visit_ty(ty, Lookup::Loc(location));
|
||||
self.visit_lvalue(lvalue, LvalueContext::Validate, location);
|
||||
}
|
||||
}
|
||||
StatementKind::SetDiscriminant{ ref $($mutability)* lvalue, .. } => {
|
||||
self.visit_lvalue(lvalue, LvalueContext::Store, location);
|
||||
}
|
||||
|
@ -784,6 +790,9 @@ pub enum LvalueContext<'tcx> {
|
|||
// Starting and ending a storage live range
|
||||
StorageLive,
|
||||
StorageDead,
|
||||
|
||||
// Validation command
|
||||
Validate,
|
||||
}
|
||||
|
||||
impl<'tcx> LvalueContext<'tcx> {
|
||||
|
@ -830,7 +839,8 @@ impl<'tcx> LvalueContext<'tcx> {
|
|||
LvalueContext::Borrow { kind: BorrowKind::Shared, .. } |
|
||||
LvalueContext::Borrow { kind: BorrowKind::Unique, .. } |
|
||||
LvalueContext::Projection(Mutability::Not) | LvalueContext::Consume |
|
||||
LvalueContext::StorageLive | LvalueContext::StorageDead => false,
|
||||
LvalueContext::StorageLive | LvalueContext::StorageDead |
|
||||
LvalueContext::Validate => false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -842,7 +852,8 @@ impl<'tcx> LvalueContext<'tcx> {
|
|||
LvalueContext::Projection(Mutability::Not) | LvalueContext::Consume => true,
|
||||
LvalueContext::Borrow { kind: BorrowKind::Mut, .. } | LvalueContext::Store |
|
||||
LvalueContext::Call | LvalueContext::Projection(Mutability::Mut) |
|
||||
LvalueContext::Drop | LvalueContext::StorageLive | LvalueContext::StorageDead => false,
|
||||
LvalueContext::Drop | LvalueContext::StorageLive | LvalueContext::StorageDead |
|
||||
LvalueContext::Validate => false,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -289,6 +289,7 @@ pub(crate) fn drop_flag_effects_for_location<'a, 'tcx, F>(
|
|||
mir::StatementKind::StorageDead(_) |
|
||||
mir::StatementKind::InlineAsm { .. } |
|
||||
mir::StatementKind::EndRegion(_) |
|
||||
mir::StatementKind::Validate(..) |
|
||||
mir::StatementKind::Nop => {}
|
||||
},
|
||||
None => {
|
||||
|
|
|
@ -486,6 +486,7 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> {
|
|||
mir::StatementKind::StorageDead(_) |
|
||||
mir::StatementKind::InlineAsm { .. } |
|
||||
mir::StatementKind::EndRegion(_) |
|
||||
mir::StatementKind::Validate(..) |
|
||||
mir::StatementKind::Nop => {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -416,6 +416,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
|
|||
}
|
||||
StatementKind::InlineAsm { .. } |
|
||||
StatementKind::EndRegion(_) |
|
||||
StatementKind::Validate(..) |
|
||||
StatementKind::Nop => {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -908,6 +908,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
|
|||
StatementKind::StorageDead(_) |
|
||||
StatementKind::InlineAsm {..} |
|
||||
StatementKind::EndRegion(_) |
|
||||
StatementKind::Validate(..) |
|
||||
StatementKind::Nop => {}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -161,6 +161,7 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
mir::StatementKind::StorageDead(_) |
|
||||
mir::StatementKind::InlineAsm { .. } |
|
||||
mir::StatementKind::EndRegion(_) |
|
||||
mir::StatementKind::Validate(..) |
|
||||
mir::StatementKind::Nop => continue,
|
||||
mir::StatementKind::SetDiscriminant{ .. } =>
|
||||
span_bug!(stmt.source_info.span,
|
||||
|
|
|
@ -414,6 +414,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
StatementKind::InlineAsm { .. } |
|
||||
StatementKind::EndRegion(_) |
|
||||
StatementKind::Validate(..) |
|
||||
StatementKind::Nop => {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,6 +126,7 @@ impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> {
|
|||
self.record(match statement.kind {
|
||||
StatementKind::Assign(..) => "StatementKind::Assign",
|
||||
StatementKind::EndRegion(..) => "StatementKind::EndRegion",
|
||||
StatementKind::Validate(..) => "StatementKind::Validate",
|
||||
StatementKind::SetDiscriminant { .. } => "StatementKind::SetDiscriminant",
|
||||
StatementKind::StorageLive(..) => "StatementKind::StorageLive",
|
||||
StatementKind::StorageDead(..) => "StatementKind::StorageDead",
|
||||
|
|
|
@ -158,6 +158,7 @@ impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> {
|
|||
|
||||
LvalueContext::StorageLive |
|
||||
LvalueContext::StorageDead |
|
||||
LvalueContext::Validate |
|
||||
LvalueContext::Inspect |
|
||||
LvalueContext::Consume => {}
|
||||
|
||||
|
|
|
@ -285,6 +285,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
|
|||
}
|
||||
mir::StatementKind::StorageLive(_) |
|
||||
mir::StatementKind::StorageDead(_) |
|
||||
mir::StatementKind::Validate(..) |
|
||||
mir::StatementKind::EndRegion(_) |
|
||||
mir::StatementKind::Nop => {}
|
||||
mir::StatementKind::InlineAsm { .. } |
|
||||
|
|
|
@ -87,6 +87,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
|||
bcx
|
||||
}
|
||||
mir::StatementKind::EndRegion(_) |
|
||||
mir::StatementKind::Validate(..) |
|
||||
mir::StatementKind::Nop => bcx,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue