Skip to content

Commit c16f00c

Browse files
authored
Rollup merge of #134642 - kpreid:pointerlike-cell, r=compiler-errors
Implement `PointerLike` for `isize`, `NonNull`, `Cell`, `UnsafeCell`, and `SyncUnsafeCell`. * Implementing `PointerLike` for `UnsafeCell` enables the possibility of interior mutable `dyn*` values. Since this means potentially exercising new codegen behavior, I added a test for it in `tests/ui/dyn-star/cell.rs`. Please let me know if there are further sorts of tests that should be written, or other care that should be taken with this change. It is unfortunately not possible without compiler changes to implement `PointerLike` for `Atomic*` types, since they are not `repr(transparent)` (and, in theory if not in practice, `AtomicUsize`'s alignment may be greater than that of an ordinary pointer or `usize`). * Implementing `PointerLike` for `NonNull` is useful for pointer types which wrap `NonNull`. * Implementing `PointerLike` for `isize` is just for completeness; I have no use cases in mind, but I cannot think of any reason not to do this. * Tracking issue: #102425 `@rustbot` label +F-dyn_star (there is no label or tracking issue for F-pointer_like_trait)
2 parents e86874f + 5c04151 commit c16f00c

File tree

6 files changed

+53
-3
lines changed

6 files changed

+53
-3
lines changed

Diff for: library/core/src/cell.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@
252252

253253
use crate::cmp::Ordering;
254254
use crate::fmt::{self, Debug, Display};
255-
use crate::marker::{PhantomData, Unsize};
255+
use crate::marker::{PhantomData, PointerLike, Unsize};
256256
use crate::mem;
257257
use crate::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn};
258258
use crate::pin::PinCoerceUnsized;
@@ -677,6 +677,9 @@ impl<T: CoerceUnsized<U>, U> CoerceUnsized<Cell<U>> for Cell<T> {}
677677
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
678678
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<Cell<U>> for Cell<T> {}
679679

680+
#[unstable(feature = "pointer_like_trait", issue = "none")]
681+
impl<T: PointerLike> PointerLike for Cell<T> {}
682+
680683
impl<T> Cell<[T]> {
681684
/// Returns a `&[Cell<T>]` from a `&Cell<[T]>`
682685
///
@@ -2258,6 +2261,9 @@ impl<T: CoerceUnsized<U>, U> CoerceUnsized<UnsafeCell<U>> for UnsafeCell<T> {}
22582261
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
22592262
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<UnsafeCell<U>> for UnsafeCell<T> {}
22602263

2264+
#[unstable(feature = "pointer_like_trait", issue = "none")]
2265+
impl<T: PointerLike> PointerLike for UnsafeCell<T> {}
2266+
22612267
/// [`UnsafeCell`], but [`Sync`].
22622268
///
22632269
/// This is just an `UnsafeCell`, except it implements `Sync`
@@ -2364,6 +2370,9 @@ impl<T: CoerceUnsized<U>, U> CoerceUnsized<SyncUnsafeCell<U>> for SyncUnsafeCell
23642370
//#[unstable(feature = "sync_unsafe_cell", issue = "95439")]
23652371
impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<SyncUnsafeCell<U>> for SyncUnsafeCell<T> {}
23662372

2373+
#[unstable(feature = "pointer_like_trait", issue = "none")]
2374+
impl<T: PointerLike> PointerLike for SyncUnsafeCell<T> {}
2375+
23672376
#[allow(unused)]
23682377
fn assert_coerce_unsized(
23692378
a: UnsafeCell<&i32>,

Diff for: library/core/src/marker.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,7 @@ pub trait PointerLike {}
10031003
marker_impls! {
10041004
#[unstable(feature = "pointer_like_trait", issue = "none")]
10051005
PointerLike for
1006+
isize,
10061007
usize,
10071008
{T} &T,
10081009
{T} &mut T,

Diff for: library/core/src/ptr/non_null.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1555,6 +1555,10 @@ impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NonNull<U>> for NonNull<T> where T: U
15551555
#[stable(feature = "pin", since = "1.33.0")]
15561556
unsafe impl<T: ?Sized> PinCoerceUnsized for NonNull<T> {}
15571557

1558+
#[unstable(feature = "pointer_like_trait", issue = "none")]
1559+
#[cfg(not(bootstrap))]
1560+
impl<T> core::marker::PointerLike for NonNull<T> {}
1561+
15581562
#[stable(feature = "nonnull", since = "1.25.0")]
15591563
impl<T: ?Sized> fmt::Debug for NonNull<T> {
15601564
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {

Diff for: tests/ui/dyn-star/cell.rs

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// This test with Cell also indirectly exercises UnsafeCell in dyn*.
2+
//
3+
//@ run-pass
4+
5+
#![feature(dyn_star)]
6+
#![allow(incomplete_features)]
7+
8+
use std::cell::Cell;
9+
10+
trait Rw<T> {
11+
fn read(&self) -> T;
12+
fn write(&self, v: T);
13+
}
14+
15+
impl<T: Copy> Rw<T> for Cell<T> {
16+
fn read(&self) -> T {
17+
self.get()
18+
}
19+
fn write(&self, v: T) {
20+
self.set(v)
21+
}
22+
}
23+
24+
fn make_dyn_star() -> dyn* Rw<usize> {
25+
Cell::new(42usize) as dyn* Rw<usize>
26+
}
27+
28+
fn main() {
29+
let x = make_dyn_star();
30+
31+
assert_eq!(x.read(), 42);
32+
x.write(24);
33+
assert_eq!(x.read(), 24);
34+
}

Diff for: tests/ui/dyn-star/error.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::fmt::Debug;
66
trait Foo {}
77

88
fn make_dyn_star() {
9-
let i = 42;
9+
let i = 42usize;
1010
let dyn_i: dyn* Foo = i; //~ ERROR trait bound `usize: Foo` is not satisfied
1111
}
1212

Diff for: tests/ui/dyn-star/float-as-dyn-star.stderr

+3-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ LL | f32::from_bits(0x1) as f64
1414
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `f64` needs to be a pointer-like type
1515
|
1616
= help: the trait `PointerLike` is not implemented for `f64`
17-
= help: the trait `PointerLike` is implemented for `usize`
17+
= help: the following other types implement trait `PointerLike`:
18+
isize
19+
usize
1820

1921
error: aborting due to 1 previous error; 1 warning emitted
2022

0 commit comments

Comments
 (0)