Skip to content

Rewrite Gankra's provenance draft to be lib-only #95229

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 5 commits into from
Closed
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
20 changes: 11 additions & 9 deletions compiler/rustc_arena/src/lib.rs
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@
#![feature(decl_macro)]
#![feature(rustc_attrs)]
#![cfg_attr(test, feature(test))]
#![feature(strict_provenance)]

use smallvec::SmallVec;

@@ -87,7 +88,7 @@ impl<T> ArenaChunk<T> {
unsafe {
if mem::size_of::<T>() == 0 {
// A pointer as large as possible for zero-sized elements.
!0 as *mut T
ptr::invalid_mut(!0)
} else {
self.start().add(self.storage.len())
}
@@ -199,7 +200,7 @@ impl<T> TypedArena<T> {
unsafe {
if mem::size_of::<T>() == 0 {
self.ptr.set((self.ptr.get() as *mut u8).wrapping_offset(1) as *mut T);
let ptr = mem::align_of::<T>() as *mut T;
let ptr = ptr::NonNull::<T>::dangling().as_ptr();
// Don't drop the object. This `write` is equivalent to `forget`.
ptr::write(ptr, object);
&mut *ptr
@@ -216,7 +217,7 @@ impl<T> TypedArena<T> {

#[inline]
fn can_allocate(&self, additional: usize) -> bool {
let available_bytes = self.end.get() as usize - self.ptr.get() as usize;
let available_bytes = self.end.get().addr() - self.ptr.get().addr();
let additional_bytes = additional.checked_mul(mem::size_of::<T>()).unwrap();
available_bytes >= additional_bytes
}
@@ -262,7 +263,7 @@ impl<T> TypedArena<T> {
// If a type is `!needs_drop`, we don't need to keep track of how many elements
// the chunk stores - the field will be ignored anyway.
if mem::needs_drop::<T>() {
let used_bytes = self.ptr.get() as usize - last_chunk.start() as usize;
let used_bytes = self.ptr.get().addr() - last_chunk.start().addr();
last_chunk.entries = used_bytes / mem::size_of::<T>();
}

@@ -288,9 +289,9 @@ impl<T> TypedArena<T> {
// chunks.
fn clear_last_chunk(&self, last_chunk: &mut ArenaChunk<T>) {
// Determine how much was filled.
let start = last_chunk.start() as usize;
let start = last_chunk.start().addr();
// We obtain the value of the pointer to the first uninitialized element.
let end = self.ptr.get() as usize;
let end = self.ptr.get().addr();
// We then calculate the number of elements to be dropped in the last chunk,
// which is the filled area's length.
let diff = if mem::size_of::<T>() == 0 {
@@ -395,15 +396,16 @@ impl DroplessArena {
/// request.
#[inline]
fn alloc_raw_without_grow(&self, layout: Layout) -> Option<*mut u8> {
let start = self.start.get() as usize;
let end = self.end.get() as usize;
let start = self.start.get().addr();
let old_end = self.end.get();
let end = old_end.addr();

let align = layout.align();
let bytes = layout.size();

let new_end = end.checked_sub(bytes)? & !(align - 1);
if start <= new_end {
let new_end = new_end as *mut u8;
let new_end = old_end.with_addr(new_end);
self.end.set(new_end);
Some(new_end)
} else {
1 change: 1 addition & 0 deletions compiler/rustc_codegen_ssa/src/lib.rs
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@
#![feature(once_cell)]
#![feature(nll)]
#![feature(associated_type_bounds)]
#![feature(strict_provenance)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]

2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/mono_item.rs
Original file line number Diff line number Diff line change
@@ -116,7 +116,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
fn to_raw_string(&self) -> String {
match *self {
MonoItem::Fn(instance) => {
format!("Fn({:?}, {})", instance.def, instance.substs.as_ptr() as usize)
format!("Fn({:?}, {})", instance.def, instance.substs.as_ptr().addr())
}
MonoItem::Static(id) => format!("Static({:?})", id),
MonoItem::GlobalAsm(id) => format!("GlobalAsm({:?})", id),
1 change: 1 addition & 0 deletions library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -158,6 +158,7 @@
#![feature(rustc_allow_const_fn_unstable)]
#![feature(rustc_attrs)]
#![feature(staged_api)]
#![feature(strict_provenance)]
#![cfg_attr(test, feature(test))]
#![feature(unboxed_closures)]
#![feature(unsized_fn_params)]
5 changes: 2 additions & 3 deletions library/alloc/src/rc.rs
Original file line number Diff line number Diff line change
@@ -2115,13 +2115,12 @@ impl<T> Weak<T> {
#[rustc_const_unstable(feature = "const_weak_new", issue = "95091", reason = "recently added")]
#[must_use]
pub const fn new() -> Weak<T> {
Weak { ptr: unsafe { NonNull::new_unchecked(usize::MAX as *mut RcBox<T>) } }
Weak { ptr: unsafe { NonNull::new_unchecked(ptr::invalid_mut::<RcBox<T>>(usize::MAX)) } }
}
}

pub(crate) fn is_dangling<T: ?Sized>(ptr: *mut T) -> bool {
let address = ptr as *mut () as usize;
address == usize::MAX
(ptr as *mut ()).addr() == usize::MAX
}

/// Helper type to allow accessing the reference counts without
2 changes: 1 addition & 1 deletion library/alloc/src/slice.rs
Original file line number Diff line number Diff line change
@@ -1044,7 +1044,7 @@ where
impl<T> Drop for MergeHole<T> {
fn drop(&mut self) {
// `T` is not a zero-sized type, so it's okay to divide by its size.
let len = (self.end as usize - self.start as usize) / mem::size_of::<T>();
let len = (self.end.addr() - self.start.addr()) / mem::size_of::<T>();
unsafe {
ptr::copy_nonoverlapping(self.start, self.dest, len);
}
2 changes: 1 addition & 1 deletion library/alloc/src/sync.rs
Original file line number Diff line number Diff line change
@@ -1745,7 +1745,7 @@ impl<T> Weak<T> {
#[rustc_const_unstable(feature = "const_weak_new", issue = "95091", reason = "recently added")]
#[must_use]
pub const fn new() -> Weak<T> {
Weak { ptr: unsafe { NonNull::new_unchecked(usize::MAX as *mut ArcInner<T>) } }
Weak { ptr: unsafe { NonNull::new_unchecked(ptr::invalid_mut::<ArcInner<T>>(usize::MAX)) } }
}
}

2 changes: 1 addition & 1 deletion library/alloc/src/vec/into_iter.rs
Original file line number Diff line number Diff line change
@@ -154,7 +154,7 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let exact = if mem::size_of::<T>() == 0 {
(self.end as usize).wrapping_sub(self.ptr as usize)
self.end.addr().wrapping_sub(self.ptr.addr())
} else {
unsafe { self.end.offset_from(self.ptr) as usize }
};
2 changes: 1 addition & 1 deletion library/core/src/alloc/layout.rs
Original file line number Diff line number Diff line change
@@ -194,7 +194,7 @@ impl Layout {
#[inline]
pub const fn dangling(&self) -> NonNull<u8> {
// SAFETY: align is guaranteed to be non-zero
unsafe { NonNull::new_unchecked(self.align() as *mut u8) }
unsafe { NonNull::new_unchecked(crate::ptr::invalid_mut::<u8>(self.align())) }
}

/// Creates a layout describing the record that can hold a value
8 changes: 6 additions & 2 deletions library/core/src/fmt/mod.rs
Original file line number Diff line number Diff line change
@@ -352,7 +352,11 @@ impl<'a> ArgumentV1<'a> {
}

fn as_usize(&self) -> Option<usize> {
if self.formatter as usize == USIZE_MARKER as usize {
// We are type punning a bit here: USIZE_MARKER only takes an &usize but
// formatter takes an &Opaque. Rust understandably doesn't think we should compare
// the function pointers if they don't have the same signature, so we cast to
// pointers to convince it that we know what we're doing.
if self.formatter as *mut u8 == USIZE_MARKER as *mut u8 {
// SAFETY: The `formatter` field is only set to USIZE_MARKER if
// the value is a usize, so this is safe
Some(unsafe { *(self.value as *const _ as *const usize) })
@@ -2246,7 +2250,7 @@ impl<T: ?Sized> Pointer for *const T {
}
f.flags |= 1 << (FlagV1::Alternate as u32);

let ret = LowerHex::fmt(&(ptr as usize), f);
let ret = LowerHex::fmt(&(ptr.addr()), f);

f.width = old_width;
f.flags = old_flags;
4 changes: 2 additions & 2 deletions library/core/src/hash/mod.rs
Original file line number Diff line number Diff line change
@@ -793,7 +793,7 @@ mod impls {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
let (address, metadata) = self.to_raw_parts();
state.write_usize(address as usize);
state.write_usize(address.addr());
metadata.hash(state);
}
}
@@ -803,7 +803,7 @@ mod impls {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
let (address, metadata) = self.to_raw_parts();
state.write_usize(address as usize);
state.write_usize(address.addr());
metadata.hash(state);
}
}
11 changes: 6 additions & 5 deletions library/core/src/intrinsics.rs
Original file line number Diff line number Diff line change
@@ -982,13 +982,14 @@ extern "rust-intrinsic" {
/// Turning a pointer into a `usize`:
///
/// ```
/// #![feature(strict_provenance)]
/// let ptr = &0;
/// let ptr_num_transmute = unsafe {
/// std::mem::transmute::<&i32, usize>(ptr)
/// };
///
/// // Use an `as` cast instead
/// let ptr_num_cast = ptr as *const i32 as usize;
/// // Use `.addr()` instead
/// let ptr_num_cast = (ptr as *const i32).addr();
/// ```
///
/// Turning a `*mut T` into an `&mut T`:
@@ -1972,15 +1973,15 @@ extern "rust-intrinsic" {
/// Checks whether `ptr` is properly aligned with respect to
/// `align_of::<T>()`.
pub(crate) fn is_aligned_and_not_null<T>(ptr: *const T) -> bool {
!ptr.is_null() && ptr as usize % mem::align_of::<T>() == 0
!ptr.is_null() && ptr.addr() % mem::align_of::<T>() == 0
}

/// Checks whether the regions of memory starting at `src` and `dst` of size
/// `count * size_of::<T>()` do *not* overlap.
#[cfg(debug_assertions)]
pub(crate) fn is_nonoverlapping<T>(src: *const T, dst: *const T, count: usize) -> bool {
let src_usize = src as usize;
let dst_usize = dst as usize;
let src_usize = src.addr();
let dst_usize = dst.addr();
let size = mem::size_of::<T>().checked_mul(count).unwrap();
let diff = if src_usize > dst_usize { src_usize - dst_usize } else { dst_usize - src_usize };
// If the absolute distance between the ptrs is at least as big as the size of the buffer,
1 change: 1 addition & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -146,6 +146,7 @@
#![feature(ptr_metadata)]
#![feature(slice_ptr_get)]
#![feature(str_internals)]
#![feature(strict_provenance)]
#![feature(utf16_extra)]
#![feature(utf16_extra_const)]
#![feature(variant_count)]
Loading