Skip to content

Commit

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

Successful merges:

 - rust-lang#70023 (clean up E0436 explanation)
 - rust-lang#70234 (#[track_caller] on core::ops::{Index, IndexMut}.)
 - rust-lang#70241 (Miri: move ModifiedStatic to ConstEval errors)
 - rust-lang#70342 (IoSlice/IoSliceMut should be Send and Sync)
 - rust-lang#70350 (Request "-Z unstable-options" for unstable options)
 - rust-lang#70355 (Clean up E0454)
 - rust-lang#70359 (must_use on split_off)
 - rust-lang#70368 (Mark hotplug_codegen_backend as ignore-stage1)

Failed merges:

r? @ghost
  • Loading branch information
bors committed Mar 24, 2020
2 parents 2dcf54f + bf1ad22 commit 02046a5
Show file tree
Hide file tree
Showing 29 changed files with 237 additions and 118 deletions.
1 change: 1 addition & 0 deletions src/liballoc/collections/vec_deque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1876,6 +1876,7 @@ impl<T> VecDeque<T> {
/// assert_eq!(buf2, [2, 3]);
/// ```
#[inline]
#[must_use = "use `.truncate()` if you don't need the other half"]
#[stable(feature = "split_off", since = "1.4.0")]
pub fn split_off(&mut self, at: usize) -> Self {
let len = self.len();
Expand Down
1 change: 1 addition & 0 deletions src/liballoc/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1461,6 +1461,7 @@ impl String {
/// ```
#[inline]
#[stable(feature = "string_split_off", since = "1.16.0")]
#[must_use = "use `.truncate()` if you don't need the other half"]
pub fn split_off(&mut self, at: usize) -> String {
assert!(self.is_char_boundary(at));
let other = self.vec.split_off(at);
Expand Down
4 changes: 2 additions & 2 deletions src/liballoc/tests/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,14 +266,14 @@ fn test_split_off_empty() {
fn test_split_off_past_end() {
let orig = "Hello, world!";
let mut split = String::from(orig);
split.split_off(orig.len() + 1);
let _ = split.split_off(orig.len() + 1);
}

#[test]
#[should_panic]
fn test_split_off_mid_char() {
let mut orig = String::from("山");
orig.split_off(1);
let _ = orig.split_off(1);
}

#[test]
Expand Down
2 changes: 2 additions & 0 deletions src/libcore/ops/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ pub trait Index<Idx: ?Sized> {

/// Performs the indexing (`container[index]`) operation.
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(bootstrap), track_caller)]
fn index(&self, index: Idx) -> &Self::Output;
}

Expand Down Expand Up @@ -166,5 +167,6 @@ see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#ind
pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
/// Performs the mutable indexing (`container[index]`) operation.
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(bootstrap), track_caller)]
fn index_mut(&mut self, index: Idx) -> &mut Self::Output;
}
6 changes: 6 additions & 0 deletions src/libcore/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2306,6 +2306,7 @@ impl<T> [T] {
/// assert_eq!(&bytes, b"Hello, Wello!");
/// ```
#[stable(feature = "copy_within", since = "1.37.0")]
#[track_caller]
pub fn copy_within<R: ops::RangeBounds<usize>>(&mut self, src: R, dest: usize)
where
T: Copy,
Expand Down Expand Up @@ -2721,18 +2722,21 @@ where

#[inline(never)]
#[cold]
#[track_caller]
fn slice_index_len_fail(index: usize, len: usize) -> ! {
panic!("index {} out of range for slice of length {}", index, len);
}

#[inline(never)]
#[cold]
#[track_caller]
fn slice_index_order_fail(index: usize, end: usize) -> ! {
panic!("slice index starts at {} but ends at {}", index, end);
}

#[inline(never)]
#[cold]
#[track_caller]
fn slice_index_overflow_fail() -> ! {
panic!("attempted to index slice up to maximum usize");
}
Expand Down Expand Up @@ -2804,11 +2808,13 @@ pub trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
/// Returns a shared reference to the output at this location, panicking
/// if out of bounds.
#[unstable(feature = "slice_index_methods", issue = "none")]
#[cfg_attr(not(bootstrap), track_caller)]
fn index(self, slice: &T) -> &Self::Output;

/// Returns a mutable reference to the output at this location, panicking
/// if out of bounds.
#[unstable(feature = "slice_index_methods", issue = "none")]
#[cfg_attr(not(bootstrap), track_caller)]
fn index_mut(self, slice: &mut T) -> &mut Self::Output;
}

Expand Down
2 changes: 2 additions & 0 deletions src/libcore/str/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1794,6 +1794,7 @@ mod traits {

#[inline(never)]
#[cold]
#[track_caller]
fn str_index_overflow_fail() -> ! {
panic!("attempted to index str up to maximum usize");
}
Expand Down Expand Up @@ -2185,6 +2186,7 @@ fn truncate_to_char_boundary(s: &str, mut max: usize) -> (bool, &str) {

#[inline(never)]
#[cold]
#[track_caller]
fn slice_error_fail(s: &str, begin: usize, end: usize) -> ! {
const MAX_DISPLAY_LENGTH: usize = 256;
let (truncated, s_trunc) = truncate_to_char_boundary(s, MAX_DISPLAY_LENGTH);
Expand Down
9 changes: 0 additions & 9 deletions src/librustc/mir/interpret/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,9 +453,6 @@ pub enum UnsupportedOpInfo {
ReadForeignStatic(DefId),
/// Could not find MIR for a function.
NoMirFor(DefId),
/// Modified a static during const-eval.
/// FIXME: move this to `ConstEvalErrKind` through a machine hook.
ModifiedStatic,
/// Encountered a pointer where we needed raw bytes.
ReadPointerAsBytes,
/// Encountered raw bytes where we needed a pointer.
Expand All @@ -471,12 +468,6 @@ impl fmt::Debug for UnsupportedOpInfo {
write!(f, "tried to read from foreign (extern) static {:?}", did)
}
NoMirFor(did) => write!(f, "could not load MIR for {:?}", did),
ModifiedStatic => write!(
f,
"tried to modify a static's initial value from another static's \
initializer"
),

ReadPointerAsBytes => write!(f, "unable to turn pointer into raw bytes",),
ReadBytesAsPointer => write!(f, "unable to turn bytes into a pointer"),
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -984,6 +984,7 @@ pub struct GlobalCtxt<'tcx> {
/// Stores the value of constants (and deduplicates the actual memory)
allocation_interner: ShardedHashMap<&'tcx Allocation, ()>,

/// Stores memory for globals (statics/consts).
pub alloc_map: Lock<interpret::AllocMap<'tcx>>,

layout_interner: ShardedHashMap<&'tcx LayoutDetails, ()>,
Expand Down
7 changes: 4 additions & 3 deletions src/librustc_error_codes/error_codes/E0436.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
The functional record update syntax is only allowed for structs. (Struct-like
enum variants don't qualify, for example.)
The functional record update syntax was used on something other than a struct.

Erroneous code example:

Expand All @@ -24,7 +23,9 @@ fn one_up_competitor(competitor_frequency: PublicationFrequency)
}
```

Rewrite the expression without functional record update syntax:
The functional record update syntax is only allowed for structs (struct-like
enum variants don't qualify, for example). To fix the previous code, rewrite the
expression without functional record update syntax:

```
enum PublicationFrequency {
Expand Down
4 changes: 3 additions & 1 deletion src/librustc_error_codes/error_codes/E0454.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
A link name was given with an empty name. Erroneous code example:
A link name was given with an empty name.

Erroneous code example:

```compile_fail,E0454
#[link(name = "")] extern {}
Expand Down
4 changes: 4 additions & 0 deletions src/librustc_mir/const_eval/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::interpret::{ConstEvalErr, InterpErrorInfo, Machine};
pub enum ConstEvalErrKind {
NeedsRfc(String),
ConstAccessesStatic,
ModifiedGlobal,
AssertFailure(AssertKind<u64>),
Panic { msg: Symbol, line: u32, col: u32, file: Symbol },
}
Expand All @@ -33,6 +34,9 @@ impl fmt::Display for ConstEvalErrKind {
write!(f, "\"{}\" needs an rfc before being allowed inside constants", msg)
}
ConstAccessesStatic => write!(f, "constant accesses static"),
ModifiedGlobal => {
write!(f, "modifying a static's initial value from another static's initializer")
}
AssertFailure(ref msg) => write!(f, "{:?}", msg),
Panic { msg, line, col, file } => {
write!(f, "the evaluated program panicked at '{}', {}:{}:{}", msg, file, line, col)
Expand Down
23 changes: 16 additions & 7 deletions src/librustc_mir/const_eval/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ use std::hash::Hash;
use rustc_data_structures::fx::FxHashMap;

use rustc::mir::AssertMessage;
use rustc_span::source_map::Span;
use rustc_ast::ast::Mutability;
use rustc_span::symbol::Symbol;
use rustc_span::{def_id::DefId, Span};

use crate::interpret::{
self, AllocId, Allocation, GlobalId, ImmTy, InterpCx, InterpResult, Memory, MemoryKind, OpTy,
Expand Down Expand Up @@ -167,7 +168,7 @@ impl interpret::MayLeak for ! {
}

impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter {
type MemoryKinds = !;
type MemoryKind = !;
type PointerTag = ();
type ExtraFnVal = !;

Expand All @@ -177,7 +178,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter {

type MemoryMap = FxHashMap<AllocId, (MemoryKind<!>, Allocation)>;

const STATIC_KIND: Option<!> = None; // no copying of statics allowed
const GLOBAL_KIND: Option<!> = None; // no copying of globals allowed

// We do not check for alignment to avoid having to carry an `Align`
// in `ConstValue::ByRef`.
Expand Down Expand Up @@ -317,7 +318,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter {
}

#[inline(always)]
fn tag_static_base_pointer(_memory_extra: &MemoryExtra, _id: AllocId) -> Self::PointerTag {}
fn tag_global_base_pointer(_memory_extra: &MemoryExtra, _id: AllocId) -> Self::PointerTag {}

fn box_alloc(
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
Expand Down Expand Up @@ -345,11 +346,19 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter {
Ok(())
}

fn before_access_static(
fn before_access_global(
memory_extra: &MemoryExtra,
_allocation: &Allocation,
alloc_id: AllocId,
allocation: &Allocation,
def_id: Option<DefId>,
is_write: bool,
) -> InterpResult<'tcx> {
if memory_extra.can_access_statics {
if is_write && allocation.mutability == Mutability::Not {
Err(err_ub!(WriteToReadOnly(alloc_id)).into())
} else if is_write {
Err(ConstEvalErrKind::ModifiedGlobal.into())
} else if memory_extra.can_access_statics || def_id.is_none() {
// `def_id.is_none()` indicates this is not a static, but a const or so.
Ok(())
} else {
Err(ConstEvalErrKind::ConstAccessesStatic.into())
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
/// This represents a *direct* access to that memory, as opposed to access
/// through a pointer that was created by the program.
#[inline(always)]
pub fn tag_static_base_pointer(&self, ptr: Pointer) -> Pointer<M::PointerTag> {
self.memory.tag_static_base_pointer(ptr)
pub fn tag_global_base_pointer(&self, ptr: Pointer) -> Pointer<M::PointerTag> {
self.memory.tag_global_base_pointer(ptr)
}

#[inline(always)]
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/interpret/intern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use super::{AllocId, Allocation, InterpCx, MPlaceTy, Machine, MemoryKind, Scalar
pub trait CompileTimeMachine<'mir, 'tcx> = Machine<
'mir,
'tcx,
MemoryKinds = !,
MemoryKind = !,
PointerTag = (),
ExtraFnVal = !,
FrameExtra = (),
Expand Down Expand Up @@ -104,7 +104,7 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>>(
MemoryKind::Stack | MemoryKind::Vtable | MemoryKind::CallerLocation => {}
}
// Set allocation mutability as appropriate. This is used by LLVM to put things into
// read-only memory, and also by Miri when evluating other constants/statics that
// read-only memory, and also by Miri when evaluating other globals that
// access this one.
if mode == InternMode::Static {
// When `ty` is `None`, we assume no interior mutability.
Expand Down
37 changes: 21 additions & 16 deletions src/librustc_mir/interpret/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::hash::Hash;

use rustc::mir;
use rustc::ty::{self, Ty};
use rustc_span::Span;
use rustc_span::{def_id::DefId, Span};

use super::{
AllocId, Allocation, AllocationExtra, Frame, ImmTy, InterpCx, InterpResult, Memory, MemoryKind,
Expand Down Expand Up @@ -79,7 +79,7 @@ pub trait AllocMap<K: Hash + Eq, V> {
/// and some use case dependent behaviour can instead be applied.
pub trait Machine<'mir, 'tcx>: Sized {
/// Additional memory kinds a machine wishes to distinguish from the builtin ones
type MemoryKinds: ::std::fmt::Debug + MayLeak + Eq + 'static;
type MemoryKind: ::std::fmt::Debug + MayLeak + Eq + 'static;

/// Tag tracked alongside every pointer. This is used to implement "Stacked Borrows"
/// <https://www.ralfj.de/blog/2018/08/07/stacked-borrows.html>.
Expand All @@ -105,16 +105,17 @@ pub trait Machine<'mir, 'tcx>: Sized {
/// Memory's allocation map
type MemoryMap: AllocMap<
AllocId,
(MemoryKind<Self::MemoryKinds>, Allocation<Self::PointerTag, Self::AllocExtra>),
(MemoryKind<Self::MemoryKind>, Allocation<Self::PointerTag, Self::AllocExtra>),
> + Default
+ Clone;

/// The memory kind to use for copied statics -- or None if statics should not be mutated
/// and thus any such attempt will cause a `ModifiedStatic` error to be raised.
/// The memory kind to use for copied global memory (held in `tcx`) --
/// or None if such memory should not be mutated and thus any such attempt will cause
/// a `ModifiedStatic` error to be raised.
/// Statics are copied under two circumstances: When they are mutated, and when
/// `tag_allocation` or `find_foreign_static` (see below) returns an owned allocation
/// `tag_allocation` (see below) returns an owned allocation
/// that is added to the memory so that the work is not done twice.
const STATIC_KIND: Option<Self::MemoryKinds>;
const GLOBAL_KIND: Option<Self::MemoryKind>;

/// Whether memory accesses should be alignment-checked.
const CHECK_ALIGN: bool;
Expand Down Expand Up @@ -207,11 +208,15 @@ pub trait Machine<'mir, 'tcx>: Sized {
Ok(())
}

/// Called before a `Static` value is accessed.
/// Called before a global allocation is accessed.
/// `def_id` is `Some` if this is the "lazy" allocation of a static.
#[inline]
fn before_access_static(
fn before_access_global(
_memory_extra: &Self::MemoryExtra,
_alloc_id: AllocId,
_allocation: &Allocation,
_def_id: Option<DefId>,
_is_write: bool,
) -> InterpResult<'tcx> {
Ok(())
}
Expand All @@ -231,10 +236,10 @@ pub trait Machine<'mir, 'tcx>: Sized {
/// it contains (in relocations) tagged. The way we construct allocations is
/// to always first construct it without extra and then add the extra.
/// This keeps uniform code paths for handling both allocations created by CTFE
/// for statics, and allocations created by Miri during evaluation.
/// for globals, and allocations created by Miri during evaluation.
///
/// `kind` is the kind of the allocation being tagged; it can be `None` when
/// it's a static and `STATIC_KIND` is `None`.
/// it's a global and `GLOBAL_KIND` is `None`.
///
/// This should avoid copying if no work has to be done! If this returns an owned
/// allocation (because a copy had to be done to add tags or metadata), machine memory will
Expand All @@ -243,20 +248,20 @@ pub trait Machine<'mir, 'tcx>: Sized {
///
/// Also return the "base" tag to use for this allocation: the one that is used for direct
/// accesses to this allocation. If `kind == STATIC_KIND`, this tag must be consistent
/// with `tag_static_base_pointer`.
/// with `tag_global_base_pointer`.
fn init_allocation_extra<'b>(
memory_extra: &Self::MemoryExtra,
id: AllocId,
alloc: Cow<'b, Allocation>,
kind: Option<MemoryKind<Self::MemoryKinds>>,
kind: Option<MemoryKind<Self::MemoryKind>>,
) -> (Cow<'b, Allocation<Self::PointerTag, Self::AllocExtra>>, Self::PointerTag);

/// Return the "base" tag for the given *static* allocation: the one that is used for direct
/// accesses to this static/const/fn allocation. If `id` is not a static allocation,
/// Return the "base" tag for the given *global* allocation: the one that is used for direct
/// accesses to this static/const/fn allocation. If `id` is not a global allocation,
/// this will return an unusable tag (i.e., accesses will be UB)!
///
/// Expects `id` to be already canonical, if needed.
fn tag_static_base_pointer(memory_extra: &Self::MemoryExtra, id: AllocId) -> Self::PointerTag;
fn tag_global_base_pointer(memory_extra: &Self::MemoryExtra, id: AllocId) -> Self::PointerTag;

/// Executes a retagging operation
#[inline]
Expand Down
Loading

0 comments on commit 02046a5

Please sign in to comment.