summary refs log tree commit diff
path: root/library
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-11-20 20:10:13 +0100
committerGitHub <noreply@github.com>2024-11-20 20:10:13 +0100
commitfbed195b4df1a21aee835e68efa88e8f4c4e0d4a (patch)
treeae03424afdc87650c5c89f5d417674da47b88f06 /library
parent7fc2b337229dfb4bc2e410317af271c1b8dbfe6b (diff)
parent228068bc6efb16f359b5318e66fa789c2f58ce60 (diff)
downloadrust-fbed195b4df1a21aee835e68efa88e8f4c4e0d4a.tar.gz
rust-fbed195b4df1a21aee835e68efa88e8f4c4e0d4a.zip
Rollup merge of #133226 - compiler-errors:opt-in-pointer-like, r=lcnr
Make `PointerLike` opt-in instead of built-in

The `PointerLike` trait currently is a built-in trait that computes the layout of the type. This is a bit problematic, because types implement this trait automatically. Since this can be broken due to semver-compatible changes to a type's layout, this is undesirable. Also, calling `layout_of` in the trait system also causes cycles.

This PR makes the trait implemented via regular impls, and adds additional validation on top to make sure that those impls are valid. This could eventually be `derive()`d for custom smart pointers, and we can trust *that* as a semver promise rather than risking library authors accidentally breaking it.

On the other hand, we may never expose `PointerLike`, but at least now the implementation doesn't invoke `layout_of` which could cause ICEs or cause cycles.

Right now for a `PointerLike` impl to be valid, it must be an ADT that is `repr(transparent)` and the non-1zst field needs to implement `PointerLike`. There are also some primitive impls for `&T`/ `&mut T`/`*const T`/`*mut T`/`Box<T>`.
Diffstat (limited to 'library')
-rw-r--r--library/alloc/src/boxed.rs6
-rw-r--r--library/alloc/src/lib.rs1
-rw-r--r--library/core/src/marker.rs12
3 files changed, 19 insertions, 0 deletions
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index ac3e4626ee5..ee60ec0fbac 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -191,6 +191,8 @@ use core::error::{self, Error};
 use core::fmt;
 use core::future::Future;
 use core::hash::{Hash, Hasher};
+#[cfg(not(bootstrap))]
+use core::marker::PointerLike;
 use core::marker::{Tuple, Unsize};
 use core::mem::{self, SizedTypeProperties};
 use core::ops::{
@@ -2131,3 +2133,7 @@ impl<E: Error> Error for Box<E> {
         Error::provide(&**self, request);
     }
 }
+
+#[cfg(not(bootstrap))]
+#[unstable(feature = "pointer_like_trait", issue = "none")]
+impl<T> PointerLike for Box<T> {}
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 7839fe04b8d..041ff37897f 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -136,6 +136,7 @@
 #![feature(panic_internals)]
 #![feature(pattern)]
 #![feature(pin_coerce_unsized_trait)]
+#![feature(pointer_like_trait)]
 #![feature(ptr_internals)]
 #![feature(ptr_metadata)]
 #![feature(ptr_sub_ptr)]
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 1c5c58d64a2..c8ea52a1fb0 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -981,6 +981,18 @@ pub trait Tuple {}
 )]
 pub trait PointerLike {}
 
+#[cfg(not(bootstrap))]
+marker_impls! {
+    #[unstable(feature = "pointer_like_trait", issue = "none")]
+    PointerLike for
+        usize,
+        {T} &T,
+        {T} &mut T,
+        {T} *const T,
+        {T} *mut T,
+        {T: PointerLike} crate::pin::Pin<T>,
+}
+
 /// A marker for types which can be used as types of `const` generic parameters.
 ///
 /// These types must have a proper equivalence relation (`Eq`) and it must be automatically