about summary refs log tree commit diff
diff options
context:
space:
mode:
authorErik Desjardins <erikdesjardins@users.noreply.github.com>2021-08-25 17:44:27 -0400
committerErik Desjardins <erikdesjardins@users.noreply.github.com>2021-08-25 17:49:29 -0400
commitadf3b013c8b51e7d6ceea33ef3005896cc2cd030 (patch)
tree8607ffcb8bc0995f8ffabb3bca27148e5a39b95a
parentc07a2eb5b417b72583e6331e8eeca1d505f9bac8 (diff)
downloadrust-adf3b013c8b51e7d6ceea33ef3005896cc2cd030.tar.gz
rust-adf3b013c8b51e7d6ceea33ef3005896cc2cd030.zip
use a peekable iterator to check the first chunk
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation.rs17
1 files changed, 14 insertions, 3 deletions
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs
index abc8799d102..b6358f99294 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs
@@ -895,6 +895,14 @@ pub enum InitChunk {
 
 impl InitChunk {
     #[inline]
+    pub fn is_init(&self) -> bool {
+        match self {
+            Self::Init(_) => true,
+            Self::Uninit(_) => false,
+        }
+    }
+
+    #[inline]
     pub fn range(&self) -> Range<Size> {
         match self {
             Self::Init(r) => r.clone(),
@@ -1035,7 +1043,7 @@ impl InitMaskCompressed {
 
 /// Transferring the initialization mask to other allocations.
 impl<Tag, Extra> Allocation<Tag, Extra> {
-    /// Creates a run-length encoding of the initialization mask.
+    /// Creates a run-length encoding of the initialization mask; panics if range is empty.
     ///
     /// This is essentially a more space-efficient version of
     /// `InitMask::range_as_init_chunks(...).collect::<Vec<_>>()`.
@@ -1053,10 +1061,13 @@ impl<Tag, Extra> Allocation<Tag, Extra> {
         // where each element toggles the state.
 
         let mut ranges = smallvec::SmallVec::<[u64; 1]>::new();
-        let initial = self.init_mask.get(range.start);
+
+        let mut chunks = self.init_mask.range_as_init_chunks(range.start, range.end()).peekable();
+
+        let initial = chunks.peek().expect("range should be nonempty").is_init();
 
         // Here we rely on `range_as_init_chunks` to yield alternating init/uninit chunks.
-        for chunk in self.init_mask.range_as_init_chunks(range.start, range.end()) {
+        for chunk in chunks {
             let len = chunk.range().end.bytes() - chunk.range().start.bytes();
             ranges.push(len);
         }