Skip to content

Commit 5c04151

Browse files
committed
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`. Also updated UI tests to account for the `isize` implementation changing error messages.
1 parent 13170cd commit 5c04151

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
@@ -997,6 +997,7 @@ pub trait PointerLike {}
997997
marker_impls! {
998998
#[unstable(feature = "pointer_like_trait", issue = "none")]
999999
PointerLike for
1000+
isize,
10001001
usize,
10011002
{T} &T,
10021003
{T} &mut T,

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

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

1551+
#[unstable(feature = "pointer_like_trait", issue = "none")]
1552+
#[cfg(not(bootstrap))]
1553+
impl<T> core::marker::PointerLike for NonNull<T> {}
1554+
15511555
#[stable(feature = "nonnull", since = "1.25.0")]
15521556
impl<T: ?Sized> fmt::Debug for NonNull<T> {
15531557
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)