Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 7 pull requests #85413

Closed
wants to merge 16 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 5 additions & 29 deletions compiler/rustc_middle/src/mir/interpret/allocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ pub struct Allocation<Tag = (), Extra = ()> {
relocations: Relocations<Tag>,
/// Denotes which part of this allocation is initialized.
init_mask: InitMask,
/// The size of the allocation. Currently, must always equal `bytes.len()`.
pub size: Size,
/// The alignment of the allocation to detect unaligned reads.
/// (`Align` guarantees that this is a power of two.)
pub align: Align,
Expand Down Expand Up @@ -94,7 +92,6 @@ impl<Tag> Allocation<Tag> {
bytes,
relocations: Relocations::new(),
init_mask: InitMask::new(size, true),
size,
align,
mutability: Mutability::Not,
extra: (),
Expand All @@ -110,7 +107,6 @@ impl<Tag> Allocation<Tag> {
bytes: vec![0; size.bytes_usize()],
relocations: Relocations::new(),
init_mask: InitMask::new(size, false),
size,
align,
mutability: Mutability::Mut,
extra: (),
Expand All @@ -127,7 +123,6 @@ impl Allocation<(), ()> {
) -> Allocation<T, E> {
Allocation {
bytes: self.bytes,
size: self.size,
relocations: Relocations::from_presorted(
self.relocations
.iter()
Expand All @@ -150,7 +145,11 @@ impl Allocation<(), ()> {
/// Raw accessors. Provide access to otherwise private bytes.
impl<Tag, Extra> Allocation<Tag, Extra> {
pub fn len(&self) -> usize {
self.size.bytes_usize()
self.bytes.len()
}

pub fn size(&self) -> Size {
Size::from_bytes(self.len())
}

/// Looks at a slice which may describe uninitialized bytes or describe a relocation. This differs
Expand Down Expand Up @@ -276,29 +275,6 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {

/// Reading and writing.
impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
/// Reads bytes until a `0` is encountered. Will error if the end of the allocation is reached
/// before a `0` is found.
///
/// Most likely, you want to call `Memory::read_c_str` instead of this method.
pub fn read_c_str(
&self,
cx: &impl HasDataLayout,
ptr: Pointer<Tag>,
) -> InterpResult<'tcx, &[u8]> {
let offset = ptr.offset.bytes_usize();
Ok(match self.bytes[offset..].iter().position(|&c| c == 0) {
Some(size) => {
let size_with_null = Size::from_bytes(size) + Size::from_bytes(1);
// Go through `get_bytes` for checks and AllocationExtra hooks.
// We read the null, so we include it in the request, but we want it removed
// from the result, so we do subslicing.
&self.get_bytes(cx, ptr, size_with_null)?[..size]
}
// This includes the case where `offset` is out-of-bounds to begin with.
None => throw_ub!(UnterminatedCString(ptr.erase_tag())),
})
}

/// Validates that `ptr.offset` and `ptr.offset + size` do not point to the middle of a
/// relocation. If `allow_uninit_and_ptr` is `false`, also enforces that the memory in the
/// given range contains neither relocations nor uninitialized bytes.
Expand Down
89 changes: 7 additions & 82 deletions compiler/rustc_mir/src/interpret/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
let new_ptr = self.allocate(new_size, new_align, kind);
let old_size = match old_size_and_align {
Some((size, _align)) => size,
None => self.get_raw(ptr.alloc_id)?.size,
None => self.get_raw(ptr.alloc_id)?.size(),
};
self.copy(ptr, new_ptr, old_size.min(new_size), /*nonoverlapping*/ true)?;
self.deallocate(ptr, old_size_and_align, kind)?;
Expand Down Expand Up @@ -306,11 +306,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
);
}
if let Some((size, align)) = old_size_and_align {
if size != alloc.size || align != alloc.align {
if size != alloc.size() || align != alloc.align {
throw_ub_format!(
"incorrect layout on deallocation: {} has size {} and alignment {}, but gave size {} and alignment {}",
ptr.alloc_id,
alloc.size.bytes(),
alloc.size().bytes(),
alloc.align.bytes(),
size.bytes(),
align.bytes(),
Expand All @@ -319,11 +319,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
}

// Let the machine take some extra action
let size = alloc.size;
let size = alloc.size();
AllocationExtra::memory_deallocated(&mut alloc, ptr, size)?;

// Don't forget to remember size and align of this now-dead allocation
let old = self.dead_alloc_map.insert(ptr.alloc_id, (alloc.size, alloc.align));
let old = self.dead_alloc_map.insert(ptr.alloc_id, (alloc.size(), alloc.align));
if old.is_some() {
bug!("Nothing can be deallocated twice");
}
Expand Down Expand Up @@ -586,7 +586,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
// a) cause cycles in case `id` refers to a static
// b) duplicate a global's allocation in miri
if let Some((_, alloc)) = self.alloc_map.get(id) {
return Ok((alloc.size, alloc.align));
return Ok((alloc.size(), alloc.align));
}

// # Function pointers
Expand Down Expand Up @@ -614,7 +614,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
Some(GlobalAlloc::Memory(alloc)) => {
// Need to duplicate the logic here, because the global allocations have
// different associated types than the interpreter-local ones.
Ok((alloc.size, alloc.align))
Ok((alloc.size(), alloc.align))
}
Some(GlobalAlloc::Function(_)) => bug!("We already checked function pointers above"),
// The rest must be dead.
Expand Down Expand Up @@ -804,41 +804,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
self.get_raw(ptr.alloc_id)?.get_bytes(self, ptr, size)
}

/// Reads a 0-terminated sequence of bytes from memory. Returns them as a slice.
///
/// Performs appropriate bounds checks.
pub fn read_c_str(&self, ptr: Scalar<M::PointerTag>) -> InterpResult<'tcx, &[u8]> {
let ptr = self.force_ptr(ptr)?; // We need to read at least 1 byte, so we *need* a ptr.
self.get_raw(ptr.alloc_id)?.read_c_str(self, ptr)
}

/// Reads a 0x0000-terminated u16-sequence from memory. Returns them as a Vec<u16>.
/// Terminator 0x0000 is not included in the returned Vec<u16>.
///
/// Performs appropriate bounds checks.
pub fn read_wide_str(&self, ptr: Scalar<M::PointerTag>) -> InterpResult<'tcx, Vec<u16>> {
let size_2bytes = Size::from_bytes(2);
let align_2bytes = Align::from_bytes(2).unwrap();
// We need to read at least 2 bytes, so we *need* a ptr.
let mut ptr = self.force_ptr(ptr)?;
let allocation = self.get_raw(ptr.alloc_id)?;
let mut u16_seq = Vec::new();

loop {
ptr = self
.check_ptr_access(ptr.into(), size_2bytes, align_2bytes)?
.expect("cannot be a ZST");
let single_u16 = allocation.read_scalar(self, ptr, size_2bytes)?.to_u16()?;
if single_u16 != 0x0000 {
u16_seq.push(single_u16);
ptr = ptr.offset(size_2bytes, self)?;
} else {
break;
}
}
Ok(u16_seq)
}

/// Writes the given stream of bytes into memory.
///
/// Performs appropriate bounds checks.
Expand Down Expand Up @@ -866,46 +831,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
self.get_raw_mut(ptr.alloc_id)?.write_bytes(&tcx, ptr, src)
}

/// Writes the given stream of u16s into memory.
///
/// Performs appropriate bounds checks.
pub fn write_u16s(
&mut self,
ptr: Scalar<M::PointerTag>,
src: impl IntoIterator<Item = u16>,
) -> InterpResult<'tcx> {
let mut src = src.into_iter();
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 size = Size::from_bytes(lower);
let ptr = match self.check_ptr_access(ptr, size, Align::from_bytes(2).unwrap())? {
Some(ptr) => ptr,
None => {
// zero-sized access
assert_matches!(
src.next(),
None,
"iterator said it was empty but returned an element"
);
return Ok(());
}
};
let tcx = self.tcx;
let allocation = self.get_raw_mut(ptr.alloc_id)?;

for idx in 0..len {
let val = Scalar::from_u16(
src.next().expect("iterator was shorter than it said it would be"),
);
let offset_ptr = ptr.offset(Size::from_bytes(idx) * 2, &tcx)?; // `Size` multiplication
allocation.write_scalar(&tcx, offset_ptr, val.into(), Size::from_bytes(2))?;
}
assert_matches!(src.next(), None, "iterator was longer than it said it would be");
Ok(())
}

/// Expects the caller to have checked bounds and alignment.
pub fn copy(
&mut self,
Expand Down
29 changes: 18 additions & 11 deletions compiler/rustc_mir/src/interpret/terminator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ use std::convert::TryFrom;

use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::ty::Instance;
use rustc_middle::{mir, ty};
use rustc_middle::{
mir,
ty::{self, Ty},
};
use rustc_target::abi::{self, LayoutOf as _};
use rustc_target::spec::abi::Abi;

Expand Down Expand Up @@ -228,15 +231,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
};

// ABI check
{
let callee_abi = {
let instance_ty = instance.ty(*self.tcx, self.param_env);
match instance_ty.kind() {
ty::FnDef(..) => instance_ty.fn_sig(*self.tcx).abi(),
ty::Closure(..) => Abi::RustCall,
ty::Generator(..) => Abi::Rust,
_ => span_bug!(self.cur_span(), "unexpected callee ty: {:?}", instance_ty),
}
let check_abi = |this: &Self, instance_ty: Ty<'tcx>| -> InterpResult<'tcx> {
let callee_abi = match instance_ty.kind() {
ty::FnDef(..) => instance_ty.fn_sig(*this.tcx).abi(),
ty::Closure(..) => Abi::RustCall,
ty::Generator(..) => Abi::Rust,
_ => span_bug!(this.cur_span(), "unexpected callee ty: {:?}", instance_ty),
};
let normalize_abi = |abi| match abi {
Abi::Rust | Abi::RustCall | Abi::RustIntrinsic | Abi::PlatformIntrinsic =>
Expand All @@ -253,10 +253,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
caller_abi.name()
)
}
}
Ok(())
};

match instance.def {
ty::InstanceDef::Intrinsic(..) => {
check_abi(self, instance.ty(*self.tcx, self.param_env))?;
assert!(caller_abi == Abi::RustIntrinsic || caller_abi == Abi::PlatformIntrinsic);
M::call_intrinsic(self, instance, args, ret, unwind)
}
Expand All @@ -274,6 +276,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
None => return Ok(()),
};

// Check against the ABI of the MIR body we are calling (not the ABI of `instance`;
// these can differ when `find_mir_or_eval_fn` does something clever like resolve
// exported symbol names).
check_abi(self, self.tcx.type_of(body.source.def_id()))?;

self.push_stack_frame(
instance,
body,
Expand Down
12 changes: 6 additions & 6 deletions compiler/rustc_mir/src/util/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -776,8 +776,8 @@ pub struct RenderAllocation<'a, 'tcx, Tag, Extra> {
impl<Tag: Copy + Debug, Extra> std::fmt::Display for RenderAllocation<'a, 'tcx, Tag, Extra> {
fn fmt(&self, w: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let RenderAllocation { tcx, alloc } = *self;
write!(w, "size: {}, align: {})", alloc.size.bytes(), alloc.align.bytes())?;
if alloc.size == Size::ZERO {
write!(w, "size: {}, align: {})", alloc.size().bytes(), alloc.align.bytes())?;
if alloc.size() == Size::ZERO {
// We are done.
return write!(w, " {{}}");
}
Expand Down Expand Up @@ -822,9 +822,9 @@ fn write_allocation_bytes<Tag: Copy + Debug, Extra>(
w: &mut dyn std::fmt::Write,
prefix: &str,
) -> std::fmt::Result {
let num_lines = alloc.size.bytes_usize().saturating_sub(BYTES_PER_LINE);
let num_lines = alloc.size().bytes_usize().saturating_sub(BYTES_PER_LINE);
// Number of chars needed to represent all line numbers.
let pos_width = format!("{:x}", alloc.size.bytes()).len();
let pos_width = format!("{:x}", alloc.size().bytes()).len();

if num_lines > 0 {
write!(w, "{}0x{:02$x} │ ", prefix, 0, pos_width)?;
Expand All @@ -845,7 +845,7 @@ fn write_allocation_bytes<Tag: Copy + Debug, Extra>(
}
};

while i < alloc.size {
while i < alloc.size() {
// The line start already has a space. While we could remove that space from the line start
// printing and unconditionally print a space here, that would cause the single-line case
// to have a single space before it, which looks weird.
Expand Down Expand Up @@ -929,7 +929,7 @@ fn write_allocation_bytes<Tag: Copy + Debug, Extra>(
i += Size::from_bytes(1);
}
// Print a new line header if the next line still has some bytes to print.
if i == line_start + Size::from_bytes(BYTES_PER_LINE) && i != alloc.size {
if i == line_start + Size::from_bytes(BYTES_PER_LINE) && i != alloc.size() {
line_start = write_allocation_newline(w, line_start, &ascii, pos_width, prefix)?;
ascii.clear();
}
Expand Down
2 changes: 2 additions & 0 deletions library/alloc/src/collections/binary_heap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1299,6 +1299,7 @@ impl<T> ExactSizeIterator for IntoIter<T> {
impl<T> FusedIterator for IntoIter<T> {}

#[unstable(issue = "none", feature = "inplace_iteration")]
#[doc(hidden)]
unsafe impl<T> SourceIter for IntoIter<T> {
type Source = IntoIter<T>;

Expand All @@ -1309,6 +1310,7 @@ unsafe impl<T> SourceIter for IntoIter<T> {
}

#[unstable(issue = "none", feature = "inplace_iteration")]
#[doc(hidden)]
unsafe impl<I> InPlaceIterable for IntoIter<I> {}

impl<I> AsIntoIter for IntoIter<I> {
Expand Down
2 changes: 2 additions & 0 deletions library/alloc/src/vec/into_iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,11 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for IntoIter<T, A> {
}

#[unstable(issue = "none", feature = "inplace_iteration")]
#[doc(hidden)]
unsafe impl<T, A: Allocator> InPlaceIterable for IntoIter<T, A> {}

#[unstable(issue = "none", feature = "inplace_iteration")]
#[doc(hidden)]
unsafe impl<T, A: Allocator> SourceIter for IntoIter<T, A> {
type Source = Self;

Expand Down
1 change: 1 addition & 0 deletions library/core/src/iter/adapters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ pub use self::zip::zip;
/// [`FromIterator`]: crate::iter::FromIterator
/// [`as_inner`]: SourceIter::as_inner
#[unstable(issue = "none", feature = "inplace_iteration")]
#[doc(hidden)]
pub unsafe trait SourceIter {
/// A source stage in an iterator pipeline.
type Source: Iterator;
Expand Down
1 change: 1 addition & 0 deletions library/core/src/iter/traits/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,5 @@ unsafe impl<I: TrustedLen + ?Sized> TrustedLen for &mut I {}
/// [`next()`]: Iterator::next
/// [`try_fold()`]: Iterator::try_fold
#[unstable(issue = "none", feature = "inplace_iteration")]
#[doc(hidden)]
pub unsafe trait InPlaceIterable: Iterator {}
2 changes: 1 addition & 1 deletion library/std/src/os/wasi/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Platform-specific extensions to `std` for WASI.
//! Platform-specific extensions to `std` for the WebAssembly System Interface (WASI).
//!
//! Provides access to platform-level information on WASI, and exposes
//! WASI-specific functions that would otherwise be inappropriate as
Expand Down
4 changes: 2 additions & 2 deletions src/librustdoc/html/static/themes/ayu.css
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,8 @@ details.undocumented > summary::before {
box-shadow: 0 0 0 1px #148099,0 0 0 2px transparent;
}

.search-focus:disabled {
color: #929292;
.search-input:disabled {
background-color: #3e3e3e;
}

.module-item .stab,
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/html/static/themes/dark.css
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ details.undocumented > summary::before {
border-color: #008dfd;
}

.search-focus:disabled {
.search-input:disabled {
background-color: #c5c4c4;
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/html/static/themes/light.css
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ details.undocumented > summary::before {
border-color: #66afe9;
}

.search-focus:disabled {
.search-input:disabled {
background-color: #e6e6e6;
}

Expand Down
Loading