17
17
#![ stable( feature = "rust1" , since = "1.0.0" ) ]
18
18
19
19
use intrinsics;
20
- use ops:: { CoerceUnsized , Deref } ;
20
+ use ops:: CoerceUnsized ;
21
21
use fmt;
22
22
use hash;
23
23
use marker:: { PhantomData , Unsize } ;
@@ -957,13 +957,25 @@ impl<T: ?Sized> PartialOrd for *mut T {
957
957
}
958
958
959
959
/// A wrapper around a raw non-null `*mut T` that indicates that the possessor
960
- /// of this wrapper owns the referent. This in turn implies that the
961
- /// `Unique<T>` is `Send`/`Sync` if `T` is `Send`/`Sync`, unlike a raw
962
- /// `*mut T` (which conveys no particular ownership semantics). It
963
- /// also implies that the referent of the pointer should not be
964
- /// modified without a unique path to the `Unique` reference. Useful
965
- /// for building abstractions like `Vec<T>` or `Box<T>`, which
966
- /// internally use raw pointers to manage the memory that they own.
960
+ /// of this wrapper owns the referent. Useful for building abstractions like
961
+ /// `Box<T>`, `Vec<T>`, `String`, and `HashMap<K, V>`.
962
+ ///
963
+ /// Unlike `*mut T`, `Unique<T>` behaves "as if" it were an instance of `T`.
964
+ /// It implements `Send`/`Sync` if `T` is `Send`/`Sync`. It also implies
965
+ /// the kind of strong aliasing guarantees an instance of `T` can expect:
966
+ /// the referent of the pointer should not be modified without a unique path to
967
+ /// its owning Unique.
968
+ ///
969
+ /// If you're uncertain of whether it's correct to use `Unique` for your purposes,
970
+ /// consider using `Shared`, which has weaker semantics.
971
+ ///
972
+ /// Unlike `*mut T`, the pointer must always be non-null, even if the pointer
973
+ /// is never dereferenced. This is so that enums may use this forbidden value
974
+ /// as a discriminant -- `Option<Unique<T>>` has the same size as `Unique<T>`.
975
+ /// However the pointer may still dangle if it isn't dereferenced.
976
+ ///
977
+ /// Unlike `*mut T`, `Unique<T>` is covariant over `T`. This should always be correct
978
+ /// for any type which upholds Unique's aliasing requirements.
967
979
#[ allow( missing_debug_implementations) ]
968
980
#[ unstable( feature = "unique" , reason = "needs an RFC to flesh out design" ,
969
981
issue = "27730" ) ]
@@ -991,6 +1003,20 @@ unsafe impl<T: Send + ?Sized> Send for Unique<T> { }
991
1003
#[ unstable( feature = "unique" , issue = "27730" ) ]
992
1004
unsafe impl < T : Sync + ?Sized > Sync for Unique < T > { }
993
1005
1006
+ #[ unstable( feature = "unique" , issue = "27730" ) ]
1007
+ impl < T : Sized > Unique < T > {
1008
+ /// Creates a new `Shared` that is dangling, but well-aligned.
1009
+ ///
1010
+ /// This is useful for initializing types which lazily allocate, like
1011
+ /// `Vec::new` does.
1012
+ pub fn empty ( ) -> Self {
1013
+ unsafe {
1014
+ let ptr = mem:: align_of :: < T > ( ) as * mut T ;
1015
+ Unique :: new ( ptr)
1016
+ }
1017
+ }
1018
+ }
1019
+
994
1020
#[ unstable( feature = "unique" , issue = "27730" ) ]
995
1021
impl < T : ?Sized > Unique < T > {
996
1022
/// Creates a new `Unique`.
@@ -1002,41 +1028,72 @@ impl<T: ?Sized> Unique<T> {
1002
1028
Unique { pointer : NonZero :: new ( ptr) , _marker : PhantomData }
1003
1029
}
1004
1030
1031
+ /// Acquires the underlying `*mut` pointer.
1032
+ pub fn as_ptr ( self ) -> * mut T {
1033
+ self . pointer . get ( ) as * mut T
1034
+ }
1035
+
1005
1036
/// Dereferences the content.
1006
- pub unsafe fn get ( & self ) -> & T {
1007
- & * * self . pointer
1037
+ ///
1038
+ /// The resulting lifetime is bound to self so this behaves "as if"
1039
+ /// it were actually an instance of T that is getting borrowed. If a longer
1040
+ /// (unbound) lifetime is needed, use `&*my_ptr.ptr()`.
1041
+ pub unsafe fn as_ref ( & self ) -> & T {
1042
+ & * self . as_ptr ( )
1008
1043
}
1009
1044
1010
1045
/// Mutably dereferences the content.
1011
- pub unsafe fn get_mut ( & mut self ) -> & mut T {
1012
- & mut * * * self
1046
+ ///
1047
+ /// The resulting lifetime is bound to self so this behaves "as if"
1048
+ /// it were actually an instance of T that is getting borrowed. If a longer
1049
+ /// (unbound) lifetime is needed, use `&mut *my_ptr.ptr()`.
1050
+ pub unsafe fn as_mut ( & mut self ) -> & mut T {
1051
+ & mut * self . as_ptr ( )
1013
1052
}
1014
1053
}
1015
1054
1016
- #[ unstable( feature = "unique" , issue = "27730" ) ]
1017
- impl < T : ?Sized , U : ?Sized > CoerceUnsized < Unique < U > > for Unique < T > where T : Unsize < U > { }
1018
-
1019
- #[ unstable( feature = "unique" , issue= "27730" ) ]
1020
- impl < T : ?Sized > Deref for Unique < T > {
1021
- type Target = * mut T ;
1022
-
1023
- #[ inline]
1024
- fn deref ( & self ) -> & * mut T {
1025
- unsafe { mem:: transmute ( & * self . pointer ) }
1055
+ #[ unstable( feature = "shared" , issue = "27730" ) ]
1056
+ impl < T : ?Sized > Clone for Unique < T > {
1057
+ fn clone ( & self ) -> Self {
1058
+ * self
1026
1059
}
1027
1060
}
1028
1061
1062
+ #[ unstable( feature = "shared" , issue = "27730" ) ]
1063
+ impl < T : ?Sized > Copy for Unique < T > { }
1064
+
1065
+ #[ unstable( feature = "unique" , issue = "27730" ) ]
1066
+ impl < T : ?Sized , U : ?Sized > CoerceUnsized < Unique < U > > for Unique < T > where T : Unsize < U > { }
1067
+
1029
1068
#[ unstable( feature = "unique" , issue = "27730" ) ]
1030
- impl < T > fmt:: Pointer for Unique < T > {
1069
+ impl < T : ? Sized > fmt:: Pointer for Unique < T > {
1031
1070
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1032
- fmt:: Pointer :: fmt ( & * self . pointer , f)
1071
+ fmt:: Pointer :: fmt ( & self . as_ptr ( ) , f)
1033
1072
}
1034
1073
}
1035
1074
1036
- /// A wrapper around a raw non-null `*mut T` that indicates that the possessor
1075
+ /// A wrapper around a raw `*mut T` that indicates that the possessor
1037
1076
/// of this wrapper has shared ownership of the referent. Useful for
1038
- /// building abstractions like `Rc<T>` or `Arc<T>`, which internally
1039
- /// use raw pointers to manage the memory that they own.
1077
+ /// building abstractions like `Rc<T>`, `Arc<T>`, or doubly-linked lists, which
1078
+ /// internally use aliased raw pointers to manage the memory that they own.
1079
+ ///
1080
+ /// This is similar to `Unique`, except that it doesn't make any aliasing
1081
+ /// guarantees, and doesn't derive Send and Sync. Note that unlike `&T`,
1082
+ /// Shared has no special mutability requirements. Shared may mutate data
1083
+ /// aliased by other Shared pointers. More precise rules require Rust to
1084
+ /// develop an actual aliasing model.
1085
+ ///
1086
+ /// Unlike `*mut T`, the pointer must always be non-null, even if the pointer
1087
+ /// is never dereferenced. This is so that enums may use this forbidden value
1088
+ /// as a discriminant -- `Option<Shared<T>>` has the same size as `Shared<T>`.
1089
+ /// However the pointer may still dangle if it isn't dereferenced.
1090
+ ///
1091
+ /// Unlike `*mut T`, `Shared<T>` is covariant over `T`. If this is incorrect
1092
+ /// for your use case, you should include some PhantomData in your type to
1093
+ /// provide invariance, such as `PhantomData<Cell<T>>` or `PhantomData<&'a mut T>`.
1094
+ /// Usually this won't be necessary; covariance is correct for Rc, Arc, and LinkedList
1095
+ /// because they provide a public API that follows the normal shared XOR mutable
1096
+ /// rules of Rust.
1040
1097
#[ allow( missing_debug_implementations) ]
1041
1098
#[ unstable( feature = "shared" , reason = "needs an RFC to flesh out design" ,
1042
1099
issue = "27730" ) ]
@@ -1060,23 +1117,59 @@ impl<T: ?Sized> !Send for Shared<T> { }
1060
1117
#[ unstable( feature = "shared" , issue = "27730" ) ]
1061
1118
impl < T : ?Sized > !Sync for Shared < T > { }
1062
1119
1120
+ #[ unstable( feature = "shared" , issue = "27730" ) ]
1121
+ impl < T : Sized > Shared < T > {
1122
+ /// Creates a new `Shared` that is dangling, but well-aligned.
1123
+ ///
1124
+ /// This is useful for initializing types which lazily allocate, like
1125
+ /// `Vec::new` does.
1126
+ pub fn empty ( ) -> Self {
1127
+ unsafe {
1128
+ let ptr = mem:: align_of :: < T > ( ) as * mut T ;
1129
+ Shared :: new ( ptr)
1130
+ }
1131
+ }
1132
+ }
1133
+
1063
1134
#[ unstable( feature = "shared" , issue = "27730" ) ]
1064
1135
impl < T : ?Sized > Shared < T > {
1065
1136
/// Creates a new `Shared`.
1066
1137
///
1067
1138
/// # Safety
1068
1139
///
1069
1140
/// `ptr` must be non-null.
1070
- pub unsafe fn new ( ptr : * const T ) -> Self {
1141
+ pub unsafe fn new ( ptr : * mut T ) -> Self {
1071
1142
Shared { pointer : NonZero :: new ( ptr) , _marker : PhantomData }
1072
1143
}
1073
- }
1074
1144
1075
- #[ unstable( feature = "shared" , issue = "27730" ) ]
1076
- impl < T : ?Sized > Shared < T > {
1145
+ /// Acquires the underlying `*mut` pointer.
1146
+ pub fn as_ptr ( self ) -> * mut T {
1147
+ self . pointer . get ( ) as * mut T
1148
+ }
1149
+
1150
+ /// Dereferences the content.
1151
+ ///
1152
+ /// The resulting lifetime is bound to self so this behaves "as if"
1153
+ /// it were actually an instance of T that is getting borrowed. If a longer
1154
+ /// (unbound) lifetime is needed, use `&*my_ptr.ptr()`.
1155
+ pub unsafe fn as_ref ( & self ) -> & T {
1156
+ & * self . as_ptr ( )
1157
+ }
1158
+
1159
+ /// Mutably dereferences the content.
1160
+ ///
1161
+ /// The resulting lifetime is bound to self so this behaves "as if"
1162
+ /// it were actually an instance of T that is getting borrowed. If a longer
1163
+ /// (unbound) lifetime is needed, use `&mut *my_ptr.ptr_mut()`.
1164
+ pub unsafe fn as_mut ( & mut self ) -> & mut T {
1165
+ & mut * self . as_ptr ( )
1166
+ }
1167
+
1077
1168
/// Acquires the underlying pointer as a `*mut` pointer.
1169
+ #[ rustc_deprecated( since = "1.19" , reason = "renamed to `as_ptr` for ergonomics/consistency" ) ]
1170
+ #[ unstable( feature = "shared" , issue = "27730" ) ]
1078
1171
pub unsafe fn as_mut_ptr ( & self ) -> * mut T {
1079
- * * self as _
1172
+ self . as_ptr ( )
1080
1173
}
1081
1174
}
1082
1175
@@ -1094,18 +1187,8 @@ impl<T: ?Sized> Copy for Shared<T> { }
1094
1187
impl < T : ?Sized , U : ?Sized > CoerceUnsized < Shared < U > > for Shared < T > where T : Unsize < U > { }
1095
1188
1096
1189
#[ unstable( feature = "shared" , issue = "27730" ) ]
1097
- impl < T : ?Sized > Deref for Shared < T > {
1098
- type Target = * const T ;
1099
-
1100
- #[ inline]
1101
- fn deref ( & self ) -> & * const T {
1102
- unsafe { mem:: transmute ( & * self . pointer ) }
1103
- }
1104
- }
1105
-
1106
- #[ unstable( feature = "shared" , issue = "27730" ) ]
1107
- impl < T > fmt:: Pointer for Shared < T > {
1190
+ impl < T : ?Sized > fmt:: Pointer for Shared < T > {
1108
1191
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1109
- fmt:: Pointer :: fmt ( & * self . pointer , f)
1192
+ fmt:: Pointer :: fmt ( & self . as_ptr ( ) , f)
1110
1193
}
1111
1194
}
0 commit comments