diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs index 796d293e2c63c..aa8ac4902a894 100644 --- a/src/librustc/mir/interpret/allocation.rs +++ b/src/librustc/mir/interpret/allocation.rs @@ -353,11 +353,14 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { &mut self, cx: &impl HasDataLayout, ptr: Pointer, - src: impl IntoIterator, + src: impl IntoIterator, ) -> InterpResult<'tcx> { let mut src = src.into_iter(); - let bytes = self.get_bytes_mut(cx, ptr, Size::from_bytes(src.len() as u64))?; + let (lower, upper) = src.size_hint(); + let len = upper.expect("can only write bounded iterators"); + assert_eq!(lower, len, "can only write iterators with a precise length"); + let bytes = self.get_bytes_mut(cx, ptr, Size::from_bytes(len as u64))?; // `zip` would stop when the first iterator ends; we want to definitely // cover all of `bytes`. for dest in bytes { diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index eef1868ec65b6..d113ee33162d2 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -7,7 +7,7 @@ //! short-circuiting the empty case! use std::collections::VecDeque; -use std::{ptr, iter}; +use std::ptr; use std::borrow::Cow; use rustc::ty::{self, Instance, ParamEnv, query::TyCtxtAt}; @@ -791,11 +791,12 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { pub fn write_bytes( &mut self, ptr: Scalar, - src: impl IntoIterator, + src: impl IntoIterator, ) -> InterpResult<'tcx> { let src = src.into_iter(); - let size = Size::from_bytes(src.len() as u64); + let size = Size::from_bytes(src.size_hint().0 as u64); + // `write_bytes` checks that this lower bound matches the upper bound matches reality. let ptr = match self.check_ptr_access(ptr, size, Align::from_bytes(1).unwrap())? { Some(ptr) => ptr, None => return Ok(()), // zero-sized access