Skip to content

Commit

Permalink
Auto merge of rust-lang#85414 - RalfJung:rollup-ueqcik4, r=RalfJung
Browse files Browse the repository at this point in the history
Rollup of 8 pull requests

Successful merges:

 - rust-lang#85087 (`eval_fn_call`: check the ABI of `body.source`)
 - rust-lang#85302 (Expand WASI abbreviation in docs)
 - rust-lang#85355 (More tests for issue-85255)
 - rust-lang#85367 (Fix invalid input:disabled CSS selector)
 - rust-lang#85374 (mark internal inplace_iteration traits as hidden)
 - rust-lang#85408 (remove size field from Allocation)
 - rust-lang#85409 (Simplify `cfg(any(unix, target_os="redox"))` in example to just `cfg(unix)`)
 - rust-lang#85412 (remove some functions that were only used by Miri)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed May 17, 2021
2 parents fa72878 + a28be5c commit 3e99439
Show file tree
Hide file tree
Showing 35 changed files with 174 additions and 183 deletions.
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/ffi/os_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,7 @@ impl OsStr {
/// // sequences simply through collecting user command line arguments, for
/// // example.
///
/// #[cfg(any(unix, target_os = "redox"))] {
/// #[cfg(unix)] {
/// use std::ffi::OsStr;
/// use std::os::unix::ffi::OsStrExt;
///
Expand Down
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
Loading

0 comments on commit 3e99439

Please sign in to comment.