Skip to content

Commit b39c4bc

Browse files
committed
Auto merge of #46749 - SimonSapin:exorcism, r=nikomatsakis
Move PhantomData<T> from Shared<T> to users of both Shared and #[may_dangle] After discussing #27730 (comment) today with @pnkfelix and @gankro, we concluded that it’s ok for drop checking not to be much smarter than the current `#[may_dangle]` design which requires an explicit unsafe opt-in.
2 parents a9f047c + 60dc104 commit b39c4bc

File tree

4 files changed

+34
-36
lines changed

4 files changed

+34
-36
lines changed

src/liballoc/arc.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use core::mem::{self, align_of_val, size_of_val, uninitialized};
2626
use core::ops::Deref;
2727
use core::ops::CoerceUnsized;
2828
use core::ptr::{self, Shared};
29-
use core::marker::Unsize;
29+
use core::marker::{Unsize, PhantomData};
3030
use core::hash::{Hash, Hasher};
3131
use core::{isize, usize};
3232
use core::convert::From;
@@ -198,6 +198,7 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize;
198198
#[stable(feature = "rust1", since = "1.0.0")]
199199
pub struct Arc<T: ?Sized> {
200200
ptr: Shared<ArcInner<T>>,
201+
phantom: PhantomData<T>,
201202
}
202203

203204
#[stable(feature = "rust1", since = "1.0.0")]
@@ -285,7 +286,7 @@ impl<T> Arc<T> {
285286
weak: atomic::AtomicUsize::new(1),
286287
data,
287288
};
288-
Arc { ptr: Shared::from(Box::into_unique(x)) }
289+
Arc { ptr: Shared::from(Box::into_unique(x)), phantom: PhantomData }
289290
}
290291

291292
/// Returns the contained value, if the `Arc` has exactly one strong reference.
@@ -397,6 +398,7 @@ impl<T: ?Sized> Arc<T> {
397398

398399
Arc {
399400
ptr: Shared::new_unchecked(arc_ptr),
401+
phantom: PhantomData,
400402
}
401403
}
402404

@@ -580,7 +582,7 @@ impl<T: ?Sized> Arc<T> {
580582
// Free the allocation without dropping its contents
581583
box_free(bptr);
582584

583-
Arc { ptr: Shared::new_unchecked(ptr) }
585+
Arc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData }
584586
}
585587
}
586588
}
@@ -607,7 +609,7 @@ impl<T> Arc<[T]> {
607609
&mut (*ptr).data as *mut [T] as *mut T,
608610
v.len());
609611

610-
Arc { ptr: Shared::new_unchecked(ptr) }
612+
Arc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData }
611613
}
612614
}
613615

@@ -667,7 +669,7 @@ impl<T: Clone> ArcFromSlice<T> for Arc<[T]> {
667669
// All clear. Forget the guard so it doesn't free the new ArcInner.
668670
mem::forget(guard);
669671

670-
Arc { ptr: Shared::new_unchecked(ptr) }
672+
Arc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData }
671673
}
672674
}
673675
}
@@ -725,7 +727,7 @@ impl<T: ?Sized> Clone for Arc<T> {
725727
}
726728
}
727729

728-
Arc { ptr: self.ptr }
730+
Arc { ptr: self.ptr, phantom: PhantomData }
729731
}
730732
}
731733

@@ -1052,7 +1054,7 @@ impl<T: ?Sized> Weak<T> {
10521054

10531055
// Relaxed is valid for the same reason it is on Arc's Clone impl
10541056
match inner.strong.compare_exchange_weak(n, n + 1, Relaxed, Relaxed) {
1055-
Ok(_) => return Some(Arc { ptr: self.ptr }),
1057+
Ok(_) => return Some(Arc { ptr: self.ptr, phantom: PhantomData }),
10561058
Err(old) => n = old,
10571059
}
10581060
}

src/liballoc/rc.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ use core::fmt;
252252
use core::hash::{Hash, Hasher};
253253
use core::intrinsics::abort;
254254
use core::marker;
255-
use core::marker::Unsize;
255+
use core::marker::{Unsize, PhantomData};
256256
use core::mem::{self, align_of_val, forget, size_of_val, uninitialized};
257257
use core::ops::Deref;
258258
use core::ops::CoerceUnsized;
@@ -283,6 +283,7 @@ struct RcBox<T: ?Sized> {
283283
#[stable(feature = "rust1", since = "1.0.0")]
284284
pub struct Rc<T: ?Sized> {
285285
ptr: Shared<RcBox<T>>,
286+
phantom: PhantomData<T>,
286287
}
287288

288289
#[stable(feature = "rust1", since = "1.0.0")]
@@ -315,6 +316,7 @@ impl<T> Rc<T> {
315316
weak: Cell::new(1),
316317
value,
317318
})),
319+
phantom: PhantomData,
318320
}
319321
}
320322

@@ -427,6 +429,7 @@ impl<T: ?Sized> Rc<T> {
427429

428430
Rc {
429431
ptr: Shared::new_unchecked(rc_ptr),
432+
phantom: PhantomData,
430433
}
431434
}
432435

@@ -647,6 +650,7 @@ impl Rc<Any> {
647650
forget(self);
648651
Ok(Rc {
649652
ptr: Shared::new_unchecked(raw as *const RcBox<T> as *mut _),
653+
phantom: PhantomData,
650654
})
651655
}
652656
} else {
@@ -691,7 +695,7 @@ impl<T: ?Sized> Rc<T> {
691695
// Free the allocation without dropping its contents
692696
box_free(bptr);
693697

694-
Rc { ptr: Shared::new_unchecked(ptr) }
698+
Rc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData }
695699
}
696700
}
697701
}
@@ -718,7 +722,7 @@ impl<T> Rc<[T]> {
718722
&mut (*ptr).value as *mut [T] as *mut T,
719723
v.len());
720724

721-
Rc { ptr: Shared::new_unchecked(ptr) }
725+
Rc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData }
722726
}
723727
}
724728

@@ -777,7 +781,7 @@ impl<T: Clone> RcFromSlice<T> for Rc<[T]> {
777781
// All clear. Forget the guard so it doesn't free the new RcBox.
778782
forget(guard);
779783

780-
Rc { ptr: Shared::new_unchecked(ptr) }
784+
Rc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData }
781785
}
782786
}
783787
}
@@ -868,7 +872,7 @@ impl<T: ?Sized> Clone for Rc<T> {
868872
#[inline]
869873
fn clone(&self) -> Rc<T> {
870874
self.inc_strong();
871-
Rc { ptr: self.ptr }
875+
Rc { ptr: self.ptr, phantom: PhantomData }
872876
}
873877
}
874878

@@ -1228,7 +1232,7 @@ impl<T: ?Sized> Weak<T> {
12281232
None
12291233
} else {
12301234
self.inc_strong();
1231-
Some(Rc { ptr: self.ptr })
1235+
Some(Rc { ptr: self.ptr, phantom: PhantomData })
12321236
}
12331237
}
12341238
}

src/liballoc/vec.rs

+3
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ use core::fmt;
7171
use core::hash::{self, Hash};
7272
use core::intrinsics::{arith_offset, assume};
7373
use core::iter::{FromIterator, FusedIterator, TrustedLen};
74+
use core::marker::PhantomData;
7475
use core::mem;
7576
#[cfg(not(test))]
7677
use core::num::Float;
@@ -1743,6 +1744,7 @@ impl<T> IntoIterator for Vec<T> {
17431744
mem::forget(self);
17441745
IntoIter {
17451746
buf: Shared::new_unchecked(begin),
1747+
phantom: PhantomData,
17461748
cap,
17471749
ptr: begin,
17481750
end,
@@ -2264,6 +2266,7 @@ impl<'a, T> FromIterator<T> for Cow<'a, [T]> where T: Clone {
22642266
#[stable(feature = "rust1", since = "1.0.0")]
22652267
pub struct IntoIter<T> {
22662268
buf: Shared<T>,
2269+
phantom: PhantomData<T>,
22672270
cap: usize,
22682271
ptr: *const T,
22692272
end: *const T,

src/libcore/ptr.rs

+12-23
Original file line numberDiff line numberDiff line change
@@ -2450,16 +2450,11 @@ impl<'a, T: ?Sized> From<&'a T> for Unique<T> {
24502450
}
24512451
}
24522452

2453-
/// A wrapper around a raw `*mut T` that indicates that the possessor
2454-
/// of this wrapper has shared ownership of the referent. Useful for
2455-
/// building abstractions like `Rc<T>`, `Arc<T>`, or doubly-linked lists, which
2456-
/// internally use aliased raw pointers to manage the memory that they own.
2453+
/// `*mut T` but non-zero and covariant.
24572454
///
2458-
/// This is similar to `Unique`, except that it doesn't make any aliasing
2459-
/// guarantees, and doesn't derive Send and Sync. Note that unlike `&T`,
2460-
/// Shared has no special mutability requirements. Shared may mutate data
2461-
/// aliased by other Shared pointers. More precise rules require Rust to
2462-
/// develop an actual aliasing model.
2455+
/// This is often the correct thing to use when building data structures using
2456+
/// raw pointers, but is ultimately more dangerous to use because of its additional
2457+
/// properties. If you're not sure if you should use `Shared<T>`, just use `*mut T`!
24632458
///
24642459
/// Unlike `*mut T`, the pointer must always be non-null, even if the pointer
24652460
/// is never dereferenced. This is so that enums may use this forbidden value
@@ -2469,20 +2464,14 @@ impl<'a, T: ?Sized> From<&'a T> for Unique<T> {
24692464
/// Unlike `*mut T`, `Shared<T>` is covariant over `T`. If this is incorrect
24702465
/// for your use case, you should include some PhantomData in your type to
24712466
/// provide invariance, such as `PhantomData<Cell<T>>` or `PhantomData<&'a mut T>`.
2472-
/// Usually this won't be necessary; covariance is correct for Rc, Arc, and LinkedList
2473-
/// because they provide a public API that follows the normal shared XOR mutable
2474-
/// rules of Rust.
2467+
/// Usually this won't be necessary; covariance is correct for most safe abstractions,
2468+
/// such as Box, Rc, Arc, Vec, and LinkedList. This is the case because they
2469+
/// provide a public API that follows the normal shared XOR mutable rules of Rust.
24752470
#[allow(missing_debug_implementations)]
24762471
#[unstable(feature = "shared", reason = "needs an RFC to flesh out design",
24772472
issue = "27730")]
24782473
pub struct Shared<T: ?Sized> {
24792474
pointer: NonZero<*const T>,
2480-
// NOTE: this marker has no consequences for variance, but is necessary
2481-
// for dropck to understand that we logically own a `T`.
2482-
//
2483-
// For details, see:
2484-
// https://github.com/rust-lang/rfcs/blob/master/text/0769-sound-generic-drop.md#phantom-data
2485-
_marker: PhantomData<T>,
24862475
}
24872476

24882477
/// `Shared` pointers are not `Send` because the data they reference may be aliased.
@@ -2518,12 +2507,12 @@ impl<T: ?Sized> Shared<T> {
25182507
/// `ptr` must be non-null.
25192508
#[unstable(feature = "shared", issue = "27730")]
25202509
pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
2521-
Shared { pointer: NonZero::new_unchecked(ptr), _marker: PhantomData }
2510+
Shared { pointer: NonZero::new_unchecked(ptr) }
25222511
}
25232512

25242513
/// Creates a new `Shared` if `ptr` is non-null.
25252514
pub fn new(ptr: *mut T) -> Option<Self> {
2526-
NonZero::new(ptr as *const T).map(|nz| Shared { pointer: nz, _marker: PhantomData })
2515+
NonZero::new(ptr as *const T).map(|nz| Shared { pointer: nz })
25272516
}
25282517

25292518
/// Acquires the underlying `*mut` pointer.
@@ -2580,20 +2569,20 @@ impl<T: ?Sized> fmt::Pointer for Shared<T> {
25802569
#[unstable(feature = "shared", issue = "27730")]
25812570
impl<T: ?Sized> From<Unique<T>> for Shared<T> {
25822571
fn from(unique: Unique<T>) -> Self {
2583-
Shared { pointer: unique.pointer, _marker: PhantomData }
2572+
Shared { pointer: unique.pointer }
25842573
}
25852574
}
25862575

25872576
#[unstable(feature = "shared", issue = "27730")]
25882577
impl<'a, T: ?Sized> From<&'a mut T> for Shared<T> {
25892578
fn from(reference: &'a mut T) -> Self {
2590-
Shared { pointer: NonZero::from(reference), _marker: PhantomData }
2579+
Shared { pointer: NonZero::from(reference) }
25912580
}
25922581
}
25932582

25942583
#[unstable(feature = "shared", issue = "27730")]
25952584
impl<'a, T: ?Sized> From<&'a T> for Shared<T> {
25962585
fn from(reference: &'a T) -> Self {
2597-
Shared { pointer: NonZero::from(reference), _marker: PhantomData }
2586+
Shared { pointer: NonZero::from(reference) }
25982587
}
25992588
}

0 commit comments

Comments
 (0)