Auto merge of #137944 - davidtwco:sized-hierarchy, r=oli-obk
Sized Hierarchy: Part I This patch implements the non-const parts of rust-lang/rfcs#3729. It introduces two new traits to the standard library, `MetaSized` and `PointeeSized`. See the RFC for the rationale behind these traits and to discuss whether this change makes sense in the abstract. These traits are unstable (as is their constness), so users cannot refer to them without opting-in to `feature(sized_hierarchy)`. These traits are not behind `cfg`s as this would make implementation unfeasible, there would simply be too many `cfg`s required to add the necessary bounds everywhere. So, like `Sized`, these traits are automatically implemented by the compiler. RFC 3729 describes changes which are necessary to preserve backwards compatibility given the introduction of these traits, which are implemented and as follows: - `?Sized` is rewritten as `MetaSized` - `MetaSized` is added as a default supertrait for all traits w/out an explicit sizedness supertrait already. There are no edition migrations implemented in this, as these are primarily required for the constness parts of the RFC and prior to stabilisation of this (and so will come in follow-up PRs alongside the const parts). All diagnostic output should remain the same (showing `?Sized` even if the compiler sees `MetaSized`) unless the `sized_hierarchy` feature is enabled. Due to the use of unstable extern types in the standard library and rustc, some bounds in both projects have had to be relaxed already - this is unfortunate but unavoidable so that these extern types can continue to be used where they were before. Performing these relaxations in the standard library and rustc are desirable longer-term anyway, but some bounds are not as relaxed as they ideally would be due to the inability to relax `Deref::Target` (this will be investigated separately). It is hoped that this is implemented such that it could be merged and these traits could exist "under the hood" without that being observable to the user (other than in any performance impact this has on the compiler, etc). Some details might leak through due to the standard library relaxations, but this has not been observed in test output. **Notes:** - Any commits starting with "upstream:" can be ignored, as these correspond to other upstream PRs that this is based on which have yet to be merged. - This best reviewed commit-by-commit. I've attempted to make the implementation easy to follow and keep similar changes and test output updates together. - Each commit has a short description describing its purpose. - This patch is large but it's primarily in the test suite. - I've worked on the performance of this patch and a few optimisations are implemented so that the performance impact is neutral-to-minor. - `PointeeSized` is a different name from the RFC just to make it more obvious that it is different from `std::ptr::Pointee` but all the names are yet to be bikeshed anyway. - `@nikomatsakis` has confirmed [that this can proceed as an experiment from the t-lang side](https://rust-lang.zulipchat.com/#narrow/channel/435869-project-goals/topic/SVE.20and.20SME.20on.20AArch64.20.28goals.23270.29/near/506196491) - FCP in https://github.com/rust-lang/rust/pull/137944#issuecomment-2912207485 Fixes rust-lang/rust#79409. r? `@ghost` (I'll discuss this with relevant teams to find a reviewer)
This commit is contained in:
@@ -36,6 +36,8 @@
|
||||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
use crate::marker::PointeeSized;
|
||||
|
||||
mod uninit;
|
||||
|
||||
/// A common trait that allows explicit creation of a duplicate value.
|
||||
@@ -283,7 +285,7 @@ impl_use_cloned! {
|
||||
reason = "deriving hack, should not be public",
|
||||
issue = "none"
|
||||
)]
|
||||
pub struct AssertParamIsClone<T: Clone + ?Sized> {
|
||||
pub struct AssertParamIsClone<T: Clone + PointeeSized> {
|
||||
_field: crate::marker::PhantomData<T>,
|
||||
}
|
||||
#[doc(hidden)]
|
||||
@@ -293,7 +295,7 @@ pub struct AssertParamIsClone<T: Clone + ?Sized> {
|
||||
reason = "deriving hack, should not be public",
|
||||
issue = "none"
|
||||
)]
|
||||
pub struct AssertParamIsCopy<T: Copy + ?Sized> {
|
||||
pub struct AssertParamIsCopy<T: Copy + PointeeSized> {
|
||||
_field: crate::marker::PhantomData<T>,
|
||||
}
|
||||
|
||||
@@ -530,6 +532,8 @@ unsafe impl CloneToUninit for crate::bstr::ByteStr {
|
||||
/// are implemented in `traits::SelectionContext::copy_clone_conditions()`
|
||||
/// in `rustc_trait_selection`.
|
||||
mod impls {
|
||||
use crate::marker::PointeeSized;
|
||||
|
||||
macro_rules! impl_clone {
|
||||
($($t:ty)*) => {
|
||||
$(
|
||||
@@ -560,7 +564,7 @@ mod impls {
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Clone for *const T {
|
||||
impl<T: PointeeSized> Clone for *const T {
|
||||
#[inline(always)]
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
@@ -568,7 +572,7 @@ mod impls {
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Clone for *mut T {
|
||||
impl<T: PointeeSized> Clone for *mut T {
|
||||
#[inline(always)]
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
@@ -577,7 +581,7 @@ mod impls {
|
||||
|
||||
/// Shared references can be cloned, but mutable references *cannot*!
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Clone for &T {
|
||||
impl<T: PointeeSized> Clone for &T {
|
||||
#[inline(always)]
|
||||
#[rustc_diagnostic_item = "noop_method_clone"]
|
||||
fn clone(&self) -> Self {
|
||||
@@ -587,5 +591,5 @@ mod impls {
|
||||
|
||||
/// Shared references can be cloned, but mutable references *cannot*!
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> !Clone for &mut T {}
|
||||
impl<T: PointeeSized> !Clone for &mut T {}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ mod bytewise;
|
||||
pub(crate) use bytewise::BytewiseEq;
|
||||
|
||||
use self::Ordering::*;
|
||||
use crate::marker::PointeeSized;
|
||||
use crate::ops::ControlFlow;
|
||||
|
||||
/// Trait for comparisons using the equality operator.
|
||||
@@ -246,7 +247,7 @@ use crate::ops::ControlFlow;
|
||||
append_const_msg
|
||||
)]
|
||||
#[rustc_diagnostic_item = "PartialEq"]
|
||||
pub trait PartialEq<Rhs: ?Sized = Self> {
|
||||
pub trait PartialEq<Rhs: PointeeSized = Self>: PointeeSized {
|
||||
/// Tests for `self` and `other` values to be equal, and is used by `==`.
|
||||
#[must_use]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
@@ -332,7 +333,7 @@ pub macro PartialEq($item:item) {
|
||||
#[doc(alias = "!=")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_diagnostic_item = "Eq"]
|
||||
pub trait Eq: PartialEq<Self> {
|
||||
pub trait Eq: PartialEq<Self> + PointeeSized {
|
||||
// this method is used solely by `impl Eq or #[derive(Eq)]` to assert that every component of a
|
||||
// type implements `Eq` itself. The current deriving infrastructure means doing this assertion
|
||||
// without using a method on this trait is nearly impossible.
|
||||
@@ -361,7 +362,7 @@ pub macro Eq($item:item) {
|
||||
#[doc(hidden)]
|
||||
#[allow(missing_debug_implementations)]
|
||||
#[unstable(feature = "derive_eq", reason = "deriving hack, should not be public", issue = "none")]
|
||||
pub struct AssertParamIsEq<T: Eq + ?Sized> {
|
||||
pub struct AssertParamIsEq<T: Eq + PointeeSized> {
|
||||
_field: crate::marker::PhantomData<T>,
|
||||
}
|
||||
|
||||
@@ -954,7 +955,7 @@ impl<T: Clone> Clone for Reverse<T> {
|
||||
#[doc(alias = ">=")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_diagnostic_item = "Ord"]
|
||||
pub trait Ord: Eq + PartialOrd<Self> {
|
||||
pub trait Ord: Eq + PartialOrd<Self> + PointeeSized {
|
||||
/// This method returns an [`Ordering`] between `self` and `other`.
|
||||
///
|
||||
/// By convention, `self.cmp(&other)` returns the ordering matching the expression
|
||||
@@ -1337,7 +1338,8 @@ pub macro Ord($item:item) {
|
||||
append_const_msg
|
||||
)]
|
||||
#[rustc_diagnostic_item = "PartialOrd"]
|
||||
pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
|
||||
#[allow(multiple_supertrait_upcastable)] // FIXME(sized_hierarchy): remove this
|
||||
pub trait PartialOrd<Rhs: PointeeSized = Self>: PartialEq<Rhs> + PointeeSized {
|
||||
/// This method returns an ordering between `self` and `other` values if one exists.
|
||||
///
|
||||
/// # Examples
|
||||
@@ -1481,7 +1483,7 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
|
||||
}
|
||||
}
|
||||
|
||||
fn default_chaining_impl<T: ?Sized, U: ?Sized>(
|
||||
fn default_chaining_impl<T: PointeeSized, U: PointeeSized>(
|
||||
lhs: &T,
|
||||
rhs: &U,
|
||||
p: impl FnOnce(Ordering) -> bool,
|
||||
@@ -1803,6 +1805,7 @@ where
|
||||
mod impls {
|
||||
use crate::cmp::Ordering::{self, Equal, Greater, Less};
|
||||
use crate::hint::unreachable_unchecked;
|
||||
use crate::marker::PointeeSized;
|
||||
use crate::ops::ControlFlow::{self, Break, Continue};
|
||||
|
||||
macro_rules! partial_eq_impl {
|
||||
@@ -2015,7 +2018,7 @@ mod impls {
|
||||
// & pointers
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<A: ?Sized, B: ?Sized> PartialEq<&B> for &A
|
||||
impl<A: PointeeSized, B: PointeeSized> PartialEq<&B> for &A
|
||||
where
|
||||
A: PartialEq<B>,
|
||||
{
|
||||
@@ -2029,7 +2032,7 @@ mod impls {
|
||||
}
|
||||
}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<A: ?Sized, B: ?Sized> PartialOrd<&B> for &A
|
||||
impl<A: PointeeSized, B: PointeeSized> PartialOrd<&B> for &A
|
||||
where
|
||||
A: PartialOrd<B>,
|
||||
{
|
||||
@@ -2071,7 +2074,7 @@ mod impls {
|
||||
}
|
||||
}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<A: ?Sized> Ord for &A
|
||||
impl<A: PointeeSized> Ord for &A
|
||||
where
|
||||
A: Ord,
|
||||
{
|
||||
@@ -2081,12 +2084,12 @@ mod impls {
|
||||
}
|
||||
}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<A: ?Sized> Eq for &A where A: Eq {}
|
||||
impl<A: PointeeSized> Eq for &A where A: Eq {}
|
||||
|
||||
// &mut pointers
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<A: ?Sized, B: ?Sized> PartialEq<&mut B> for &mut A
|
||||
impl<A: PointeeSized, B: PointeeSized> PartialEq<&mut B> for &mut A
|
||||
where
|
||||
A: PartialEq<B>,
|
||||
{
|
||||
@@ -2100,7 +2103,7 @@ mod impls {
|
||||
}
|
||||
}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<A: ?Sized, B: ?Sized> PartialOrd<&mut B> for &mut A
|
||||
impl<A: PointeeSized, B: PointeeSized> PartialOrd<&mut B> for &mut A
|
||||
where
|
||||
A: PartialOrd<B>,
|
||||
{
|
||||
@@ -2142,7 +2145,7 @@ mod impls {
|
||||
}
|
||||
}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<A: ?Sized> Ord for &mut A
|
||||
impl<A: PointeeSized> Ord for &mut A
|
||||
where
|
||||
A: Ord,
|
||||
{
|
||||
@@ -2152,10 +2155,10 @@ mod impls {
|
||||
}
|
||||
}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<A: ?Sized> Eq for &mut A where A: Eq {}
|
||||
impl<A: PointeeSized> Eq for &mut A where A: Eq {}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<A: ?Sized, B: ?Sized> PartialEq<&mut B> for &A
|
||||
impl<A: PointeeSized, B: PointeeSized> PartialEq<&mut B> for &A
|
||||
where
|
||||
A: PartialEq<B>,
|
||||
{
|
||||
@@ -2170,7 +2173,7 @@ mod impls {
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<A: ?Sized, B: ?Sized> PartialEq<&B> for &mut A
|
||||
impl<A: PointeeSized, B: PointeeSized> PartialEq<&B> for &mut A
|
||||
where
|
||||
A: PartialEq<B>,
|
||||
{
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
use crate::error::Error;
|
||||
use crate::fmt;
|
||||
use crate::hash::{Hash, Hasher};
|
||||
use crate::marker::PointeeSized;
|
||||
|
||||
mod num;
|
||||
|
||||
@@ -215,7 +216,7 @@ pub const fn identity<T>(x: T) -> T {
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_diagnostic_item = "AsRef"]
|
||||
pub trait AsRef<T: ?Sized> {
|
||||
pub trait AsRef<T: PointeeSized>: PointeeSized {
|
||||
/// Converts this type into a shared reference of the (usually inferred) input type.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn as_ref(&self) -> &T;
|
||||
@@ -366,7 +367,7 @@ pub trait AsRef<T: ?Sized> {
|
||||
/// `&mut Vec<u8>`, for example, is the better choice (callers need to pass the correct type then).
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_diagnostic_item = "AsMut"]
|
||||
pub trait AsMut<T: ?Sized> {
|
||||
pub trait AsMut<T: PointeeSized>: PointeeSized {
|
||||
/// Converts this type into a mutable reference of the (usually inferred) input type.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn as_mut(&mut self) -> &mut T;
|
||||
@@ -701,7 +702,7 @@ pub trait TryFrom<T>: Sized {
|
||||
|
||||
// As lifts over &
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized, U: ?Sized> AsRef<U> for &T
|
||||
impl<T: PointeeSized, U: PointeeSized> AsRef<U> for &T
|
||||
where
|
||||
T: AsRef<U>,
|
||||
{
|
||||
@@ -713,7 +714,7 @@ where
|
||||
|
||||
// As lifts over &mut
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized, U: ?Sized> AsRef<U> for &mut T
|
||||
impl<T: PointeeSized, U: PointeeSized> AsRef<U> for &mut T
|
||||
where
|
||||
T: AsRef<U>,
|
||||
{
|
||||
@@ -733,7 +734,7 @@ where
|
||||
|
||||
// AsMut lifts over &mut
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized, U: ?Sized> AsMut<U> for &mut T
|
||||
impl<T: PointeeSized, U: PointeeSized> AsMut<U> for &mut T
|
||||
where
|
||||
T: AsMut<U>,
|
||||
{
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
use crate::cell::{Cell, Ref, RefCell, RefMut, SyncUnsafeCell, UnsafeCell};
|
||||
use crate::char::{EscapeDebugExtArgs, MAX_LEN_UTF8};
|
||||
use crate::marker::PhantomData;
|
||||
use crate::marker::{PhantomData, PointeeSized};
|
||||
use crate::num::fmt as numfmt;
|
||||
use crate::ops::Deref;
|
||||
use crate::{iter, result, str};
|
||||
@@ -864,7 +864,7 @@ impl Display for Arguments<'_> {
|
||||
#[doc(alias = "{:?}")]
|
||||
#[rustc_diagnostic_item = "Debug"]
|
||||
#[rustc_trivial_field_reads]
|
||||
pub trait Debug {
|
||||
pub trait Debug: PointeeSized {
|
||||
#[doc = include_str!("fmt_trait_method_doc.md")]
|
||||
///
|
||||
/// # Examples
|
||||
@@ -995,7 +995,7 @@ pub use macros::Debug;
|
||||
#[doc(alias = "{}")]
|
||||
#[rustc_diagnostic_item = "Display"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait Display {
|
||||
pub trait Display: PointeeSized {
|
||||
#[doc = include_str!("fmt_trait_method_doc.md")]
|
||||
///
|
||||
/// # Examples
|
||||
@@ -1071,7 +1071,7 @@ pub trait Display {
|
||||
/// assert_eq!(format!("l as octal is: {l:#06o}"), "l as octal is: 0o0011");
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait Octal {
|
||||
pub trait Octal: PointeeSized {
|
||||
#[doc = include_str!("fmt_trait_method_doc.md")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result;
|
||||
@@ -1130,7 +1130,7 @@ pub trait Octal {
|
||||
/// );
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait Binary {
|
||||
pub trait Binary: PointeeSized {
|
||||
#[doc = include_str!("fmt_trait_method_doc.md")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result;
|
||||
@@ -1185,7 +1185,7 @@ pub trait Binary {
|
||||
/// assert_eq!(format!("l as hex is: {l:#010x}"), "l as hex is: 0x00000009");
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait LowerHex {
|
||||
pub trait LowerHex: PointeeSized {
|
||||
#[doc = include_str!("fmt_trait_method_doc.md")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result;
|
||||
@@ -1240,7 +1240,7 @@ pub trait LowerHex {
|
||||
/// assert_eq!(format!("l as hex is: {l:#010X}"), "l as hex is: 0x7FFFFFFF");
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait UpperHex {
|
||||
pub trait UpperHex: PointeeSized {
|
||||
#[doc = include_str!("fmt_trait_method_doc.md")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result;
|
||||
@@ -1299,7 +1299,7 @@ pub trait UpperHex {
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_diagnostic_item = "Pointer"]
|
||||
pub trait Pointer {
|
||||
pub trait Pointer: PointeeSized {
|
||||
#[doc = include_str!("fmt_trait_method_doc.md")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result;
|
||||
@@ -1350,7 +1350,7 @@ pub trait Pointer {
|
||||
/// );
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait LowerExp {
|
||||
pub trait LowerExp: PointeeSized {
|
||||
#[doc = include_str!("fmt_trait_method_doc.md")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result;
|
||||
@@ -1401,7 +1401,7 @@ pub trait LowerExp {
|
||||
/// );
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait UpperExp {
|
||||
pub trait UpperExp: PointeeSized {
|
||||
#[doc = include_str!("fmt_trait_method_doc.md")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result;
|
||||
@@ -2646,11 +2646,11 @@ macro_rules! fmt_refs {
|
||||
($($tr:ident),*) => {
|
||||
$(
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized + $tr> $tr for &T {
|
||||
impl<T: PointeeSized + $tr> $tr for &T {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result { $tr::fmt(&**self, f) }
|
||||
}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized + $tr> $tr for &mut T {
|
||||
impl<T: PointeeSized + $tr> $tr for &mut T {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result { $tr::fmt(&**self, f) }
|
||||
}
|
||||
)*
|
||||
@@ -2772,7 +2772,7 @@ impl Display for char {
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Pointer for *const T {
|
||||
impl<T: PointeeSized> Pointer for *const T {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
||||
if <<T as core::ptr::Pointee>::Metadata as core::unit::IsUnit>::is_unit() {
|
||||
pointer_fmt_inner(self.expose_provenance(), f)
|
||||
@@ -2817,21 +2817,21 @@ pub(crate) fn pointer_fmt_inner(ptr_addr: usize, f: &mut Formatter<'_>) -> Resul
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Pointer for *mut T {
|
||||
impl<T: PointeeSized> Pointer for *mut T {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
||||
Pointer::fmt(&(*self as *const T), f)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Pointer for &T {
|
||||
impl<T: PointeeSized> Pointer for &T {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
||||
Pointer::fmt(&(*self as *const T), f)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Pointer for &mut T {
|
||||
impl<T: PointeeSized> Pointer for &mut T {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
||||
Pointer::fmt(&(&**self as *const T), f)
|
||||
}
|
||||
@@ -2840,13 +2840,13 @@ impl<T: ?Sized> Pointer for &mut T {
|
||||
// Implementation of Display/Debug for various core types
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Debug for *const T {
|
||||
impl<T: PointeeSized> Debug for *const T {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
||||
Pointer::fmt(self, f)
|
||||
}
|
||||
}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Debug for *mut T {
|
||||
impl<T: PointeeSized> Debug for *mut T {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
||||
Pointer::fmt(self, f)
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ mod sip;
|
||||
/// [impl]: ../../std/primitive.str.html#impl-Hash-for-str
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_diagnostic_item = "Hash"]
|
||||
pub trait Hash {
|
||||
pub trait Hash: marker::PointeeSized {
|
||||
/// Feeds this value into the given [`Hasher`].
|
||||
///
|
||||
/// # Examples
|
||||
@@ -941,7 +941,7 @@ mod impls {
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized + Hash> Hash for &T {
|
||||
impl<T: ?Sized + marker::PointeeSized + Hash> Hash for &T {
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
(**self).hash(state);
|
||||
@@ -949,7 +949,7 @@ mod impls {
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized + Hash> Hash for &mut T {
|
||||
impl<T: ?Sized + marker::PointeeSized + Hash> Hash for &mut T {
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
(**self).hash(state);
|
||||
@@ -957,7 +957,7 @@ mod impls {
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Hash for *const T {
|
||||
impl<T: ?Sized + marker::PointeeSized> Hash for *const T {
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
let (address, metadata) = self.to_raw_parts();
|
||||
@@ -967,7 +967,7 @@ mod impls {
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Hash for *mut T {
|
||||
impl<T: ?Sized + marker::PointeeSized> Hash for *mut T {
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
let (address, metadata) = self.to_raw_parts();
|
||||
|
||||
@@ -1,39 +1,41 @@
|
||||
//! Various traits used to restrict intrinsics to not-completely-wrong types.
|
||||
|
||||
use crate::marker::PointeeSized;
|
||||
|
||||
/// Types with a built-in dereference operator in runtime MIR,
|
||||
/// aka references and raw pointers.
|
||||
///
|
||||
/// # Safety
|
||||
/// Must actually *be* such a type.
|
||||
pub unsafe trait BuiltinDeref: Sized {
|
||||
type Pointee: ?Sized;
|
||||
type Pointee: PointeeSized;
|
||||
}
|
||||
|
||||
unsafe impl<T: ?Sized> BuiltinDeref for &mut T {
|
||||
unsafe impl<T: PointeeSized> BuiltinDeref for &mut T {
|
||||
type Pointee = T;
|
||||
}
|
||||
unsafe impl<T: ?Sized> BuiltinDeref for &T {
|
||||
unsafe impl<T: PointeeSized> BuiltinDeref for &T {
|
||||
type Pointee = T;
|
||||
}
|
||||
unsafe impl<T: ?Sized> BuiltinDeref for *mut T {
|
||||
unsafe impl<T: PointeeSized> BuiltinDeref for *mut T {
|
||||
type Pointee = T;
|
||||
}
|
||||
unsafe impl<T: ?Sized> BuiltinDeref for *const T {
|
||||
unsafe impl<T: PointeeSized> BuiltinDeref for *const T {
|
||||
type Pointee = T;
|
||||
}
|
||||
|
||||
pub trait ChangePointee<U: ?Sized>: BuiltinDeref {
|
||||
pub trait ChangePointee<U: PointeeSized>: BuiltinDeref {
|
||||
type Output;
|
||||
}
|
||||
impl<'a, T: ?Sized + 'a, U: ?Sized + 'a> ChangePointee<U> for &'a mut T {
|
||||
impl<'a, T: PointeeSized + 'a, U: PointeeSized + 'a> ChangePointee<U> for &'a mut T {
|
||||
type Output = &'a mut U;
|
||||
}
|
||||
impl<'a, T: ?Sized + 'a, U: ?Sized + 'a> ChangePointee<U> for &'a T {
|
||||
impl<'a, T: PointeeSized + 'a, U: PointeeSized + 'a> ChangePointee<U> for &'a T {
|
||||
type Output = &'a U;
|
||||
}
|
||||
impl<T: ?Sized, U: ?Sized> ChangePointee<U> for *mut T {
|
||||
impl<T: PointeeSized, U: PointeeSized> ChangePointee<U> for *mut T {
|
||||
type Output = *mut U;
|
||||
}
|
||||
impl<T: ?Sized, U: ?Sized> ChangePointee<U> for *const T {
|
||||
impl<T: PointeeSized, U: PointeeSized> ChangePointee<U> for *const T {
|
||||
type Output = *const U;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
)]
|
||||
#![allow(missing_docs)]
|
||||
|
||||
use crate::marker::{ConstParamTy, DiscriminantKind, Tuple};
|
||||
use crate::marker::{ConstParamTy, DiscriminantKind, PointeeSized, Tuple};
|
||||
use crate::ptr;
|
||||
|
||||
mod bounds;
|
||||
@@ -2740,7 +2740,7 @@ where
|
||||
#[unstable(feature = "core_intrinsics", issue = "none")]
|
||||
#[rustc_intrinsic_const_stable_indirect]
|
||||
#[rustc_intrinsic]
|
||||
pub const fn ptr_metadata<P: ptr::Pointee<Metadata = M> + ?Sized, M>(ptr: *const P) -> M;
|
||||
pub const fn ptr_metadata<P: ptr::Pointee<Metadata = M> + PointeeSized, M>(ptr: *const P) -> M;
|
||||
|
||||
/// This is an accidentally-stable alias to [`ptr::copy_nonoverlapping`]; use that instead.
|
||||
// Note (intentionally not in the doc comment): `ptr::copy_nonoverlapping` adds some extra
|
||||
|
||||
@@ -93,15 +93,15 @@ pub unsafe auto trait Send {
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> !Send for *const T {}
|
||||
impl<T: PointeeSized> !Send for *const T {}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> !Send for *mut T {}
|
||||
impl<T: PointeeSized> !Send for *mut T {}
|
||||
|
||||
// Most instances arise automatically, but this instance is needed to link up `T: Sync` with
|
||||
// `&T: Send` (and it also removes the unsound default instance `T Send` -> `&T: Send` that would
|
||||
// otherwise exist).
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
unsafe impl<T: Sync + ?Sized> Send for &T {}
|
||||
unsafe impl<T: Sync + PointeeSized> Send for &T {}
|
||||
|
||||
/// Types with a constant size known at compile time.
|
||||
///
|
||||
@@ -151,11 +151,48 @@ unsafe impl<T: Sync + ?Sized> Send for &T {}
|
||||
#[rustc_specialization_trait]
|
||||
#[rustc_deny_explicit_impl]
|
||||
#[rustc_do_not_implement_via_object]
|
||||
// `Sized` being coinductive, despite having supertraits, is okay as there are no user-written impls,
|
||||
// and we know that the supertraits are always implemented if the subtrait is just by looking at
|
||||
// the builtin impls.
|
||||
#[rustc_coinductive]
|
||||
pub trait Sized {
|
||||
pub trait Sized: MetaSized {
|
||||
// Empty.
|
||||
}
|
||||
|
||||
/// Types with a size that can be determined from pointer metadata.
|
||||
#[unstable(feature = "sized_hierarchy", issue = "none")]
|
||||
#[lang = "meta_sized"]
|
||||
#[diagnostic::on_unimplemented(
|
||||
message = "the size for values of type `{Self}` cannot be known",
|
||||
label = "doesn't have a known size"
|
||||
)]
|
||||
#[fundamental]
|
||||
#[rustc_specialization_trait]
|
||||
#[rustc_deny_explicit_impl]
|
||||
#[rustc_do_not_implement_via_object]
|
||||
// `MetaSized` being coinductive, despite having supertraits, is okay for the same reasons as
|
||||
// `Sized` above.
|
||||
#[rustc_coinductive]
|
||||
pub trait MetaSized: PointeeSized {
|
||||
// Empty
|
||||
}
|
||||
|
||||
/// Types that may or may not have a size.
|
||||
#[unstable(feature = "sized_hierarchy", issue = "none")]
|
||||
#[lang = "pointee_sized"]
|
||||
#[diagnostic::on_unimplemented(
|
||||
message = "values of type `{Self}` may or may not have a size",
|
||||
label = "may or may not have a known size"
|
||||
)]
|
||||
#[fundamental]
|
||||
#[rustc_specialization_trait]
|
||||
#[rustc_deny_explicit_impl]
|
||||
#[rustc_do_not_implement_via_object]
|
||||
#[rustc_coinductive]
|
||||
pub trait PointeeSized {
|
||||
// Empty
|
||||
}
|
||||
|
||||
/// Types that can be "unsized" to a dynamically-sized type.
|
||||
///
|
||||
/// For example, the sized array type `[i8; 2]` implements `Unsize<[i8]>` and
|
||||
@@ -192,7 +229,7 @@ pub trait Sized {
|
||||
#[lang = "unsize"]
|
||||
#[rustc_deny_explicit_impl]
|
||||
#[rustc_do_not_implement_via_object]
|
||||
pub trait Unsize<T: ?Sized> {
|
||||
pub trait Unsize<T: PointeeSized>: PointeeSized {
|
||||
// Empty.
|
||||
}
|
||||
|
||||
@@ -229,7 +266,7 @@ marker_impls! {
|
||||
(),
|
||||
{T, const N: usize} [T; N],
|
||||
{T} [T],
|
||||
{T: ?Sized} &T,
|
||||
{T: PointeeSized} &T,
|
||||
}
|
||||
|
||||
/// Types whose values can be duplicated simply by copying bits.
|
||||
@@ -442,8 +479,8 @@ marker_impls! {
|
||||
isize, i8, i16, i32, i64, i128,
|
||||
f16, f32, f64, f128,
|
||||
bool, char,
|
||||
{T: ?Sized} *const T,
|
||||
{T: ?Sized} *mut T,
|
||||
{T: PointeeSized} *const T,
|
||||
{T: PointeeSized} *mut T,
|
||||
|
||||
}
|
||||
|
||||
@@ -452,7 +489,7 @@ impl Copy for ! {}
|
||||
|
||||
/// Shared references can be copied, but mutable references *cannot*!
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Copy for &T {}
|
||||
impl<T: PointeeSized> Copy for &T {}
|
||||
|
||||
/// Marker trait for the types that are allowed in union fields and unsafe
|
||||
/// binder types.
|
||||
@@ -636,9 +673,9 @@ pub unsafe auto trait Sync {
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> !Sync for *const T {}
|
||||
impl<T: PointeeSized> !Sync for *const T {}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> !Sync for *mut T {}
|
||||
impl<T: PointeeSized> !Sync for *mut T {}
|
||||
|
||||
/// Zero-sized type used to mark things that "act like" they own a `T`.
|
||||
///
|
||||
@@ -775,57 +812,57 @@ impl<T: ?Sized> !Sync for *mut T {}
|
||||
/// [drop check]: Drop#drop-check
|
||||
#[lang = "phantom_data"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct PhantomData<T: ?Sized>;
|
||||
pub struct PhantomData<T: PointeeSized>;
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Hash for PhantomData<T> {
|
||||
impl<T: PointeeSized> Hash for PhantomData<T> {
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&self, _: &mut H) {}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> cmp::PartialEq for PhantomData<T> {
|
||||
impl<T: PointeeSized> cmp::PartialEq for PhantomData<T> {
|
||||
fn eq(&self, _other: &PhantomData<T>) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> cmp::Eq for PhantomData<T> {}
|
||||
impl<T: PointeeSized> cmp::Eq for PhantomData<T> {}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> cmp::PartialOrd for PhantomData<T> {
|
||||
impl<T: PointeeSized> cmp::PartialOrd for PhantomData<T> {
|
||||
fn partial_cmp(&self, _other: &PhantomData<T>) -> Option<cmp::Ordering> {
|
||||
Option::Some(cmp::Ordering::Equal)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> cmp::Ord for PhantomData<T> {
|
||||
impl<T: PointeeSized> cmp::Ord for PhantomData<T> {
|
||||
fn cmp(&self, _other: &PhantomData<T>) -> cmp::Ordering {
|
||||
cmp::Ordering::Equal
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Copy for PhantomData<T> {}
|
||||
impl<T: PointeeSized> Copy for PhantomData<T> {}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Clone for PhantomData<T> {
|
||||
impl<T: PointeeSized> Clone for PhantomData<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Default for PhantomData<T> {
|
||||
impl<T: PointeeSized> Default for PhantomData<T> {
|
||||
fn default() -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "structural_match", issue = "31434")]
|
||||
impl<T: ?Sized> StructuralPartialEq for PhantomData<T> {}
|
||||
impl<T: PointeeSized> StructuralPartialEq for PhantomData<T> {}
|
||||
|
||||
/// Compiler-internal trait used to indicate the type of enum discriminants.
|
||||
///
|
||||
@@ -868,15 +905,15 @@ pub trait DiscriminantKind {
|
||||
pub unsafe auto trait Freeze {}
|
||||
|
||||
#[unstable(feature = "freeze", issue = "121675")]
|
||||
impl<T: ?Sized> !Freeze for UnsafeCell<T> {}
|
||||
impl<T: PointeeSized> !Freeze for UnsafeCell<T> {}
|
||||
marker_impls! {
|
||||
#[unstable(feature = "freeze", issue = "121675")]
|
||||
unsafe Freeze for
|
||||
{T: ?Sized} PhantomData<T>,
|
||||
{T: ?Sized} *const T,
|
||||
{T: ?Sized} *mut T,
|
||||
{T: ?Sized} &T,
|
||||
{T: ?Sized} &mut T,
|
||||
{T: PointeeSized} PhantomData<T>,
|
||||
{T: PointeeSized} *const T,
|
||||
{T: PointeeSized} *mut T,
|
||||
{T: PointeeSized} &T,
|
||||
{T: PointeeSized} &mut T,
|
||||
}
|
||||
|
||||
/// Used to determine whether a type contains any `UnsafePinned` (or `PhantomPinned`) internally,
|
||||
@@ -991,15 +1028,15 @@ impl !UnsafeUnpin for PhantomPinned {}
|
||||
marker_impls! {
|
||||
#[stable(feature = "pin", since = "1.33.0")]
|
||||
Unpin for
|
||||
{T: ?Sized} &T,
|
||||
{T: ?Sized} &mut T,
|
||||
{T: PointeeSized} &T,
|
||||
{T: PointeeSized} &mut T,
|
||||
}
|
||||
|
||||
marker_impls! {
|
||||
#[stable(feature = "pin_raw", since = "1.38.0")]
|
||||
Unpin for
|
||||
{T: ?Sized} *const T,
|
||||
{T: ?Sized} *mut T,
|
||||
{T: PointeeSized} *const T,
|
||||
{T: PointeeSized} *mut T,
|
||||
}
|
||||
|
||||
/// A marker for types that can be dropped.
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use crate::marker::PointeeSized;
|
||||
|
||||
/// Used for immutable dereferencing operations, like `*v`.
|
||||
///
|
||||
/// In addition to being used for explicit dereferencing operations with the
|
||||
@@ -135,7 +137,7 @@
|
||||
#[rustc_diagnostic_item = "Deref"]
|
||||
#[const_trait]
|
||||
#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
|
||||
pub trait Deref {
|
||||
pub trait Deref: PointeeSized {
|
||||
/// The resulting type after dereferencing.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_diagnostic_item = "deref_target"]
|
||||
@@ -267,7 +269,7 @@ impl<T: ?Sized> const Deref for &mut T {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[const_trait]
|
||||
#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
|
||||
pub trait DerefMut: ~const Deref {
|
||||
pub trait DerefMut: ~const Deref + PointeeSized {
|
||||
/// Mutably dereferences the value.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_diagnostic_item = "deref_mut_method"]
|
||||
@@ -293,7 +295,7 @@ impl<T: ?Sized> const DerefMut for &mut T {
|
||||
/// unchanged.
|
||||
#[unstable(feature = "deref_pure_trait", issue = "87121")]
|
||||
#[lang = "deref_pure"]
|
||||
pub unsafe trait DerefPure {}
|
||||
pub unsafe trait DerefPure: PointeeSized {}
|
||||
|
||||
#[unstable(feature = "deref_pure_trait", issue = "87121")]
|
||||
unsafe impl<T: ?Sized> DerefPure for &T {}
|
||||
@@ -366,7 +368,7 @@ unsafe impl<T: ?Sized> DerefPure for &mut T {}
|
||||
/// ```
|
||||
#[lang = "receiver"]
|
||||
#[unstable(feature = "arbitrary_self_types", issue = "44874")]
|
||||
pub trait Receiver {
|
||||
pub trait Receiver: PointeeSized {
|
||||
/// The target type on which the method may be called.
|
||||
#[rustc_diagnostic_item = "receiver_target"]
|
||||
#[lang = "receiver_target"]
|
||||
@@ -393,12 +395,12 @@ where
|
||||
#[lang = "legacy_receiver"]
|
||||
#[unstable(feature = "legacy_receiver_trait", issue = "none")]
|
||||
#[doc(hidden)]
|
||||
pub trait LegacyReceiver {
|
||||
pub trait LegacyReceiver: PointeeSized {
|
||||
// Empty.
|
||||
}
|
||||
|
||||
#[unstable(feature = "legacy_receiver_trait", issue = "none")]
|
||||
impl<T: ?Sized> LegacyReceiver for &T {}
|
||||
impl<T: PointeeSized> LegacyReceiver for &T {}
|
||||
|
||||
#[unstable(feature = "legacy_receiver_trait", issue = "none")]
|
||||
impl<T: ?Sized> LegacyReceiver for &mut T {}
|
||||
impl<T: PointeeSized> LegacyReceiver for &mut T {}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::marker::Unsize;
|
||||
use crate::marker::{PointeeSized, Unsize};
|
||||
|
||||
/// Trait that indicates that this is a pointer or a wrapper for one,
|
||||
/// where unsizing can be performed on the pointee.
|
||||
@@ -33,40 +33,40 @@ use crate::marker::Unsize;
|
||||
/// [nomicon-coerce]: ../../nomicon/coercions.html
|
||||
#[unstable(feature = "coerce_unsized", issue = "18598")]
|
||||
#[lang = "coerce_unsized"]
|
||||
pub trait CoerceUnsized<T: ?Sized> {
|
||||
pub trait CoerceUnsized<T: PointeeSized> {
|
||||
// Empty.
|
||||
}
|
||||
|
||||
// &mut T -> &mut U
|
||||
#[unstable(feature = "coerce_unsized", issue = "18598")]
|
||||
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {}
|
||||
impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a mut U> for &'a mut T {}
|
||||
// &mut T -> &U
|
||||
#[unstable(feature = "coerce_unsized", issue = "18598")]
|
||||
impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {}
|
||||
impl<'a, 'b: 'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a U> for &'b mut T {}
|
||||
// &mut T -> *mut U
|
||||
#[unstable(feature = "coerce_unsized", issue = "18598")]
|
||||
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {}
|
||||
impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*mut U> for &'a mut T {}
|
||||
// &mut T -> *const U
|
||||
#[unstable(feature = "coerce_unsized", issue = "18598")]
|
||||
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {}
|
||||
impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for &'a mut T {}
|
||||
|
||||
// &T -> &U
|
||||
#[unstable(feature = "coerce_unsized", issue = "18598")]
|
||||
impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
|
||||
impl<'a, 'b: 'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<&'a U> for &'b T {}
|
||||
// &T -> *const U
|
||||
#[unstable(feature = "coerce_unsized", issue = "18598")]
|
||||
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a T {}
|
||||
impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for &'a T {}
|
||||
|
||||
// *mut T -> *mut U
|
||||
#[unstable(feature = "coerce_unsized", issue = "18598")]
|
||||
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
|
||||
impl<T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*mut U> for *mut T {}
|
||||
// *mut T -> *const U
|
||||
#[unstable(feature = "coerce_unsized", issue = "18598")]
|
||||
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {}
|
||||
impl<T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for *mut T {}
|
||||
|
||||
// *const T -> *const U
|
||||
#[unstable(feature = "coerce_unsized", issue = "18598")]
|
||||
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
|
||||
impl<T: PointeeSized + Unsize<U>, U: PointeeSized> CoerceUnsized<*const U> for *const T {}
|
||||
|
||||
/// `DispatchFromDyn` is used in the implementation of dyn-compatibility[^1] checks (specifically
|
||||
/// allowing arbitrary self types), to guarantee that a method's receiver type can be dispatched on.
|
||||
@@ -122,13 +122,13 @@ pub trait DispatchFromDyn<T> {
|
||||
|
||||
// &T -> &U
|
||||
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
|
||||
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {}
|
||||
impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<&'a U> for &'a T {}
|
||||
// &mut T -> &mut U
|
||||
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
|
||||
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {}
|
||||
impl<'a, T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<&'a mut U> for &'a mut T {}
|
||||
// *const T -> *const U
|
||||
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
|
||||
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*const U> for *const T {}
|
||||
impl<T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<*const U> for *const T {}
|
||||
// *mut T -> *mut U
|
||||
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
|
||||
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {}
|
||||
impl<T: PointeeSized + Unsize<U>, U: PointeeSized> DispatchFromDyn<*mut U> for *mut T {}
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::intrinsics::const_eval_select;
|
||||
use crate::mem::{self, SizedTypeProperties};
|
||||
use crate::slice::{self, SliceIndex};
|
||||
|
||||
impl<T: ?Sized> *const T {
|
||||
impl<T: PointeeSized> *const T {
|
||||
#[doc = include_str!("docs/is_null.md")]
|
||||
///
|
||||
/// # Examples
|
||||
@@ -129,7 +129,7 @@ impl<T: ?Sized> *const T {
|
||||
#[inline]
|
||||
pub const fn with_metadata_of<U>(self, meta: *const U) -> *const U
|
||||
where
|
||||
U: ?Sized,
|
||||
U: PointeeSized,
|
||||
{
|
||||
from_raw_parts::<U>(self as *const (), metadata(meta))
|
||||
}
|
||||
@@ -1586,7 +1586,7 @@ impl<T, const N: usize> *const [T; N] {
|
||||
|
||||
/// Pointer equality is by address, as produced by the [`<*const T>::addr`](pointer::addr) method.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> PartialEq for *const T {
|
||||
impl<T: PointeeSized> PartialEq for *const T {
|
||||
#[inline]
|
||||
#[allow(ambiguous_wide_pointer_comparisons)]
|
||||
fn eq(&self, other: &*const T) -> bool {
|
||||
@@ -1596,11 +1596,11 @@ impl<T: ?Sized> PartialEq for *const T {
|
||||
|
||||
/// Pointer equality is an equivalence relation.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Eq for *const T {}
|
||||
impl<T: PointeeSized> Eq for *const T {}
|
||||
|
||||
/// Pointer comparison is by address, as produced by the `[`<*const T>::addr`](pointer::addr)` method.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Ord for *const T {
|
||||
impl<T: PointeeSized> Ord for *const T {
|
||||
#[inline]
|
||||
#[allow(ambiguous_wide_pointer_comparisons)]
|
||||
fn cmp(&self, other: &*const T) -> Ordering {
|
||||
@@ -1616,7 +1616,7 @@ impl<T: ?Sized> Ord for *const T {
|
||||
|
||||
/// Pointer comparison is by address, as produced by the `[`<*const T>::addr`](pointer::addr)` method.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> PartialOrd for *const T {
|
||||
impl<T: PointeeSized> PartialOrd for *const T {
|
||||
#[inline]
|
||||
#[allow(ambiguous_wide_pointer_comparisons)]
|
||||
fn partial_cmp(&self, other: &*const T) -> Option<Ordering> {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
use crate::fmt;
|
||||
use crate::hash::{Hash, Hasher};
|
||||
use crate::intrinsics::{aggregate_raw_ptr, ptr_metadata};
|
||||
use crate::marker::Freeze;
|
||||
use crate::marker::{Freeze, PointeeSized};
|
||||
use crate::ptr::NonNull;
|
||||
|
||||
/// Provides the pointer metadata type of any pointed-to type.
|
||||
@@ -55,7 +55,7 @@ use crate::ptr::NonNull;
|
||||
#[lang = "pointee_trait"]
|
||||
#[rustc_deny_explicit_impl]
|
||||
#[rustc_do_not_implement_via_object]
|
||||
pub trait Pointee {
|
||||
pub trait Pointee: PointeeSized {
|
||||
/// The type for metadata in pointers and references to `Self`.
|
||||
#[lang = "metadata_type"]
|
||||
// NOTE: Keep trait bounds in `static_assert_expected_bounds_for_metadata`
|
||||
@@ -81,7 +81,7 @@ pub trait Pointee {
|
||||
/// ```
|
||||
#[unstable(feature = "ptr_metadata", issue = "81513")]
|
||||
// NOTE: don’t stabilize this before trait aliases are stable in the language?
|
||||
pub trait Thin = Pointee<Metadata = ()>;
|
||||
pub trait Thin = Pointee<Metadata = ()> + PointeeSized;
|
||||
|
||||
/// Extracts the metadata component of a pointer.
|
||||
///
|
||||
@@ -96,7 +96,7 @@ pub trait Thin = Pointee<Metadata = ()>;
|
||||
/// assert_eq!(std::ptr::metadata("foo"), 3_usize);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub const fn metadata<T: ?Sized>(ptr: *const T) -> <T as Pointee>::Metadata {
|
||||
pub const fn metadata<T: PointeeSized>(ptr: *const T) -> <T as Pointee>::Metadata {
|
||||
ptr_metadata(ptr)
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ pub const fn metadata<T: ?Sized>(ptr: *const T) -> <T as Pointee>::Metadata {
|
||||
/// [`slice::from_raw_parts`]: crate::slice::from_raw_parts
|
||||
#[unstable(feature = "ptr_metadata", issue = "81513")]
|
||||
#[inline]
|
||||
pub const fn from_raw_parts<T: ?Sized>(
|
||||
pub const fn from_raw_parts<T: PointeeSized>(
|
||||
data_pointer: *const impl Thin,
|
||||
metadata: <T as Pointee>::Metadata,
|
||||
) -> *const T {
|
||||
@@ -122,7 +122,7 @@ pub const fn from_raw_parts<T: ?Sized>(
|
||||
/// See the documentation of [`from_raw_parts`] for more details.
|
||||
#[unstable(feature = "ptr_metadata", issue = "81513")]
|
||||
#[inline]
|
||||
pub const fn from_raw_parts_mut<T: ?Sized>(
|
||||
pub const fn from_raw_parts_mut<T: PointeeSized>(
|
||||
data_pointer: *mut impl Thin,
|
||||
metadata: <T as Pointee>::Metadata,
|
||||
) -> *mut T {
|
||||
@@ -152,7 +152,7 @@ pub const fn from_raw_parts_mut<T: ?Sized>(
|
||||
/// duplicated in multiple codegen units), and pointers to vtables of *different* types/traits can
|
||||
/// compare equal (since identical vtables can be deduplicated within a codegen unit).
|
||||
#[lang = "dyn_metadata"]
|
||||
pub struct DynMetadata<Dyn: ?Sized> {
|
||||
pub struct DynMetadata<Dyn: PointeeSized> {
|
||||
_vtable_ptr: NonNull<VTable>,
|
||||
_phantom: crate::marker::PhantomData<Dyn>,
|
||||
}
|
||||
@@ -165,7 +165,7 @@ unsafe extern "C" {
|
||||
type VTable;
|
||||
}
|
||||
|
||||
impl<Dyn: ?Sized> DynMetadata<Dyn> {
|
||||
impl<Dyn: PointeeSized> DynMetadata<Dyn> {
|
||||
/// When `DynMetadata` appears as the metadata field of a wide pointer, the rustc_middle layout
|
||||
/// computation does magic and the resulting layout is *not* a `FieldsShape::Aggregate`, instead
|
||||
/// it is a `FieldsShape::Primitive`. This means that the same type can have different layout
|
||||
@@ -206,10 +206,10 @@ impl<Dyn: ?Sized> DynMetadata<Dyn> {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<Dyn: ?Sized> Send for DynMetadata<Dyn> {}
|
||||
unsafe impl<Dyn: ?Sized> Sync for DynMetadata<Dyn> {}
|
||||
unsafe impl<Dyn: PointeeSized> Send for DynMetadata<Dyn> {}
|
||||
unsafe impl<Dyn: PointeeSized> Sync for DynMetadata<Dyn> {}
|
||||
|
||||
impl<Dyn: ?Sized> fmt::Debug for DynMetadata<Dyn> {
|
||||
impl<Dyn: PointeeSized> fmt::Debug for DynMetadata<Dyn> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_tuple("DynMetadata").field(&self.vtable_ptr()).finish()
|
||||
}
|
||||
@@ -217,27 +217,27 @@ impl<Dyn: ?Sized> fmt::Debug for DynMetadata<Dyn> {
|
||||
|
||||
// Manual impls needed to avoid `Dyn: $Trait` bounds.
|
||||
|
||||
impl<Dyn: ?Sized> Unpin for DynMetadata<Dyn> {}
|
||||
impl<Dyn: PointeeSized> Unpin for DynMetadata<Dyn> {}
|
||||
|
||||
impl<Dyn: ?Sized> Copy for DynMetadata<Dyn> {}
|
||||
impl<Dyn: PointeeSized> Copy for DynMetadata<Dyn> {}
|
||||
|
||||
impl<Dyn: ?Sized> Clone for DynMetadata<Dyn> {
|
||||
impl<Dyn: PointeeSized> Clone for DynMetadata<Dyn> {
|
||||
#[inline]
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl<Dyn: ?Sized> Eq for DynMetadata<Dyn> {}
|
||||
impl<Dyn: PointeeSized> Eq for DynMetadata<Dyn> {}
|
||||
|
||||
impl<Dyn: ?Sized> PartialEq for DynMetadata<Dyn> {
|
||||
impl<Dyn: PointeeSized> PartialEq for DynMetadata<Dyn> {
|
||||
#[inline]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
crate::ptr::eq::<VTable>(self.vtable_ptr(), other.vtable_ptr())
|
||||
}
|
||||
}
|
||||
|
||||
impl<Dyn: ?Sized> Ord for DynMetadata<Dyn> {
|
||||
impl<Dyn: PointeeSized> Ord for DynMetadata<Dyn> {
|
||||
#[inline]
|
||||
#[allow(ambiguous_wide_pointer_comparisons)]
|
||||
fn cmp(&self, other: &Self) -> crate::cmp::Ordering {
|
||||
@@ -245,14 +245,14 @@ impl<Dyn: ?Sized> Ord for DynMetadata<Dyn> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<Dyn: ?Sized> PartialOrd for DynMetadata<Dyn> {
|
||||
impl<Dyn: PointeeSized> PartialOrd for DynMetadata<Dyn> {
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &Self) -> Option<crate::cmp::Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl<Dyn: ?Sized> Hash for DynMetadata<Dyn> {
|
||||
impl<Dyn: PointeeSized> Hash for DynMetadata<Dyn> {
|
||||
#[inline]
|
||||
fn hash<H: Hasher>(&self, hasher: &mut H) {
|
||||
crate::ptr::hash::<VTable, _>(self.vtable_ptr(), hasher)
|
||||
|
||||
@@ -398,7 +398,7 @@
|
||||
|
||||
use crate::cmp::Ordering;
|
||||
use crate::intrinsics::const_eval_select;
|
||||
use crate::marker::FnPtr;
|
||||
use crate::marker::{FnPtr, PointeeSized};
|
||||
use crate::mem::{self, MaybeUninit, SizedTypeProperties};
|
||||
use crate::num::NonZero;
|
||||
use crate::{fmt, hash, intrinsics, ub_checks};
|
||||
@@ -796,7 +796,7 @@ pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
|
||||
#[lang = "drop_in_place"]
|
||||
#[allow(unconditional_recursion)]
|
||||
#[rustc_diagnostic_item = "ptr_drop_in_place"]
|
||||
pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
|
||||
pub unsafe fn drop_in_place<T: PointeeSized>(to_drop: *mut T) {
|
||||
// Code here does not matter - this is replaced by the
|
||||
// real drop glue by the compiler.
|
||||
|
||||
@@ -825,7 +825,7 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
|
||||
#[rustc_promotable]
|
||||
#[rustc_const_stable(feature = "const_ptr_null", since = "1.24.0")]
|
||||
#[rustc_diagnostic_item = "ptr_null"]
|
||||
pub const fn null<T: ?Sized + Thin>() -> *const T {
|
||||
pub const fn null<T: PointeeSized + Thin>() -> *const T {
|
||||
from_raw_parts(without_provenance::<()>(0), ())
|
||||
}
|
||||
|
||||
@@ -850,7 +850,7 @@ pub const fn null<T: ?Sized + Thin>() -> *const T {
|
||||
#[rustc_promotable]
|
||||
#[rustc_const_stable(feature = "const_ptr_null", since = "1.24.0")]
|
||||
#[rustc_diagnostic_item = "ptr_null_mut"]
|
||||
pub const fn null_mut<T: ?Sized + Thin>() -> *mut T {
|
||||
pub const fn null_mut<T: PointeeSized + Thin>() -> *mut T {
|
||||
from_raw_parts_mut(without_provenance_mut::<()>(0), ())
|
||||
}
|
||||
|
||||
@@ -1068,7 +1068,7 @@ pub fn with_exposed_provenance_mut<T>(addr: usize) -> *mut T {
|
||||
#[rustc_const_stable(feature = "ptr_from_ref", since = "1.76.0")]
|
||||
#[rustc_never_returns_null_ptr]
|
||||
#[rustc_diagnostic_item = "ptr_from_ref"]
|
||||
pub const fn from_ref<T: ?Sized>(r: &T) -> *const T {
|
||||
pub const fn from_ref<T: PointeeSized>(r: &T) -> *const T {
|
||||
r
|
||||
}
|
||||
|
||||
@@ -1118,7 +1118,7 @@ pub const fn from_ref<T: ?Sized>(r: &T) -> *const T {
|
||||
#[stable(feature = "ptr_from_ref", since = "1.76.0")]
|
||||
#[rustc_const_stable(feature = "ptr_from_ref", since = "1.76.0")]
|
||||
#[rustc_never_returns_null_ptr]
|
||||
pub const fn from_mut<T: ?Sized>(r: &mut T) -> *mut T {
|
||||
pub const fn from_mut<T: PointeeSized>(r: &mut T) -> *mut T {
|
||||
r
|
||||
}
|
||||
|
||||
@@ -2419,7 +2419,7 @@ pub(crate) unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usize {
|
||||
#[must_use = "pointer comparison produces a value"]
|
||||
#[rustc_diagnostic_item = "ptr_eq"]
|
||||
#[allow(ambiguous_wide_pointer_comparisons)] // it's actually clear here
|
||||
pub fn eq<T: ?Sized>(a: *const T, b: *const T) -> bool {
|
||||
pub fn eq<T: PointeeSized>(a: *const T, b: *const T) -> bool {
|
||||
a == b
|
||||
}
|
||||
|
||||
@@ -2443,7 +2443,7 @@ pub fn eq<T: ?Sized>(a: *const T, b: *const T) -> bool {
|
||||
#[stable(feature = "ptr_addr_eq", since = "1.76.0")]
|
||||
#[inline(always)]
|
||||
#[must_use = "pointer comparison produces a value"]
|
||||
pub fn addr_eq<T: ?Sized, U: ?Sized>(p: *const T, q: *const U) -> bool {
|
||||
pub fn addr_eq<T: PointeeSized, U: PointeeSized>(p: *const T, q: *const U) -> bool {
|
||||
(p as *const ()) == (q as *const ())
|
||||
}
|
||||
|
||||
@@ -2526,7 +2526,7 @@ pub fn fn_addr_eq<T: FnPtr, U: FnPtr>(f: T, g: U) -> bool {
|
||||
/// assert_eq!(actual, expected);
|
||||
/// ```
|
||||
#[stable(feature = "ptr_hash", since = "1.35.0")]
|
||||
pub fn hash<T: ?Sized, S: hash::Hasher>(hashee: *const T, into: &mut S) {
|
||||
pub fn hash<T: PointeeSized, S: hash::Hasher>(hashee: *const T, into: &mut S) {
|
||||
use crate::hash::Hash;
|
||||
hashee.hash(into);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
use super::*;
|
||||
use crate::cmp::Ordering::{Equal, Greater, Less};
|
||||
use crate::intrinsics::const_eval_select;
|
||||
use crate::marker::PointeeSized;
|
||||
use crate::mem::{self, SizedTypeProperties};
|
||||
use crate::slice::{self, SliceIndex};
|
||||
|
||||
impl<T: ?Sized> *mut T {
|
||||
impl<T: PointeeSized> *mut T {
|
||||
#[doc = include_str!("docs/is_null.md")]
|
||||
///
|
||||
/// # Examples
|
||||
@@ -110,7 +111,7 @@ impl<T: ?Sized> *mut T {
|
||||
#[inline]
|
||||
pub const fn with_metadata_of<U>(self, meta: *const U) -> *mut U
|
||||
where
|
||||
U: ?Sized,
|
||||
U: PointeeSized,
|
||||
{
|
||||
from_raw_parts_mut::<U>(self as *mut (), metadata(meta))
|
||||
}
|
||||
@@ -2006,7 +2007,7 @@ impl<T, const N: usize> *mut [T; N] {
|
||||
|
||||
/// Pointer equality is by address, as produced by the [`<*mut T>::addr`](pointer::addr) method.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> PartialEq for *mut T {
|
||||
impl<T: PointeeSized> PartialEq for *mut T {
|
||||
#[inline(always)]
|
||||
#[allow(ambiguous_wide_pointer_comparisons)]
|
||||
fn eq(&self, other: &*mut T) -> bool {
|
||||
@@ -2016,11 +2017,11 @@ impl<T: ?Sized> PartialEq for *mut T {
|
||||
|
||||
/// Pointer equality is an equivalence relation.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Eq for *mut T {}
|
||||
impl<T: PointeeSized> Eq for *mut T {}
|
||||
|
||||
/// Pointer comparison is by address, as produced by the [`<*mut T>::addr`](pointer::addr) method.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> Ord for *mut T {
|
||||
impl<T: PointeeSized> Ord for *mut T {
|
||||
#[inline]
|
||||
#[allow(ambiguous_wide_pointer_comparisons)]
|
||||
fn cmp(&self, other: &*mut T) -> Ordering {
|
||||
@@ -2036,7 +2037,7 @@ impl<T: ?Sized> Ord for *mut T {
|
||||
|
||||
/// Pointer comparison is by address, as produced by the [`<*mut T>::addr`](pointer::addr) method.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: ?Sized> PartialOrd for *mut T {
|
||||
impl<T: PointeeSized> PartialOrd for *mut T {
|
||||
#[inline(always)]
|
||||
#[allow(ambiguous_wide_pointer_comparisons)]
|
||||
fn partial_cmp(&self, other: &*mut T) -> Option<Ordering> {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::cmp::Ordering;
|
||||
use crate::marker::Unsize;
|
||||
use crate::marker::{PointeeSized, Unsize};
|
||||
use crate::mem::{MaybeUninit, SizedTypeProperties};
|
||||
use crate::num::NonZero;
|
||||
use crate::ops::{CoerceUnsized, DispatchFromDyn};
|
||||
@@ -67,7 +67,7 @@ use crate::{fmt, hash, intrinsics, mem, ptr};
|
||||
#[rustc_layout_scalar_valid_range_start(1)]
|
||||
#[rustc_nonnull_optimization_guaranteed]
|
||||
#[rustc_diagnostic_item = "NonNull"]
|
||||
pub struct NonNull<T: ?Sized> {
|
||||
pub struct NonNull<T: PointeeSized> {
|
||||
// Remember to use `.as_ptr()` instead of `.pointer`, as field projecting to
|
||||
// this is banned by <https://github.com/rust-lang/compiler-team/issues/807>.
|
||||
pointer: *const T,
|
||||
@@ -76,12 +76,12 @@ pub struct NonNull<T: ?Sized> {
|
||||
/// `NonNull` pointers are not `Send` because the data they reference may be aliased.
|
||||
// N.B., this impl is unnecessary, but should provide better error messages.
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
impl<T: ?Sized> !Send for NonNull<T> {}
|
||||
impl<T: PointeeSized> !Send for NonNull<T> {}
|
||||
|
||||
/// `NonNull` pointers are not `Sync` because the data they reference may be aliased.
|
||||
// N.B., this impl is unnecessary, but should provide better error messages.
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
impl<T: ?Sized> !Sync for NonNull<T> {}
|
||||
impl<T: PointeeSized> !Sync for NonNull<T> {}
|
||||
|
||||
impl<T: Sized> NonNull<T> {
|
||||
/// Creates a pointer with the given address and no [provenance][crate::ptr#provenance].
|
||||
@@ -190,7 +190,7 @@ impl<T: Sized> NonNull<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> NonNull<T> {
|
||||
impl<T: PointeeSized> NonNull<T> {
|
||||
/// Creates a new `NonNull`.
|
||||
///
|
||||
/// # Safety
|
||||
@@ -1604,7 +1604,7 @@ impl<T> NonNull<[T]> {
|
||||
}
|
||||
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
impl<T: ?Sized> Clone for NonNull<T> {
|
||||
impl<T: PointeeSized> Clone for NonNull<T> {
|
||||
#[inline(always)]
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
@@ -1612,39 +1612,39 @@ impl<T: ?Sized> Clone for NonNull<T> {
|
||||
}
|
||||
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
impl<T: ?Sized> Copy for NonNull<T> {}
|
||||
impl<T: PointeeSized> Copy for NonNull<T> {}
|
||||
|
||||
#[unstable(feature = "coerce_unsized", issue = "18598")]
|
||||
impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> {}
|
||||
impl<T: PointeeSized, U: PointeeSized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> {}
|
||||
|
||||
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
|
||||
impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: Unsize<U> {}
|
||||
impl<T: PointeeSized, U: PointeeSized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: Unsize<U> {}
|
||||
|
||||
#[stable(feature = "pin", since = "1.33.0")]
|
||||
unsafe impl<T: ?Sized> PinCoerceUnsized for NonNull<T> {}
|
||||
unsafe impl<T: PointeeSized> PinCoerceUnsized for NonNull<T> {}
|
||||
|
||||
#[unstable(feature = "pointer_like_trait", issue = "none")]
|
||||
impl<T> core::marker::PointerLike for NonNull<T> {}
|
||||
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
impl<T: ?Sized> fmt::Debug for NonNull<T> {
|
||||
impl<T: PointeeSized> fmt::Debug for NonNull<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Pointer::fmt(&self.as_ptr(), f)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
impl<T: ?Sized> fmt::Pointer for NonNull<T> {
|
||||
impl<T: PointeeSized> fmt::Pointer for NonNull<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Pointer::fmt(&self.as_ptr(), f)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
impl<T: ?Sized> Eq for NonNull<T> {}
|
||||
impl<T: PointeeSized> Eq for NonNull<T> {}
|
||||
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
impl<T: ?Sized> PartialEq for NonNull<T> {
|
||||
impl<T: PointeeSized> PartialEq for NonNull<T> {
|
||||
#[inline]
|
||||
#[allow(ambiguous_wide_pointer_comparisons)]
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
@@ -1653,7 +1653,7 @@ impl<T: ?Sized> PartialEq for NonNull<T> {
|
||||
}
|
||||
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
impl<T: ?Sized> Ord for NonNull<T> {
|
||||
impl<T: PointeeSized> Ord for NonNull<T> {
|
||||
#[inline]
|
||||
#[allow(ambiguous_wide_pointer_comparisons)]
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
@@ -1662,7 +1662,7 @@ impl<T: ?Sized> Ord for NonNull<T> {
|
||||
}
|
||||
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
impl<T: ?Sized> PartialOrd for NonNull<T> {
|
||||
impl<T: PointeeSized> PartialOrd for NonNull<T> {
|
||||
#[inline]
|
||||
#[allow(ambiguous_wide_pointer_comparisons)]
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
@@ -1671,7 +1671,7 @@ impl<T: ?Sized> PartialOrd for NonNull<T> {
|
||||
}
|
||||
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
impl<T: ?Sized> hash::Hash for NonNull<T> {
|
||||
impl<T: PointeeSized> hash::Hash for NonNull<T> {
|
||||
#[inline]
|
||||
fn hash<H: hash::Hasher>(&self, state: &mut H) {
|
||||
self.as_ptr().hash(state)
|
||||
@@ -1679,7 +1679,7 @@ impl<T: ?Sized> hash::Hash for NonNull<T> {
|
||||
}
|
||||
|
||||
#[unstable(feature = "ptr_internals", issue = "none")]
|
||||
impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
|
||||
impl<T: PointeeSized> From<Unique<T>> for NonNull<T> {
|
||||
#[inline]
|
||||
fn from(unique: Unique<T>) -> Self {
|
||||
unique.as_non_null_ptr()
|
||||
@@ -1687,7 +1687,7 @@ impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
|
||||
}
|
||||
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
impl<T: ?Sized> From<&mut T> for NonNull<T> {
|
||||
impl<T: PointeeSized> From<&mut T> for NonNull<T> {
|
||||
/// Converts a `&mut T` to a `NonNull<T>`.
|
||||
///
|
||||
/// This conversion is safe and infallible since references cannot be null.
|
||||
@@ -1698,7 +1698,7 @@ impl<T: ?Sized> From<&mut T> for NonNull<T> {
|
||||
}
|
||||
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
impl<T: ?Sized> From<&T> for NonNull<T> {
|
||||
impl<T: PointeeSized> From<&T> for NonNull<T> {
|
||||
/// Converts a `&T` to a `NonNull<T>`.
|
||||
///
|
||||
/// This conversion is safe and infallible since references cannot be null.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::fmt;
|
||||
use crate::marker::{PhantomData, Unsize};
|
||||
use crate::marker::{PhantomData, PointeeSized, Unsize};
|
||||
use crate::ops::{CoerceUnsized, DispatchFromDyn};
|
||||
use crate::pin::PinCoerceUnsized;
|
||||
use crate::ptr::NonNull;
|
||||
@@ -34,7 +34,7 @@ use crate::ptr::NonNull;
|
||||
#[repr(transparent)]
|
||||
// Lang item used experimentally by Miri to define the semantics of `Unique`.
|
||||
#[lang = "ptr_unique"]
|
||||
pub struct Unique<T: ?Sized> {
|
||||
pub struct Unique<T: PointeeSized> {
|
||||
pointer: NonNull<T>,
|
||||
// NOTE: this marker has no consequences for variance, but is necessary
|
||||
// for dropck to understand that we logically own a `T`.
|
||||
@@ -49,14 +49,14 @@ pub struct Unique<T: ?Sized> {
|
||||
/// unenforced by the type system; the abstraction using the
|
||||
/// `Unique` must enforce it.
|
||||
#[unstable(feature = "ptr_internals", issue = "none")]
|
||||
unsafe impl<T: Send + ?Sized> Send for Unique<T> {}
|
||||
unsafe impl<T: Send + PointeeSized> Send for Unique<T> {}
|
||||
|
||||
/// `Unique` pointers are `Sync` if `T` is `Sync` because the data they
|
||||
/// reference is unaliased. Note that this aliasing invariant is
|
||||
/// unenforced by the type system; the abstraction using the
|
||||
/// `Unique` must enforce it.
|
||||
#[unstable(feature = "ptr_internals", issue = "none")]
|
||||
unsafe impl<T: Sync + ?Sized> Sync for Unique<T> {}
|
||||
unsafe impl<T: Sync + PointeeSized> Sync for Unique<T> {}
|
||||
|
||||
#[unstable(feature = "ptr_internals", issue = "none")]
|
||||
impl<T: Sized> Unique<T> {
|
||||
@@ -78,7 +78,7 @@ impl<T: Sized> Unique<T> {
|
||||
}
|
||||
|
||||
#[unstable(feature = "ptr_internals", issue = "none")]
|
||||
impl<T: ?Sized> Unique<T> {
|
||||
impl<T: PointeeSized> Unique<T> {
|
||||
/// Creates a new `Unique`.
|
||||
///
|
||||
/// # Safety
|
||||
@@ -157,7 +157,7 @@ impl<T: ?Sized> Unique<T> {
|
||||
}
|
||||
|
||||
#[unstable(feature = "ptr_internals", issue = "none")]
|
||||
impl<T: ?Sized> Clone for Unique<T> {
|
||||
impl<T: PointeeSized> Clone for Unique<T> {
|
||||
#[inline]
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
@@ -165,33 +165,33 @@ impl<T: ?Sized> Clone for Unique<T> {
|
||||
}
|
||||
|
||||
#[unstable(feature = "ptr_internals", issue = "none")]
|
||||
impl<T: ?Sized> Copy for Unique<T> {}
|
||||
impl<T: PointeeSized> Copy for Unique<T> {}
|
||||
|
||||
#[unstable(feature = "ptr_internals", issue = "none")]
|
||||
impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {}
|
||||
impl<T: PointeeSized, U: PointeeSized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {}
|
||||
|
||||
#[unstable(feature = "ptr_internals", issue = "none")]
|
||||
impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Unique<U>> for Unique<T> where T: Unsize<U> {}
|
||||
impl<T: PointeeSized, U: PointeeSized> DispatchFromDyn<Unique<U>> for Unique<T> where T: Unsize<U> {}
|
||||
|
||||
#[unstable(feature = "pin_coerce_unsized_trait", issue = "123430")]
|
||||
unsafe impl<T: ?Sized> PinCoerceUnsized for Unique<T> {}
|
||||
unsafe impl<T: PointeeSized> PinCoerceUnsized for Unique<T> {}
|
||||
|
||||
#[unstable(feature = "ptr_internals", issue = "none")]
|
||||
impl<T: ?Sized> fmt::Debug for Unique<T> {
|
||||
impl<T: PointeeSized> fmt::Debug for Unique<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Pointer::fmt(&self.as_ptr(), f)
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "ptr_internals", issue = "none")]
|
||||
impl<T: ?Sized> fmt::Pointer for Unique<T> {
|
||||
impl<T: PointeeSized> fmt::Pointer for Unique<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt::Pointer::fmt(&self.as_ptr(), f)
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "ptr_internals", issue = "none")]
|
||||
impl<T: ?Sized> From<&mut T> for Unique<T> {
|
||||
impl<T: PointeeSized> From<&mut T> for Unique<T> {
|
||||
/// Converts a `&mut T` to a `Unique<T>`.
|
||||
///
|
||||
/// This conversion is infallible since references cannot be null.
|
||||
@@ -202,7 +202,7 @@ impl<T: ?Sized> From<&mut T> for Unique<T> {
|
||||
}
|
||||
|
||||
#[unstable(feature = "ptr_internals", issue = "none")]
|
||||
impl<T: ?Sized> From<NonNull<T>> for Unique<T> {
|
||||
impl<T: PointeeSized> From<NonNull<T>> for Unique<T> {
|
||||
/// Converts a `NonNull<T>` to a `Unique<T>`.
|
||||
///
|
||||
/// This conversion is infallible since `NonNull` cannot be null.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// See core/src/primitive_docs.rs for documentation.
|
||||
|
||||
use crate::cmp::Ordering::{self, *};
|
||||
use crate::marker::{ConstParamTy_, StructuralPartialEq, UnsizedConstParamTy};
|
||||
use crate::marker::{ConstParamTy_, PointeeSized, StructuralPartialEq, UnsizedConstParamTy};
|
||||
use crate::ops::ControlFlow::{self, Break, Continue};
|
||||
|
||||
// Recursive macro for implementing n-ary tuple functions and operations
|
||||
@@ -25,7 +25,7 @@ macro_rules! tuple_impls {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<$($T: PartialEq),+> PartialEq for ($($T,)+)
|
||||
where
|
||||
last_type!($($T,)+): ?Sized
|
||||
last_type!($($T,)+): PointeeSized
|
||||
{
|
||||
#[inline]
|
||||
fn eq(&self, other: &($($T,)+)) -> bool {
|
||||
@@ -43,7 +43,7 @@ macro_rules! tuple_impls {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<$($T: Eq),+> Eq for ($($T,)+)
|
||||
where
|
||||
last_type!($($T,)+): ?Sized
|
||||
last_type!($($T,)+): PointeeSized
|
||||
{}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ macro_rules! tuple_impls {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<$($T: PartialOrd),+> PartialOrd for ($($T,)+)
|
||||
where
|
||||
last_type!($($T,)+): ?Sized
|
||||
last_type!($($T,)+): PointeeSized
|
||||
{
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
|
||||
@@ -119,7 +119,7 @@ macro_rules! tuple_impls {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<$($T: Ord),+> Ord for ($($T,)+)
|
||||
where
|
||||
last_type!($($T,)+): ?Sized
|
||||
last_type!($($T,)+): PointeeSized
|
||||
{
|
||||
#[inline]
|
||||
fn cmp(&self, other: &($($T,)+)) -> Ordering {
|
||||
|
||||
Reference in New Issue
Block a user