From adf3b013c8b51e7d6ceea33ef3005896cc2cd030 Mon Sep 17 00:00:00 2001 From: Erik Desjardins Date: Wed, 25 Aug 2021 17:44:27 -0400 Subject: [PATCH] use a peekable iterator to check the first chunk --- .../src/mir/interpret/allocation.rs | 17 ++++++++++++++--- 1 file 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 @@ -894,6 +894,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 { match self { @@ -1035,7 +1043,7 @@ impl InitMaskCompressed { /// Transferring the initialization mask to other allocations. impl Allocation { - /// 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::>()`. @@ -1053,10 +1061,13 @@ impl Allocation { // 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); }