]> git.lizzy.rs Git - rust.git/commitdiff
add new instructions for asserting when values are valid, and to describe when we...
authorRalf Jung <post@ralfj.de>
Tue, 11 Jul 2017 21:01:07 +0000 (14:01 -0700)
committerRalf Jung <post@ralfj.de>
Sun, 30 Jul 2017 08:11:59 +0000 (01:11 -0700)
13 files changed:
src/librustc/ich/impls_mir.rs
src/librustc/mir/mod.rs
src/librustc/mir/visit.rs
src/librustc_mir/dataflow/drop_flag_effects.rs
src/librustc_mir/dataflow/impls/mod.rs
src/librustc_mir/dataflow/move_paths/mod.rs
src/librustc_mir/transform/qualify_consts.rs
src/librustc_mir/transform/rustc_peek.rs
src/librustc_mir/transform/type_check.rs
src/librustc_passes/mir_stats.rs
src/librustc_trans/mir/analyze.rs
src/librustc_trans/mir/constant.rs
src/librustc_trans/mir/statement.rs

index 6dadb702b9f24ada8ae4db46356787303b582afd..eb0c62a1161806b0343a208b0929faa8a2cbd809 100644 (file)
@@ -226,8 +226,12 @@ fn hash_stable<W: StableHasherResult>(&self,
             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 @@ fn hash_stable<W: StableHasherResult>(&self,
     }
 }
 
+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>,
index 3dcd64af2ede07a8db7f3ade91aba2078480b9fe..c7be58c13f86c135be5baa7842641664efded151 100644 (file)
@@ -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 @@ fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
             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 @@ fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F)
             // 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 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
             // 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,
         }
     }
index fd3a9f8cd2d9aa21d9f303a358d3869932602baf..5284a6132396be545ff1f101f934cfd38fc5f167 100644 (file)
@@ -333,6 +333,12 @@ fn super_statement(&mut self,
                         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 @@ pub fn is_mutating_use(&self) -> bool {
             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 @@ pub fn is_nonmutating_use(&self) -> bool {
             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,
         }
     }
 
index daafbecc5dfa3ba0d96642d125ac6ba5bd081b1f..24d5aa9e46bf232767ee2d41da9bf17117b03482 100644 (file)
@@ -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 => {
index 97c996dea68f6c07cc6078cd1711111fe0557b71..d5bdc71a705c5da5954ea8eb2f5a9ae1ede27759 100644 (file)
@@ -486,6 +486,7 @@ fn statement_effect(&self,
             mir::StatementKind::StorageDead(_) |
             mir::StatementKind::InlineAsm { .. } |
             mir::StatementKind::EndRegion(_) |
+            mir::StatementKind::Validate(..) |
             mir::StatementKind::Nop => {}
         }
     }
index fbf977b98f901b2f47bcb0c5418318efd65e2662..c2945d4659271432c034048731664621f5fc6ecf 100644 (file)
@@ -416,6 +416,7 @@ fn gather_statement(&mut self, loc: Location, stmt: &Statement<'tcx>) {
             }
             StatementKind::InlineAsm { .. } |
             StatementKind::EndRegion(_) |
+            StatementKind::Validate(..) |
             StatementKind::Nop => {}
         }
     }
index 9bb0f07aa68ac0fbed57efa502c746e2e3d3f3cc..9d01f8294e4fa0ec9ae8e604887cda6cd2d4eabc 100644 (file)
@@ -908,6 +908,7 @@ fn visit_statement(&mut self, bb: BasicBlock, statement: &Statement<'tcx>, locat
                 StatementKind::StorageDead(_) |
                 StatementKind::InlineAsm {..} |
                 StatementKind::EndRegion(_) |
+                StatementKind::Validate(..) |
                 StatementKind::Nop => {}
             }
         });
index 5918de0c6881104a906c857f250c2f0853d40670..268e7a4c185b00cd8eae1559064b164619d79e1d 100644 (file)
@@ -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,
index 7e6fccf30192ce626dbc072efd9b4948bf41b747..1c7899a46d1d760eb2d854a79c0ce31af6cbdd31 100644 (file)
@@ -414,6 +414,7 @@ fn check_stmt(&mut self, mir: &Mir<'tcx>, stmt: &Statement<'tcx>) {
             }
             StatementKind::InlineAsm { .. } |
             StatementKind::EndRegion(_) |
+            StatementKind::Validate(..) |
             StatementKind::Nop => {}
         }
     }
index 9895802700ef7c1895d44f28834b62453e4333d0..d5e477ff0c784d218d958dddff7ca883e12f9bd8 100644 (file)
@@ -126,6 +126,7 @@ fn visit_statement(&mut self,
         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",
index 45afcf51b5203d18ae46287ad6484b2632771ce7..598af1cda91d4940fdc7e703d1eaa56bd6d64694 100644 (file)
@@ -158,6 +158,7 @@ fn visit_lvalue(&mut self,
 
                 LvalueContext::StorageLive |
                 LvalueContext::StorageDead |
+                LvalueContext::Validate |
                 LvalueContext::Inspect |
                 LvalueContext::Consume => {}
 
index 98e774a29877dd9808acf053ad435b9de0ba55b6..c90382673a4a233873a42174296e66df59e5503f 100644 (file)
@@ -285,6 +285,7 @@ fn trans(&mut self) -> Result<Const<'tcx>, ConstEvalErr<'tcx>> {
                     }
                     mir::StatementKind::StorageLive(_) |
                     mir::StatementKind::StorageDead(_) |
+                    mir::StatementKind::Validate(..) |
                     mir::StatementKind::EndRegion(_) |
                     mir::StatementKind::Nop => {}
                     mir::StatementKind::InlineAsm { .. } |
index 170a76a49497bf738aead0e3b8de3092b95f8383..52dfc8dc4de5cac1d10f0d408ab504c3dd6cb91b 100644 (file)
@@ -87,6 +87,7 @@ pub fn trans_statement(&mut self,
                 bcx
             }
             mir::StatementKind::EndRegion(_) |
+            mir::StatementKind::Validate(..) |
             mir::StatementKind::Nop => bcx,
         }
     }