d1462d8558
Implement RFC 2580: Pointer metadata & VTable RFC: https://github.com/rust-lang/rfcs/pull/2580 ~~Before merging this PR:~~ * [x] Wait for the end of the RFC’s [FCP to merge](https://github.com/rust-lang/rfcs/pull/2580#issuecomment-759145278). * [x] Open a tracking issue: https://github.com/rust-lang/rust/issues/81513 * [x] Update `#[unstable]` attributes in the PR with the tracking issue number ---- This PR extends the language with a new lang item for the `Pointee` trait which is special-cased in trait resolution to implement it for all types. Even in generic contexts, parameters can be assumed to implement it without a corresponding bound. For this I mostly imitated what the compiler was already doing for the `DiscriminantKind` trait. I’m very unfamiliar with compiler internals, so careful review is appreciated. This PR also extends the standard library with new unstable APIs in `core::ptr` and `std::ptr`: ```rust pub trait Pointee { /// One of `()`, `usize`, or `DynMetadata<dyn SomeTrait>` type Metadata: Copy + Send + Sync + Ord + Hash + Unpin; } pub trait Thin = Pointee<Metadata = ()>; pub const fn metadata<T: ?Sized>(ptr: *const T) -> <T as Pointee>::Metadata {} pub const fn from_raw_parts<T: ?Sized>(*const (), <T as Pointee>::Metadata) -> *const T {} pub const fn from_raw_parts_mut<T: ?Sized>(*mut (),<T as Pointee>::Metadata) -> *mut T {} impl<T: ?Sized> NonNull<T> { pub const fn from_raw_parts(NonNull<()>, <T as Pointee>::Metadata) -> NonNull<T> {} /// Convenience for `(ptr.cast(), metadata(ptr))` pub const fn to_raw_parts(self) -> (NonNull<()>, <T as Pointee>::Metadata) {} } impl<T: ?Sized> *const T { pub const fn to_raw_parts(self) -> (*const (), <T as Pointee>::Metadata) {} } impl<T: ?Sized> *mut T { pub const fn to_raw_parts(self) -> (*mut (), <T as Pointee>::Metadata) {} } /// `<dyn SomeTrait as Pointee>::Metadata == DynMetadata<dyn SomeTrait>` pub struct DynMetadata<Dyn: ?Sized> { // Private pointer to vtable } impl<Dyn: ?Sized> DynMetadata<Dyn> { pub fn size_of(self) -> usize {} pub fn align_of(self) -> usize {} pub fn layout(self) -> crate::alloc::Layout {} } unsafe impl<Dyn: ?Sized> Send for DynMetadata<Dyn> {} unsafe impl<Dyn: ?Sized> Sync for DynMetadata<Dyn> {} impl<Dyn: ?Sized> Debug for DynMetadata<Dyn> {} impl<Dyn: ?Sized> Unpin for DynMetadata<Dyn> {} impl<Dyn: ?Sized> Copy for DynMetadata<Dyn> {} impl<Dyn: ?Sized> Clone for DynMetadata<Dyn> {} impl<Dyn: ?Sized> Eq for DynMetadata<Dyn> {} impl<Dyn: ?Sized> PartialEq for DynMetadata<Dyn> {} impl<Dyn: ?Sized> Ord for DynMetadata<Dyn> {} impl<Dyn: ?Sized> PartialOrd for DynMetadata<Dyn> {} impl<Dyn: ?Sized> Hash for DynMetadata<Dyn> {} ``` API differences from the RFC, in areas noted as unresolved questions in the RFC: * Module-level functions instead of associated `from_raw_parts` functions on `*const T` and `*mut T`, following the precedent of `null`, `slice_from_raw_parts`, etc. * Added `to_raw_parts`
124 lines
2.9 KiB
Rust
124 lines
2.9 KiB
Rust
#![feature(alloc_layout_extra)]
|
|
#![feature(array_chunks)]
|
|
#![feature(array_from_ref)]
|
|
#![feature(array_methods)]
|
|
#![feature(array_map)]
|
|
#![feature(array_windows)]
|
|
#![feature(bool_to_option)]
|
|
#![feature(bound_cloned)]
|
|
#![feature(box_syntax)]
|
|
#![feature(cell_update)]
|
|
#![feature(cfg_panic)]
|
|
#![feature(cfg_target_has_atomic)]
|
|
#![feature(const_assume)]
|
|
#![feature(const_cell_into_inner)]
|
|
#![feature(const_maybe_uninit_assume_init)]
|
|
#![feature(const_ptr_read)]
|
|
#![feature(const_ptr_offset)]
|
|
#![feature(control_flow_enum)]
|
|
#![feature(core_intrinsics)]
|
|
#![feature(core_private_bignum)]
|
|
#![feature(core_private_diy_float)]
|
|
#![feature(debug_non_exhaustive)]
|
|
#![feature(dec2flt)]
|
|
#![feature(div_duration)]
|
|
#![feature(duration_consts_2)]
|
|
#![feature(duration_constants)]
|
|
#![feature(duration_saturating_ops)]
|
|
#![feature(duration_zero)]
|
|
#![feature(exact_size_is_empty)]
|
|
#![feature(extern_types)]
|
|
#![feature(fixed_size_array)]
|
|
#![feature(flt2dec)]
|
|
#![feature(fmt_internals)]
|
|
#![feature(hashmap_internals)]
|
|
#![feature(try_find)]
|
|
#![feature(is_sorted)]
|
|
#![feature(pattern)]
|
|
#![feature(raw)]
|
|
#![feature(sort_internals)]
|
|
#![feature(slice_partition_at_index)]
|
|
#![feature(maybe_uninit_uninit_array)]
|
|
#![feature(maybe_uninit_array_assume_init)]
|
|
#![feature(maybe_uninit_extra)]
|
|
#![feature(maybe_uninit_write_slice)]
|
|
#![feature(min_specialization)]
|
|
#![feature(step_trait)]
|
|
#![feature(step_trait_ext)]
|
|
#![feature(str_internals)]
|
|
#![feature(test)]
|
|
#![feature(trusted_len)]
|
|
#![feature(try_trait)]
|
|
#![feature(slice_internals)]
|
|
#![feature(slice_partition_dedup)]
|
|
#![feature(int_error_matching)]
|
|
#![feature(iter_advance_by)]
|
|
#![feature(iter_partition_in_place)]
|
|
#![feature(iter_intersperse)]
|
|
#![feature(iter_is_partitioned)]
|
|
#![feature(iter_order_by)]
|
|
#![feature(cmp_min_max_by)]
|
|
#![feature(iter_map_while)]
|
|
#![feature(const_mut_refs)]
|
|
#![feature(const_pin)]
|
|
#![feature(const_slice_from_raw_parts)]
|
|
#![feature(const_raw_ptr_deref)]
|
|
#![feature(never_type)]
|
|
#![feature(unwrap_infallible)]
|
|
#![feature(option_result_unwrap_unchecked)]
|
|
#![feature(result_into_ok_or_err)]
|
|
#![feature(option_unwrap_none)]
|
|
#![feature(peekable_peek_mut)]
|
|
#![cfg_attr(not(bootstrap), feature(ptr_metadata))]
|
|
#![feature(once_cell)]
|
|
#![feature(unsafe_block_in_unsafe_fn)]
|
|
#![feature(unsized_tuple_coercion)]
|
|
#![feature(int_bits_const)]
|
|
#![feature(nonzero_leading_trailing_zeros)]
|
|
#![feature(const_option)]
|
|
#![feature(integer_atomics)]
|
|
#![feature(slice_group_by)]
|
|
#![feature(trusted_random_access)]
|
|
#![deny(unsafe_op_in_unsafe_fn)]
|
|
#![cfg_attr(not(bootstrap), feature(unsize))]
|
|
|
|
extern crate test;
|
|
|
|
mod alloc;
|
|
mod any;
|
|
mod array;
|
|
mod ascii;
|
|
mod atomic;
|
|
mod bool;
|
|
mod cell;
|
|
mod char;
|
|
mod clone;
|
|
mod cmp;
|
|
|
|
#[cfg(not(bootstrap))]
|
|
mod const_ptr;
|
|
|
|
mod fmt;
|
|
mod hash;
|
|
mod intrinsics;
|
|
mod iter;
|
|
mod lazy;
|
|
mod macros;
|
|
mod manually_drop;
|
|
mod mem;
|
|
mod nonzero;
|
|
mod num;
|
|
mod ops;
|
|
mod option;
|
|
mod pattern;
|
|
mod pin;
|
|
mod ptr;
|
|
mod result;
|
|
mod slice;
|
|
mod str;
|
|
mod str_lossy;
|
|
mod task;
|
|
mod time;
|
|
mod tuple;
|
|
mod unicode;
|