Skip to content

Rollup of 8 pull requests #66160

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

Closed
wants to merge 27 commits into from
Closed
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
6515371
QPath docs: mention how to resolve them
RalfJung Nov 4, 2019
151e989
also explain how to resolve MethodCall
RalfJung Nov 4, 2019
d22a659
Do not require extra LLVM backends for `x.py test` to pass
petrochenkov Nov 4, 2019
82dc3aa
link from raw slice creation methods to safety requirements
RalfJung Nov 5, 2019
1a254e4
expand slice from_raw_part docs
RalfJung Nov 5, 2019
6a1f303
also edit String::from_raw_parts while we are at it
RalfJung Nov 5, 2019
b1d0a68
fix link to ptr docs
RalfJung Nov 5, 2019
3a54ab7
LinkedList: PhantomData<Box<Node<T>>> => PhantomData<T>
olegnn Nov 5, 2019
45f281d
Reverted PhantomData in LinkedList, fixed PhantomData markers in Rc a…
olegnn Nov 5, 2019
11a48a0
Apply suggestions from code review
RalfJung Nov 5, 2019
6a59319
Fixed libcore/cell.rs example
olegnn Nov 5, 2019
1c7595f
gate rustc_on_unimplemented under rustc_attrs
Centril Oct 25, 2019
936349c
Update local.rs
3442853561 Nov 6, 2019
14ee66a
miri cast: avoid unnecessary to_scalar_ptr
RalfJung Nov 5, 2019
32453ce
remvoe to_scalar_ptr and use ref_to_mplace everywhere
RalfJung Nov 6, 2019
87edcf0
improve a comment
RalfJung Nov 6, 2019
2312a56
--bless
RalfJung Nov 6, 2019
f2ed1e6
Fix markdown link
RalfJung Nov 6, 2019
8ec83cf
update clippy to fix toolstate
tesuji Nov 6, 2019
db341c1
Rollup merge of #65794 - Centril:unimpl-internal, r=varkor
pietroalbini Nov 6, 2019
9bfb5cc
Rollup merge of #66076 - RalfJung:qpath, r=davidtwco,oli-obk
pietroalbini Nov 6, 2019
ab08821
Rollup merge of #66084 - petrochenkov:x86arm, r=alexcrichton
pietroalbini Nov 6, 2019
5723176
Rollup merge of #66111 - RalfJung:from_raw_parts, r=Centril
pietroalbini Nov 6, 2019
e3fbd3c
Rollup merge of #66117 - olegnn:fixed_linked_list_marker, r=RalfJung
pietroalbini Nov 6, 2019
f573bd8
Rollup merge of #66146 - 3442853561:patch-2, r=Mark-Simulacrum
pietroalbini Nov 6, 2019
619d38a
Rollup merge of #66147 - RalfJung:no-scalar-ptr, r=oli-obk
pietroalbini Nov 6, 2019
454032f
Rollup merge of #66158 - lzutao:clippyup, r=Manishearth
pietroalbini Nov 6, 2019
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
2 changes: 1 addition & 1 deletion Cargo.lock
Original file line number Diff line number Diff line change
@@ -487,7 +487,7 @@ dependencies = [
"regex-syntax",
"semver",
"serde",
"smallvec 0.6.10",
"smallvec 1.0.0",
"toml",
"unicode-normalization",
"url 2.1.0",
154 changes: 0 additions & 154 deletions src/doc/unstable-book/src/language-features/on-unimplemented.md

This file was deleted.

2 changes: 1 addition & 1 deletion src/liballoc/collections/linked_list.rs
Original file line number Diff line number Diff line change
@@ -90,7 +90,7 @@ impl<T> Clone for Iter<'_, T> {
#[stable(feature = "rust1", since = "1.0.0")]
pub struct IterMut<'a, T: 'a> {
// We do *not* exclusively own the entire list here, references to node's `element`
// have been handed out by the iterator! So be careful when using this; the methods
// have been handed out by the iterator! So be careful when using this; the methods
// called must be aware that there can be aliasing pointers to `element`.
list: &'a mut LinkedList<T>,
head: Option<NonNull<Node<T>>>,
2 changes: 1 addition & 1 deletion src/liballoc/lib.rs
Original file line number Diff line number Diff line change
@@ -116,7 +116,7 @@
#![feature(unsize)]
#![feature(unsized_locals)]
#![feature(allocator_internals)]
#![feature(on_unimplemented)]
#![cfg_attr(bootstrap, feature(on_unimplemented))]
#![feature(rustc_const_unstable)]
#![feature(slice_partition_dedup)]
#![feature(maybe_uninit_extra, maybe_uninit_slice)]
2 changes: 1 addition & 1 deletion src/liballoc/rc.rs
Original file line number Diff line number Diff line change
@@ -280,7 +280,7 @@ struct RcBox<T: ?Sized> {
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Rc<T: ?Sized> {
ptr: NonNull<RcBox<T>>,
phantom: PhantomData<T>,
phantom: PhantomData<RcBox<T>>,
}

#[stable(feature = "rust1", since = "1.0.0")]
2 changes: 1 addition & 1 deletion src/liballoc/string.rs
Original file line number Diff line number Diff line change
@@ -687,7 +687,7 @@ impl String {
/// checked:
///
/// * The memory at `ptr` needs to have been previously allocated by the
/// same allocator the standard library uses.
/// same allocator the standard library uses, with a required alignment of exactly 1.
/// * `length` needs to be less than or equal to `capacity`.
/// * `capacity` needs to be the correct value.
///
2 changes: 1 addition & 1 deletion src/liballoc/sync.rs
Original file line number Diff line number Diff line change
@@ -195,7 +195,7 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize;
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Arc<T: ?Sized> {
ptr: NonNull<ArcInner<T>>,
phantom: PhantomData<T>,
phantom: PhantomData<ArcInner<T>>,
}

#[stable(feature = "rust1", since = "1.0.0")]
9 changes: 7 additions & 2 deletions src/libcore/cell.rs
Original file line number Diff line number Diff line change
@@ -137,9 +137,11 @@
//! use std::cell::Cell;
//! use std::ptr::NonNull;
//! use std::intrinsics::abort;
//! use std::marker::PhantomData;
//!
//! struct Rc<T: ?Sized> {
//! ptr: NonNull<RcBox<T>>
//! ptr: NonNull<RcBox<T>>,
//! phantom: PhantomData<RcBox<T>>,
//! }
//!
//! struct RcBox<T: ?Sized> {
@@ -151,7 +153,10 @@
//! impl<T: ?Sized> Clone for Rc<T> {
//! fn clone(&self) -> Rc<T> {
//! self.inc_strong();
//! Rc { ptr: self.ptr }
//! Rc {
//! ptr: self.ptr,
//! phantom: PhantomData,
//! }
//! }
//! }
//!
2 changes: 1 addition & 1 deletion src/libcore/lib.rs
Original file line number Diff line number Diff line change
@@ -89,7 +89,7 @@
#![feature(nll)]
#![feature(exhaustive_patterns)]
#![feature(no_core)]
#![feature(on_unimplemented)]
#![cfg_attr(bootstrap, feature(on_unimplemented))]
#![feature(optin_builtin_traits)]
#![feature(prelude_import)]
#![feature(repr_simd, platform_intrinsics)]
23 changes: 18 additions & 5 deletions src/libcore/ptr/mod.rs
Original file line number Diff line number Diff line change
@@ -18,6 +18,10 @@
//! * A [null] pointer is *never* valid, not even for accesses of [size zero][zst].
//! * All pointers (except for the null pointer) are valid for all operations of
//! [size zero][zst].
//! * For a pointer to be valid, it is necessary, but not always sufficient, that the pointer
//! be *dereferencable*: the memory range of the given size starting at the pointer must all be
//! within the bounds of a single allocated object. Note that in Rust,
//! every (stack-allocated) variable is considered a separate allocated object.
//! * All accesses performed by functions in this module are *non-atomic* in the sense
//! of [atomic operations] used to synchronize between threads. This means it is
//! undefined behavior to perform two concurrent accesses to the same location from different
@@ -221,10 +225,15 @@ pub(crate) struct FatPtr<T> {
pub(crate) len: usize,
}

/// Forms a slice from a pointer and a length.
/// Forms a raw slice from a pointer and a length.
///
/// The `len` argument is the number of **elements**, not the number of bytes.
///
/// This function is safe, but actually using the return value is unsafe.
/// See the documentation of [`from_raw_parts`] for slice safety requirements.
///
/// [`from_raw_parts`]: ../../std/slice/fn.from_raw_parts.html
///
/// # Examples
///
/// ```rust
@@ -243,12 +252,16 @@ pub fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
unsafe { Repr { raw: FatPtr { data, len } }.rust }
}

/// Performs the same functionality as [`from_raw_parts`], except that a
/// mutable slice is returned.
/// Performs the same functionality as [`slice_from_raw_parts`], except that a
/// raw mutable slice is returned, as opposed to a raw immutable slice.
///
/// See the documentation of [`from_raw_parts`] for more details.
/// See the documentation of [`slice_from_raw_parts`] for more details.
///
/// [`from_raw_parts`]: ../../std/slice/fn.from_raw_parts.html
/// This function is safe, but actually using the return value is unsafe.
/// See the documentation of [`from_raw_parts_mut`] for slice safety requirements.
///
/// [`slice_from_raw_parts`]: fn.slice_from_raw_parts.html
/// [`from_raw_parts_mut`]: ../../std/slice/fn.from_raw_parts_mut.html
#[inline]
#[unstable(feature = "slice_from_raw_parts", reason = "recently added", issue = "36925")]
pub fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] {
60 changes: 42 additions & 18 deletions src/libcore/slice/mod.rs
Original file line number Diff line number Diff line change
@@ -5272,18 +5272,24 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {
///
/// # Safety
///
/// This function is unsafe as there is no guarantee that the given pointer is
/// valid for `len` elements, nor whether the lifetime inferred is a suitable
/// lifetime for the returned slice.
/// Behavior is undefined if any of the following conditions are violated:
///
/// `data` must be non-null and aligned, even for zero-length slices. One
/// reason for this is that enum layout optimizations may rely on references
/// (including slices of any length) being aligned and non-null to distinguish
/// them from other data. You can obtain a pointer that is usable as `data`
/// for zero-length slices using [`NonNull::dangling()`].
/// * `data` must be [valid] for reads for `len * mem::size_of::<T>()` many bytes,
/// and it must be properly aligned. This means in particular:
///
/// The total size of the slice must be no larger than `isize::MAX` **bytes**
/// in memory. See the safety documentation of [`pointer::offset`].
/// * The entire memory range of this slice must be contained within a single allocated object!
/// Slices can never span across multiple allocated objects.
/// * `data` must be non-null and aligned even for zero-length slices. One
/// reason for this is that enum layout optimizations may rely on references
/// (including slices of any length) being aligned and non-null to distinguish
/// them from other data. You can obtain a pointer that is usable as `data`
/// for zero-length slices using [`NonNull::dangling()`].
///
/// * The memory referenced by the returned slice must not be mutated for the duration
/// of lifetime `'a`, except inside an `UnsafeCell`.
///
/// * The total size `len * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
/// See the safety documentation of [`pointer::offset`].
///
/// # Caveat
///
@@ -5305,35 +5311,53 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> {
/// assert_eq!(slice[0], 42);
/// ```
///
/// [valid]: ../../std/ptr/index.html#safety
/// [`NonNull::dangling()`]: ../../std/ptr/struct.NonNull.html#method.dangling
/// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice");
debug_assert!(mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize,
"attempt to create slice covering half the address space");
"attempt to create slice covering at least half the address space");
&*ptr::slice_from_raw_parts(data, len)
}

/// Performs the same functionality as [`from_raw_parts`], except that a
/// mutable slice is returned.
///
/// This function is unsafe for the same reasons as [`from_raw_parts`], as well
/// as not being able to provide a non-aliasing guarantee of the returned
/// mutable slice. `data` must be non-null and aligned even for zero-length
/// slices as with [`from_raw_parts`]. The total size of the slice must be no
/// larger than `isize::MAX` **bytes** in memory.
/// # Safety
///
/// Behavior is undefined if any of the following conditions are violated:
///
/// * `data` must be [valid] for writes for `len * mem::size_of::<T>()` many bytes,
/// and it must be properly aligned. This means in particular:
///
/// See the documentation of [`from_raw_parts`] for more details.
/// * The entire memory range of this slice must be contained within a single allocated object!
/// Slices can never span across multiple allocated objects.
/// * `data` must be non-null and aligned even for zero-length slices. One
/// reason for this is that enum layout optimizations may rely on references
/// (including slices of any length) being aligned and non-null to distinguish
/// them from other data. You can obtain a pointer that is usable as `data`
/// for zero-length slices using [`NonNull::dangling()`].
///
/// * The memory referenced by the returned slice must not be accessed through any other pointer
/// (not derived from the return value) for the duration of lifetime `'a`.
/// Both read and write accesses are forbidden.
///
/// * The total size `len * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
/// See the safety documentation of [`pointer::offset`].
///
/// [valid]: ../../std/ptr/index.html#safety
/// [`NonNull::dangling()`]: ../../std/ptr/struct.NonNull.html#method.dangling
/// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset
/// [`from_raw_parts`]: ../../std/slice/fn.from_raw_parts.html
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] {
debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice");
debug_assert!(mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize,
"attempt to create slice covering half the address space");
"attempt to create slice covering at least half the address space");
&mut *ptr::slice_from_raw_parts_mut(data, len)
}

6 changes: 3 additions & 3 deletions src/librustc/error_codes.rs
Original file line number Diff line number Diff line change
@@ -607,7 +607,7 @@ position that needs that trait. For example, when the following code is
compiled:
```compile_fail
#![feature(on_unimplemented)]
#![feature(rustc_attrs)]
fn foo<T: Index<u8>>(x: T){}
@@ -639,7 +639,7 @@ position that needs that trait. For example, when the following code is
compiled:
```compile_fail
#![feature(on_unimplemented)]
#![feature(rustc_attrs)]
fn foo<T: Index<u8>>(x: T){}
@@ -669,7 +669,7 @@ position that needs that trait. For example, when the following code is
compiled:
```compile_fail
#![feature(on_unimplemented)]
#![feature(rustc_attrs)]
fn foo<T: Index<u8>>(x: T){}
9 changes: 9 additions & 0 deletions src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
@@ -1616,6 +1616,11 @@ pub enum ExprKind {
/// and the remaining elements are the rest of the arguments.
/// Thus, `x.foo::<Bar, Baz>(a, b, c, d)` is represented as
/// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, [x, a, b, c, d])`.
///
/// To resolve the called method to a `DefId`, call [`type_dependent_def_id`] with
/// the `hir_id` of the `MethodCall` node itself.
///
/// [`type_dependent_def_id`]: ../ty/struct.TypeckTables.html#method.type_dependent_def_id
MethodCall(P<PathSegment>, Span, HirVec<Expr>),
/// A tuple (e.g., `(a, b, c, d)`).
Tup(HirVec<Expr>),
@@ -1698,6 +1703,10 @@ pub enum ExprKind {
}

/// Represents an optionally `Self`-qualified value/type path or associated extension.
///
/// To resolve the path to a `DefId`, call [`qpath_res`].
///
/// [`qpath_res`]: ../ty/struct.TypeckTables.html#method.qpath_res
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum QPath {
/// Path to a definition, optionally "fully-qualified" with a `Self`
4 changes: 2 additions & 2 deletions src/librustc_mir/interpret/cast.rs
Original file line number Diff line number Diff line change
@@ -260,7 +260,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {

match (&src_pointee_ty.kind, &dest_pointee_ty.kind) {
(&ty::Array(_, length), &ty::Slice(_)) => {
let ptr = self.read_immediate(src)?.to_scalar_ptr()?;
let ptr = self.read_immediate(src)?.to_scalar()?;
// u64 cast is from usize to u64, which is always good
let val = Immediate::new_slice(
ptr,
@@ -279,7 +279,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
(_, &ty::Dynamic(ref data, _)) => {
// Initial cast from sized to dyn trait
let vtable = self.get_vtable(src_pointee_ty, data.principal())?;
let ptr = self.read_immediate(src)?.to_scalar_ptr()?;
let ptr = self.read_immediate(src)?.to_scalar()?;
let val = Immediate::new_dyn_trait(ptr, vtable);
self.write_immediate(val, dest)
}
22 changes: 10 additions & 12 deletions src/librustc_mir/interpret/intern.rs
Original file line number Diff line number Diff line change
@@ -192,20 +192,18 @@ for
let ty = mplace.layout.ty;
if let ty::Ref(_, referenced_ty, mutability) = ty.kind {
let value = self.ecx.read_immediate(mplace.into())?;
let mplace = self.ecx.ref_to_mplace(value)?;
// Handle trait object vtables
if let Ok(meta) = value.to_meta() {
if let ty::Dynamic(..) =
self.ecx.tcx.struct_tail_erasing_lifetimes(
referenced_ty, self.ecx.param_env).kind
{
if let Ok(vtable) = meta.unwrap().to_ptr() {
// explitly choose `Immutable` here, since vtables are immutable, even
// if the reference of the fat pointer is mutable
self.intern_shallow(vtable.alloc_id, Mutability::Immutable, None)?;
}
if let ty::Dynamic(..) =
self.ecx.tcx.struct_tail_erasing_lifetimes(
referenced_ty, self.ecx.param_env).kind
{
if let Ok(vtable) = mplace.meta.unwrap().to_ptr() {
// explitly choose `Immutable` here, since vtables are immutable, even
// if the reference of the fat pointer is mutable
self.intern_shallow(vtable.alloc_id, Mutability::Immutable, None)?;
}
}
let mplace = self.ecx.ref_to_mplace(value)?;
// Check if we have encountered this pointer+layout combination before.
// Only recurse for allocation-backed pointers.
if let Scalar::Ptr(ptr) = mplace.ptr {
@@ -230,7 +228,7 @@ for
ty::Array(_, n)
if n.eval_usize(self.ecx.tcx.tcx, self.ecx.param_env) == 0 => {}
ty::Slice(_)
if value.to_meta().unwrap().unwrap().to_usize(self.ecx)? == 0 => {}
if mplace.meta.unwrap().to_usize(self.ecx)? == 0 => {}
_ => bug!("const qualif failed to prevent mutable references"),
}
},
20 changes: 0 additions & 20 deletions src/librustc_mir/interpret/operand.rs
Original file line number Diff line number Diff line change
@@ -82,26 +82,6 @@ impl<'tcx, Tag> Immediate<Tag> {
Immediate::ScalarPair(a, b) => Ok((a.not_undef()?, b.not_undef()?))
}
}

/// Converts the immediate into a pointer (or a pointer-sized integer).
/// Throws away the second half of a ScalarPair!
#[inline]
pub fn to_scalar_ptr(self) -> InterpResult<'tcx, Scalar<Tag>> {
match self {
Immediate::Scalar(ptr) |
Immediate::ScalarPair(ptr, _) => ptr.not_undef(),
}
}

/// Converts the value into its metadata.
/// Throws away the first half of a ScalarPair!
#[inline]
pub fn to_meta(self) -> InterpResult<'tcx, Option<Scalar<Tag>>> {
Ok(match self {
Immediate::Scalar(_) => None,
Immediate::ScalarPair(_, meta) => Some(meta.not_undef()?),
})
}
}

// ScalarPair needs a type to interpret, so we often have an immediate and a type together
12 changes: 9 additions & 3 deletions src/librustc_mir/interpret/place.rs
Original file line number Diff line number Diff line change
@@ -287,17 +287,23 @@ where
&self,
val: ImmTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
let pointee_type = val.layout.ty.builtin_deref(true).unwrap().ty;
let pointee_type = val.layout.ty.builtin_deref(true)
.expect("`ref_to_mplace` called on non-ptr type")
.ty;
let layout = self.layout_of(pointee_type)?;
let (ptr, meta) = match *val {
Immediate::Scalar(ptr) => (ptr.not_undef()?, None),
Immediate::ScalarPair(ptr, meta) => (ptr.not_undef()?, Some(meta.not_undef()?)),
};

let mplace = MemPlace {
ptr: val.to_scalar_ptr()?,
ptr,
// We could use the run-time alignment here. For now, we do not, because
// the point of tracking the alignment here is to make sure that the *static*
// alignment information emitted with the loads is correct. The run-time
// alignment can only be more restrictive.
align: layout.align.abi,
meta: val.to_meta()?,
meta,
};
Ok(MPlaceTy { mplace, layout })
}
44 changes: 15 additions & 29 deletions src/librustc_mir/interpret/validity.rs
Original file line number Diff line number Diff line change
@@ -388,44 +388,31 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
}
}
ty::RawPtr(..) => {
// Check pointer part.
if self.ref_tracking_for_consts.is_some() {
// Integers/floats in CTFE: For consistency with integers, we do not
// accept undef.
let _ptr = try_validation!(value.to_scalar_ptr(),
"undefined address in raw pointer", self.path);
} else {
// Remain consistent with `usize`: Accept anything.
}

// Check metadata.
let meta = try_validation!(value.to_meta(),
"uninitialized data in wide pointer metadata", self.path);
let layout = self.ecx.layout_of(value.layout.ty.builtin_deref(true).unwrap().ty)?;
if layout.is_unsized() {
self.check_wide_ptr_meta(meta, layout)?;
// We are conservative with undef for integers, but try to
// actually enforce our current rules for raw pointers.
let place = try_validation!(self.ecx.ref_to_mplace(value),
"undefined pointer", self.path);
if place.layout.is_unsized() {
self.check_wide_ptr_meta(place.meta, place.layout)?;
}
}
_ if ty.is_box() || ty.is_region_ptr() => {
// Handle wide pointers.
// Check metadata early, for better diagnostics
let ptr = try_validation!(value.to_scalar_ptr(),
"undefined address in pointer", self.path);
let meta = try_validation!(value.to_meta(),
"uninitialized data in wide pointer metadata", self.path);
let layout = self.ecx.layout_of(value.layout.ty.builtin_deref(true).unwrap().ty)?;
if layout.is_unsized() {
self.check_wide_ptr_meta(meta, layout)?;
let place = try_validation!(self.ecx.ref_to_mplace(value),
"undefined pointer", self.path);
if place.layout.is_unsized() {
self.check_wide_ptr_meta(place.meta, place.layout)?;
}
// Make sure this is dereferencable and all.
let (size, align) = self.ecx.size_and_align_of(meta, layout)?
let (size, align) = self.ecx.size_and_align_of(place.meta, place.layout)?
// for the purpose of validity, consider foreign types to have
// alignment and size determined by the layout (size will be 0,
// alignment should take attributes into account).
.unwrap_or_else(|| (layout.size, layout.align.abi));
.unwrap_or_else(|| (place.layout.size, place.layout.align.abi));
let ptr: Option<_> = match
self.ecx.memory.check_ptr_access_align(
ptr,
place.ptr,
size,
Some(align),
CheckInAllocMsg::InboundsTest,
@@ -435,7 +422,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
Err(err) => {
info!(
"{:?} did not pass access check for size {:?}, align {:?}",
ptr, size, align
place.ptr, size, align
);
match err.kind {
err_unsup!(InvalidNullPointerUsage) =>
@@ -459,7 +446,6 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
};
// Recursive checking
if let Some(ref mut ref_tracking) = self.ref_tracking_for_consts {
let place = self.ecx.ref_to_mplace(value)?;
if let Some(ptr) = ptr { // not a ZST
// Skip validation entirely for some external statics
let alloc_kind = self.ecx.tcx.alloc_map.lock().get(ptr.alloc_id);
@@ -627,7 +613,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
// reject it. However, that's good: We don't inherently want
// to reject those pointers, we just do not have the machinery to
// talk about parts of a pointer.
// We also accept undef, for consistency with the type-based checks.
// We also accept undef, for consistency with the slow path.
match self.ecx.memory.get(ptr.alloc_id)?.check_bytes(
self.ecx,
ptr,
2 changes: 1 addition & 1 deletion src/libstd/lib.rs
Original file line number Diff line number Diff line change
@@ -284,7 +284,7 @@
#![feature(never_type)]
#![feature(nll)]
#![cfg_attr(bootstrap, feature(non_exhaustive))]
#![feature(on_unimplemented)]
#![cfg_attr(bootstrap, feature(on_unimplemented))]
#![feature(optin_builtin_traits)]
#![feature(panic_info_message)]
#![feature(panic_internals)]
4 changes: 2 additions & 2 deletions src/libstd/thread/local.rs
Original file line number Diff line number Diff line change
@@ -149,7 +149,7 @@ macro_rules! thread_local {
#[allow_internal_unstable(thread_local_internals, cfg_target_thread_local, thread_local)]
#[allow_internal_unsafe]
macro_rules! __thread_local_inner {
(@key $(#[$attr:meta])* $vis:vis $name:ident, $t:ty, $init:expr) => {
(@key $t:ty, $init:expr) => {
{
#[inline]
fn __init() -> $t { $init }
@@ -184,7 +184,7 @@ macro_rules! __thread_local_inner {
};
($(#[$attr:meta])* $vis:vis $name:ident, $t:ty, $init:expr) => {
$(#[$attr])* $vis const $name: $crate::thread::LocalKey<$t> =
$crate::__thread_local_inner!(@key $(#[$attr])* $vis $name, $t, $init);
$crate::__thread_local_inner!(@key $t, $init);
}
}

3 changes: 0 additions & 3 deletions src/libsyntax/feature_gate/active.rs
Original file line number Diff line number Diff line change
@@ -134,9 +134,6 @@ declare_features! (
/// Allows using `rustc_*` attributes (RFC 572).
(active, rustc_attrs, "1.0.0", Some(29642), None),

/// Allows using `#[on_unimplemented(..)]` on traits.
(active, on_unimplemented, "1.0.0", Some(29628), None),

/// Allows using the `box $expr` syntax.
(active, box_syntax, "1.0.0", Some(49733), None),

15 changes: 7 additions & 8 deletions src/libsyntax/feature_gate/builtin_attrs.rs
Original file line number Diff line number Diff line change
@@ -166,7 +166,7 @@ macro_rules! experimental {
}

const IMPL_DETAIL: &str = "internal implementation detail";
const INTERAL_UNSTABLE: &str = "this is an internal attribute that will never be stable";
const INTERNAL_UNSTABLE: &str = "this is an internal attribute that will never be stable";

pub type BuiltinAttribute = (Symbol, AttributeType, AttributeTemplate, AttributeGate);

@@ -418,14 +418,14 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
linkage, Whitelisted, template!(NameValueStr: "external|internal|..."),
"the `linkage` attribute is experimental and not portable across platforms",
),
rustc_attr!(rustc_std_internal_symbol, Whitelisted, template!(Word), INTERAL_UNSTABLE),
rustc_attr!(rustc_std_internal_symbol, Whitelisted, template!(Word), INTERNAL_UNSTABLE),

// ==========================================================================
// Internal attributes, Macro related:
// ==========================================================================

rustc_attr!(rustc_builtin_macro, Whitelisted, template!(Word), IMPL_DETAIL),
rustc_attr!(rustc_proc_macro_decls, Normal, template!(Word), INTERAL_UNSTABLE),
rustc_attr!(rustc_proc_macro_decls, Normal, template!(Word), INTERNAL_UNSTABLE),
rustc_attr!(
rustc_macro_transparency, Whitelisted,
template!(NameValueStr: "transparent|semitransparent|opaque"),
@@ -436,25 +436,24 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
// Internal attributes, Diagnostics related:
// ==========================================================================

gated!(
rustc_attr!(
rustc_on_unimplemented, Whitelisted,
template!(
List: r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#,
NameValueStr: "message"
),
on_unimplemented,
experimental!(rustc_on_unimplemented),
INTERNAL_UNSTABLE
),
// Whitelists "identity-like" conversion methods to suggest on type mismatch.
rustc_attr!(rustc_conversion_suggestion, Whitelisted, template!(Word), INTERAL_UNSTABLE),
rustc_attr!(rustc_conversion_suggestion, Whitelisted, template!(Word), INTERNAL_UNSTABLE),

// ==========================================================================
// Internal attributes, Const related:
// ==========================================================================

rustc_attr!(rustc_promotable, Whitelisted, template!(Word), IMPL_DETAIL),
rustc_attr!(rustc_allow_const_fn_ptr, Whitelisted, template!(Word), IMPL_DETAIL),
rustc_attr!(rustc_args_required_const, Whitelisted, template!(List: "N"), INTERAL_UNSTABLE),
rustc_attr!(rustc_args_required_const, Whitelisted, template!(List: "N"), INTERNAL_UNSTABLE),

// ==========================================================================
// Internal attributes, Layout related:
3 changes: 3 additions & 0 deletions src/libsyntax/feature_gate/removed.rs
Original file line number Diff line number Diff line change
@@ -99,6 +99,9 @@ declare_features! (
/// + `__register_diagnostic`
/// +`__build_diagnostic_array`
(removed, rustc_diagnostic_macros, "1.38.0", None, None, None),
/// Allows using `#[on_unimplemented(..)]` on traits.
/// (Moved to `rustc_attrs`.)
(removed, on_unimplemented, "1.40.0", None, None, None),

// -------------------------------------------------------------------------
// feature-group-end: removed features
6 changes: 1 addition & 5 deletions src/test/codegen/abi-efiapi.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
// Checks if the correct annotation for the efiapi ABI is passed to llvm.

// revisions:x86_64 i686 aarch64 arm riscv
// revisions:x86_64 i686 arm

// min-llvm-version 9.0

//[x86_64] compile-flags: --target x86_64-unknown-uefi
//[i686] compile-flags: --target i686-unknown-linux-musl
//[aarch64] compile-flags: --target aarch64-unknown-none
//[arm] compile-flags: --target armv7r-none-eabi
//[riscv] compile-flags: --target riscv64gc-unknown-none-elf
// compile-flags: -C no-prepopulate-passes

#![crate_type = "lib"]
@@ -24,8 +22,6 @@ trait Copy { }

//x86_64: define win64cc void @has_efiapi
//i686: define void @has_efiapi
//aarch64: define void @has_efiapi
//arm: define void @has_efiapi
//riscv: define void @has_efiapi
#[no_mangle]
pub extern "efiapi" fn has_efiapi() {}
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@
// revisions: cfail1 cfail2
// build-pass (FIXME(62277): could be check-pass?)

#![feature(on_unimplemented)]
#![feature(rustc_attrs)]
#![deny(unused_attributes)]

#[rustc_on_unimplemented = "invalid"]
4 changes: 2 additions & 2 deletions src/test/ui/consts/const-eval/ub-wide-ptr.stderr
Original file line number Diff line number Diff line change
@@ -42,7 +42,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:107:1
|
LL | const SLICE_LENGTH_UNINIT: &[u8] = unsafe { SliceTransmute { addr: 42 }.slice};
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized data in wide pointer metadata
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered undefined pointer
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.

@@ -90,7 +90,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-wide-ptr.rs:133:1
|
LL | const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { SliceTransmute { addr: 42 }.raw_slice};
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized data in wide pointer metadata
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered undefined pointer
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.

9 changes: 0 additions & 9 deletions src/test/ui/feature-gates/feature-gate-on-unimplemented.rs

This file was deleted.

2 changes: 1 addition & 1 deletion src/test/ui/on-unimplemented/bad-annotation.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// ignore-tidy-linelength

#![feature(on_unimplemented)]
#![feature(rustc_attrs)]

#![allow(unused)]

2 changes: 1 addition & 1 deletion src/test/ui/on-unimplemented/expected-comma-found-token.rs
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
// access to the variable, whether that mutable access be used
// for direct assignment or for taking mutable ref. Issue #6801.

#![feature(on_unimplemented)]
#![feature(rustc_attrs)]

#[rustc_on_unimplemented(
message="the message"
8 changes: 8 additions & 0 deletions src/test/ui/on-unimplemented/feature-gate-on-unimplemented.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Test that `#[rustc_on_unimplemented]` is gated by `rustc_attrs` feature gate.

#[rustc_on_unimplemented = "test error `{Self}` with `{Bar}`"]
//~^ ERROR this is an internal attribute that will never be stable
trait Foo<Bar>
{}

fn main() {}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error[E0658]: the `#[rustc_on_unimplemented]` attribute is an experimental feature
--> $DIR/feature-gate-on-unimplemented.rs:4:1
error[E0658]: this is an internal attribute that will never be stable
--> $DIR/feature-gate-on-unimplemented.rs:3:1
|
LL | #[rustc_on_unimplemented = "test error `{Self}` with `{Bar}`"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/29628
= help: add `#![feature(on_unimplemented)]` to the crate attributes to enable
= note: for more information, see https://github.com/rust-lang/rust/issues/29642
= help: add `#![feature(rustc_attrs)]` to the crate attributes to enable

error: aborting due to previous error

2 changes: 1 addition & 1 deletion src/test/ui/on-unimplemented/multiple-impls.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Test if the on_unimplemented message override works

#![feature(on_unimplemented)]
#![feature(rustc_attrs)]


struct Foo<T>(T);
2 changes: 1 addition & 1 deletion src/test/ui/on-unimplemented/on-impl.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Test if the on_unimplemented message override works

#![feature(on_unimplemented)]
#![feature(rustc_attrs)]


#[rustc_on_unimplemented = "invalid"]
2 changes: 1 addition & 1 deletion src/test/ui/on-unimplemented/on-trait.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// ignore-tidy-linelength

#![feature(on_unimplemented)]
#![feature(rustc_attrs)]

pub mod Bar {
#[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}` in `{Foo}`"]
2 changes: 1 addition & 1 deletion src/tools/clippy