Skip to content

Commit 9744678

Browse files
committed
Add core::marker::PhantomData.
Port `core::ptr::Unique` to have `PhantomData`. Add `PhantomData` to `TypedArena` and `Vec` as well. As a drive-by, switch `ptr::Unique` from a tuple-struct to a struct with fields.
1 parent 76a58cb commit 9744678

File tree

8 files changed

+105
-25
lines changed

8 files changed

+105
-25
lines changed

src/libarena/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ use std::cell::{Cell, RefCell};
4343
use std::cmp;
4444
use std::intrinsics::{TyDesc, get_tydesc};
4545
use std::intrinsics;
46+
use std::marker;
4647
use std::mem;
4748
use std::num::{Int, UnsignedInt};
4849
use std::ptr;
@@ -366,6 +367,10 @@ pub struct TypedArena<T> {
366367

367368
/// A pointer to the first arena segment.
368369
first: RefCell<*mut TypedArenaChunk<T>>,
370+
371+
/// Marker indicating that dropping the arena causes its owned
372+
/// instances of `T` to be dropped.
373+
_own: marker::PhantomData<T>,
369374
}
370375

371376
struct TypedArenaChunk<T> {
@@ -461,6 +466,7 @@ impl<T> TypedArena<T> {
461466
ptr: Cell::new((*chunk).start() as *const T),
462467
end: Cell::new((*chunk).end() as *const T),
463468
first: RefCell::new(chunk),
469+
_own: marker::PhantomData,
464470
}
465471
}
466472
}

src/libcollections/btree/node.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ impl<T> Drop for RawItems<T> {
278278
#[unsafe_destructor]
279279
impl<K, V> Drop for Node<K, V> {
280280
fn drop(&mut self) {
281-
if self.keys.0.is_null() {
281+
if self.keys.ptr.is_null() {
282282
// We have already cleaned up this node.
283283
return;
284284
}
@@ -292,7 +292,7 @@ impl<K, V> Drop for Node<K, V> {
292292
self.destroy();
293293
}
294294

295-
self.keys.0 = ptr::null_mut();
295+
self.keys.ptr = ptr::null_mut();
296296
}
297297
}
298298

@@ -337,18 +337,18 @@ impl<K, V> Node<K, V> {
337337
unsafe fn destroy(&mut self) {
338338
let (alignment, size) =
339339
calculate_allocation_generic::<K, V>(self.capacity(), self.is_leaf());
340-
heap::deallocate(self.keys.0 as *mut u8, size, alignment);
340+
heap::deallocate(self.keys.ptr as *mut u8, size, alignment);
341341
}
342342

343343
#[inline]
344344
pub fn as_slices<'a>(&'a self) -> (&'a [K], &'a [V]) {
345345
unsafe {(
346346
mem::transmute(raw::Slice {
347-
data: self.keys.0,
347+
data: self.keys.ptr,
348348
len: self.len()
349349
}),
350350
mem::transmute(raw::Slice {
351-
data: self.vals.0,
351+
data: self.vals.ptr,
352352
len: self.len()
353353
})
354354
)}
@@ -368,7 +368,7 @@ impl<K, V> Node<K, V> {
368368
} else {
369369
unsafe {
370370
mem::transmute(raw::Slice {
371-
data: self.edges.0,
371+
data: self.edges.ptr,
372372
len: self.len() + 1
373373
})
374374
}
@@ -586,7 +586,7 @@ impl <K, V> Node<K, V> {
586586

587587
/// If the node has any children
588588
pub fn is_leaf(&self) -> bool {
589-
self.edges.0.is_null()
589+
self.edges.ptr.is_null()
590590
}
591591

592592
/// if the node has too few elements
@@ -1064,7 +1064,7 @@ impl<K, V> Node<K, V> {
10641064
vals: RawItems::from_slice(self.vals()),
10651065
edges: RawItems::from_slice(self.edges()),
10661066

1067-
ptr: self.keys.0 as *mut u8,
1067+
ptr: self.keys.ptr as *mut u8,
10681068
capacity: self.capacity(),
10691069
is_leaf: self.is_leaf()
10701070
},

src/libcollections/vec.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ use core::default::Default;
5757
use core::fmt;
5858
use core::hash::{self, Hash};
5959
use core::iter::{repeat, FromIterator, IntoIterator};
60-
use core::marker::{ContravariantLifetime, InvariantType};
60+
use core::marker::{self, ContravariantLifetime, InvariantType};
6161
use core::mem;
6262
use core::nonzero::NonZero;
6363
use core::num::{Int, UnsignedInt};
@@ -140,6 +140,7 @@ pub struct Vec<T> {
140140
ptr: NonZero<*mut T>,
141141
len: usize,
142142
cap: usize,
143+
_own: marker::PhantomData<T>,
143144
}
144145

145146
unsafe impl<T: Send> Send for Vec<T> { }
@@ -166,7 +167,7 @@ impl<T> Vec<T> {
166167
// non-null value which is fine since we never call deallocate on the ptr
167168
// if cap is 0. The reason for this is because the pointer of a slice
168169
// being NULL would break the null pointer optimization for enums.
169-
Vec { ptr: unsafe { NonZero::new(EMPTY as *mut T) }, len: 0, cap: 0 }
170+
unsafe { Vec::from_raw_parts(EMPTY as *mut T, 0, 0) }
170171
}
171172

172173
/// Constructs a new, empty `Vec<T>` with the specified capacity.
@@ -198,15 +199,15 @@ impl<T> Vec<T> {
198199
#[stable(feature = "rust1", since = "1.0.0")]
199200
pub fn with_capacity(capacity: usize) -> Vec<T> {
200201
if mem::size_of::<T>() == 0 {
201-
Vec { ptr: unsafe { NonZero::new(EMPTY as *mut T) }, len: 0, cap: usize::MAX }
202+
unsafe { Vec::from_raw_parts(EMPTY as *mut T, 0, usize::MAX) }
202203
} else if capacity == 0 {
203204
Vec::new()
204205
} else {
205206
let size = capacity.checked_mul(mem::size_of::<T>())
206207
.expect("capacity overflow");
207208
let ptr = unsafe { allocate(size, mem::min_align_of::<T>()) };
208209
if ptr.is_null() { ::alloc::oom() }
209-
Vec { ptr: unsafe { NonZero::new(ptr as *mut T) }, len: 0, cap: capacity }
210+
unsafe { Vec::from_raw_parts(ptr as *mut T, 0, capacity) }
210211
}
211212
}
212213

@@ -247,7 +248,12 @@ impl<T> Vec<T> {
247248
#[stable(feature = "rust1", since = "1.0.0")]
248249
pub unsafe fn from_raw_parts(ptr: *mut T, length: usize,
249250
capacity: usize) -> Vec<T> {
250-
Vec { ptr: NonZero::new(ptr), len: length, cap: capacity }
251+
Vec {
252+
ptr: NonZero::new(ptr),
253+
len: length,
254+
cap: capacity,
255+
_own: marker::PhantomData,
256+
}
251257
}
252258

253259
/// Creates a vector by copying the elements from a raw pointer.
@@ -1626,7 +1632,7 @@ impl<T> IntoIter<T> {
16261632
for _x in self.by_ref() { }
16271633
let IntoIter { allocation, cap, ptr: _ptr, end: _end } = self;
16281634
mem::forget(self);
1629-
Vec { ptr: NonZero::new(allocation), cap: cap, len: 0 }
1635+
Vec::from_raw_parts(allocation, 0, cap)
16301636
}
16311637
}
16321638
}

src/libcore/marker.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,24 @@ pub unsafe trait Sync {
202202
// Empty
203203
}
204204

205+
/// A marker type that indicates to the compiler that the instances
206+
/// of the type itself owns instances of the type parameter `T`.
207+
///
208+
/// This is used to indicate that one or more instances of the type
209+
/// `T` could be dropped when instances of the type itself is dropped,
210+
/// though that may not be apparent from the other structure of the
211+
/// type itself. For example, the type may hold a `*mut T`, which the
212+
/// compiler does not automatically treat as owned.
213+
#[unstable(feature = "core",
214+
reason = "Newly added to deal with scoping and destructor changes")]
215+
#[lang="phantom_data"]
216+
#[derive(PartialEq, Eq, PartialOrd, Ord)]
217+
pub struct PhantomData<T: ?Sized>;
218+
219+
impl<T: ?Sized> Copy for PhantomData<T> {}
220+
impl<T: ?Sized> Clone for PhantomData<T> {
221+
fn clone(&self) -> PhantomData<T> { *self }
222+
}
205223

206224
/// A marker type whose type parameter `T` is considered to be
207225
/// covariant with respect to the type itself. This is (typically)

src/libcore/ptr.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ use mem;
9292
use clone::Clone;
9393
use intrinsics;
9494
use option::Option::{self, Some, None};
95-
use marker::{Send, Sized, Sync};
95+
use marker::{self, Send, Sized, Sync};
9696

9797
use cmp::{PartialEq, Eq, Ord, PartialOrd};
9898
use cmp::Ordering::{self, Less, Equal, Greater};
@@ -522,7 +522,11 @@ impl<T> PartialOrd for *mut T {
522522
/// Useful for building abstractions like `Vec<T>` or `Box<T>`, which
523523
/// internally use raw pointers to manage the memory that they own.
524524
#[unstable(feature = "core", reason = "recently added to this module")]
525-
pub struct Unique<T>(pub *mut T);
525+
pub struct Unique<T> {
526+
/// The wrapped `*mut T`.
527+
pub ptr: *mut T,
528+
_own: marker::PhantomData<T>,
529+
}
526530

527531
/// `Unique` pointers are `Send` if `T` is `Send` because the data they
528532
/// reference is unaliased. Note that this aliasing invariant is
@@ -550,6 +554,13 @@ impl<T> Unique<T> {
550554
#[unstable(feature = "core",
551555
reason = "recently added to this module")]
552556
pub unsafe fn offset(self, offset: int) -> *mut T {
553-
self.0.offset(offset)
557+
self.ptr.offset(offset)
554558
}
555559
}
560+
561+
/// Creates a `Unique` wrapped around `ptr`, taking ownership of the
562+
/// data referenced by `ptr`.
563+
#[allow(non_snake_case)]
564+
pub fn Unique<T>(ptr: *mut T) -> Unique<T> {
565+
Unique { ptr: ptr, _own: marker::PhantomData }
566+
}

src/libflate/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,13 @@ pub struct Bytes {
4545
impl Deref for Bytes {
4646
type Target = [u8];
4747
fn deref(&self) -> &[u8] {
48-
unsafe { slice::from_raw_parts_mut(self.ptr.0, self.len) }
48+
unsafe { slice::from_raw_parts_mut(self.ptr.ptr, self.len) }
4949
}
5050
}
5151

5252
impl Drop for Bytes {
5353
fn drop(&mut self) {
54-
unsafe { libc::free(self.ptr.0 as *mut _); }
54+
unsafe { libc::free(self.ptr.ptr as *mut _); }
5555
}
5656
}
5757

src/librustc/middle/lang_items.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,8 @@ lets_do_this! {
312312
ExchangeHeapLangItem, "exchange_heap", exchange_heap;
313313
OwnedBoxLangItem, "owned_box", owned_box;
314314

315+
PhantomDataItem, "phantom_data", phantom_data;
316+
315317
CovariantTypeItem, "covariant_type", covariant_type;
316318
ContravariantTypeItem, "contravariant_type", contravariant_type;
317319
InvariantTypeItem, "invariant_type", invariant_type;

src/librustc/middle/ty.rs

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ use std::cell::{Cell, RefCell};
7272
use std::cmp;
7373
use std::fmt::{self, Show};
7474
use std::hash::{Hash, Writer, SipHasher, Hasher};
75+
#[cfg(stage0)]
76+
use std::marker;
7577
use std::mem;
7678
use std::ops;
7779
use std::rc::Rc;
@@ -931,6 +933,26 @@ pub struct TyS<'tcx> {
931933

932934
// the maximal depth of any bound regions appearing in this type.
933935
region_depth: u32,
936+
937+
// force the lifetime to be invariant to work-around
938+
// region-inference issues with a covariant lifetime.
939+
#[cfg(stage0)]
940+
marker: ShowInvariantLifetime<'tcx>,
941+
}
942+
943+
#[cfg(stage0)]
944+
struct ShowInvariantLifetime<'a>(marker::InvariantLifetime<'a>);
945+
#[cfg(stage0)]
946+
impl<'a> ShowInvariantLifetime<'a> {
947+
fn new() -> ShowInvariantLifetime<'a> {
948+
ShowInvariantLifetime(marker::InvariantLifetime)
949+
}
950+
}
951+
#[cfg(stage0)]
952+
impl<'a> fmt::Debug for ShowInvariantLifetime<'a> {
953+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
954+
write!(f, "InvariantLifetime")
955+
}
934956
}
935957

936958
impl fmt::Debug for TypeFlags {
@@ -939,11 +961,20 @@ impl fmt::Debug for TypeFlags {
939961
}
940962
}
941963

964+
#[cfg(stage0)]
942965
impl<'tcx> PartialEq for TyS<'tcx> {
943-
fn eq(&self, other: &TyS<'tcx>) -> bool {
966+
fn eq<'a,'b>(&'a self, other: &'b TyS<'tcx>) -> bool {
967+
let other: &'a TyS<'tcx> = unsafe { mem::transmute(other) };
944968
(self as *const _) == (other as *const _)
945969
}
946970
}
971+
#[cfg(not(stage0))]
972+
impl<'tcx> PartialEq for TyS<'tcx> {
973+
fn eq(&self, other: &TyS<'tcx>) -> bool {
974+
// (self as *const _) == (other as *const _)
975+
(self as *const TyS<'tcx>) == (other as *const TyS<'tcx>)
976+
}
977+
}
947978
impl<'tcx> Eq for TyS<'tcx> {}
948979

949980
impl<'tcx, S: Writer + Hasher> Hash<S> for TyS<'tcx> {
@@ -2475,11 +2506,17 @@ fn intern_ty<'tcx>(type_arena: &'tcx TypedArena<TyS<'tcx>>,
24752506

24762507
let flags = FlagComputation::for_sty(&st);
24772508

2478-
let ty = type_arena.alloc(TyS {
2479-
sty: st,
2480-
flags: flags.flags,
2481-
region_depth: flags.depth,
2482-
});
2509+
let ty = match () {
2510+
#[cfg(stage0)]
2511+
() => type_arena.alloc(TyS { sty: st,
2512+
flags: flags.flags,
2513+
region_depth: flags.depth,
2514+
marker: ShowInvariantLifetime::new(), }),
2515+
#[cfg(not(stage0))]
2516+
() => type_arena.alloc(TyS { sty: st,
2517+
flags: flags.flags,
2518+
region_depth: flags.depth, }),
2519+
};
24832520

24842521
debug!("Interned type: {:?} Pointer: {:?}",
24852522
ty, ty as *const _);

0 commit comments

Comments
 (0)