26
26
#![ stable( feature = "rust1" , since = "1.0.0" ) ]
27
27
28
28
use clone:: Clone ;
29
+ use cmp;
30
+ use option:: Option ;
31
+ use hash:: Hash ;
32
+ use hash:: Hasher ;
29
33
30
34
/// Types able to be transferred across thread boundaries.
31
35
#[ unstable( feature = "core" ,
@@ -42,15 +46,15 @@ pub unsafe trait Send: 'static {
42
46
#[ lang="send" ]
43
47
#[ rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely" ]
44
48
#[ cfg( not( stage0) ) ]
45
- pub unsafe trait Send {
49
+ pub unsafe trait Send : MarkerTrait {
46
50
// empty.
47
51
}
48
52
49
53
/// Types with a constant size known at compile-time.
50
54
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
51
55
#[ lang="sized" ]
52
56
#[ rustc_on_unimplemented = "`{Self}` does not have a constant size known at compile-time" ]
53
- pub trait Sized {
57
+ pub trait Sized : MarkerTrait {
54
58
// Empty.
55
59
}
56
60
@@ -155,7 +159,7 @@ pub trait Sized {
155
159
/// change: that second example would fail to compile if we made `Foo` non-`Copy`.
156
160
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
157
161
#[ lang="copy" ]
158
- pub trait Copy {
162
+ pub trait Copy : MarkerTrait {
159
163
// Empty.
160
164
}
161
165
@@ -208,216 +212,10 @@ pub trait Copy {
208
212
reason = "will be overhauled with new lifetime rules; see RFC 458" ) ]
209
213
#[ lang="sync" ]
210
214
#[ rustc_on_unimplemented = "`{Self}` cannot be shared between threads safely" ]
211
- pub unsafe trait Sync {
215
+ pub unsafe trait Sync : MarkerTrait {
212
216
// Empty
213
217
}
214
218
215
- /// A marker type that indicates to the compiler that the instances
216
- /// of the type itself owns instances of the type parameter `T`.
217
- ///
218
- /// This is used to indicate that one or more instances of the type
219
- /// `T` could be dropped when instances of the type itself is dropped,
220
- /// though that may not be apparent from the other structure of the
221
- /// type itself. For example, the type may hold a `*mut T`, which the
222
- /// compiler does not automatically treat as owned.
223
- #[ unstable( feature = "core" ,
224
- reason = "Newly added to deal with scoping and destructor changes" ) ]
225
- #[ lang="phantom_data" ]
226
- #[ derive( PartialEq , Eq , PartialOrd , Ord ) ]
227
- pub struct PhantomData < T : ?Sized > ;
228
-
229
- impl < T : ?Sized > Copy for PhantomData < T > { }
230
- impl < T : ?Sized > Clone for PhantomData < T > {
231
- fn clone ( & self ) -> PhantomData < T > { * self }
232
- }
233
-
234
- /// A marker type whose type parameter `T` is considered to be
235
- /// covariant with respect to the type itself. This is (typically)
236
- /// used to indicate that an instance of the type `T` is being stored
237
- /// into memory and read from, even though that may not be apparent.
238
- ///
239
- /// For more information about variance, refer to this Wikipedia
240
- /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
241
- ///
242
- /// *Note:* It is very unusual to have to add a covariant constraint.
243
- /// If you are not sure, you probably want to use `InvariantType`.
244
- ///
245
- /// # Example
246
- ///
247
- /// Given a struct `S` that includes a type parameter `T`
248
- /// but does not actually *reference* that type parameter:
249
- ///
250
- /// ```ignore
251
- /// use std::mem;
252
- ///
253
- /// struct S<T> { x: *() }
254
- /// fn get<T>(s: &S<T>) -> T {
255
- /// unsafe {
256
- /// let x: *T = mem::transmute(s.x);
257
- /// *x
258
- /// }
259
- /// }
260
- /// ```
261
- ///
262
- /// The type system would currently infer that the value of
263
- /// the type parameter `T` is irrelevant, and hence a `S<int>` is
264
- /// a subtype of `S<Box<int>>` (or, for that matter, `S<U>` for
265
- /// any `U`). But this is incorrect because `get()` converts the
266
- /// `*()` into a `*T` and reads from it. Therefore, we should include the
267
- /// a marker field `CovariantType<T>` to inform the type checker that
268
- /// `S<T>` is a subtype of `S<U>` if `T` is a subtype of `U`
269
- /// (for example, `S<&'static int>` is a subtype of `S<&'a int>`
270
- /// for some lifetime `'a`, but not the other way around).
271
- #[ unstable( feature = "core" ,
272
- reason = "likely to change with new variance strategy" ) ]
273
- #[ lang="covariant_type" ]
274
- #[ derive( PartialEq , Eq , PartialOrd , Ord ) ]
275
- pub struct CovariantType < T : ?Sized > ;
276
-
277
- impl < T : ?Sized > Copy for CovariantType < T > { }
278
- impl < T : ?Sized > Clone for CovariantType < T > {
279
- fn clone ( & self ) -> CovariantType < T > { * self }
280
- }
281
-
282
- /// A marker type whose type parameter `T` is considered to be
283
- /// contravariant with respect to the type itself. This is (typically)
284
- /// used to indicate that an instance of the type `T` will be consumed
285
- /// (but not read from), even though that may not be apparent.
286
- ///
287
- /// For more information about variance, refer to this Wikipedia
288
- /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
289
- ///
290
- /// *Note:* It is very unusual to have to add a contravariant constraint.
291
- /// If you are not sure, you probably want to use `InvariantType`.
292
- ///
293
- /// # Example
294
- ///
295
- /// Given a struct `S` that includes a type parameter `T`
296
- /// but does not actually *reference* that type parameter:
297
- ///
298
- /// ```
299
- /// use std::mem;
300
- ///
301
- /// struct S<T> { x: *const () }
302
- /// fn get<T>(s: &S<T>, v: T) {
303
- /// unsafe {
304
- /// let x: fn(T) = mem::transmute(s.x);
305
- /// x(v)
306
- /// }
307
- /// }
308
- /// ```
309
- ///
310
- /// The type system would currently infer that the value of
311
- /// the type parameter `T` is irrelevant, and hence a `S<int>` is
312
- /// a subtype of `S<Box<int>>` (or, for that matter, `S<U>` for
313
- /// any `U`). But this is incorrect because `get()` converts the
314
- /// `*()` into a `fn(T)` and then passes a value of type `T` to it.
315
- ///
316
- /// Supplying a `ContravariantType` marker would correct the
317
- /// problem, because it would mark `S` so that `S<T>` is only a
318
- /// subtype of `S<U>` if `U` is a subtype of `T`; given that the
319
- /// function requires arguments of type `T`, it must also accept
320
- /// arguments of type `U`, hence such a conversion is safe.
321
- #[ unstable( feature = "core" ,
322
- reason = "likely to change with new variance strategy" ) ]
323
- #[ lang="contravariant_type" ]
324
- #[ derive( PartialEq , Eq , PartialOrd , Ord ) ]
325
- pub struct ContravariantType < T : ?Sized > ;
326
-
327
- impl < T : ?Sized > Copy for ContravariantType < T > { }
328
- impl < T : ?Sized > Clone for ContravariantType < T > {
329
- fn clone ( & self ) -> ContravariantType < T > { * self }
330
- }
331
-
332
- /// A marker type whose type parameter `T` is considered to be
333
- /// invariant with respect to the type itself. This is (typically)
334
- /// used to indicate that instances of the type `T` may be read or
335
- /// written, even though that may not be apparent.
336
- ///
337
- /// For more information about variance, refer to this Wikipedia
338
- /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
339
- ///
340
- /// # Example
341
- ///
342
- /// The Cell type is an example of an `InvariantType` which uses unsafe
343
- /// code to achieve "interior" mutability:
344
- ///
345
- /// ```
346
- /// struct Cell<T> { value: T }
347
- /// ```
348
- ///
349
- /// The type system would infer that `value` is only read here
350
- /// and never written, but in fact `Cell` uses unsafe code to achieve
351
- /// interior mutability. In order to get correct behavior, the
352
- /// `InvariantType` marker must be applied.
353
- #[ unstable( feature = "core" ,
354
- reason = "likely to change with new variance strategy" ) ]
355
- #[ lang="invariant_type" ]
356
- #[ derive( PartialEq , Eq , PartialOrd , Ord ) ]
357
- pub struct InvariantType < T : ?Sized > ;
358
-
359
- #[ unstable( feature = "core" ,
360
- reason = "likely to change with new variance strategy" ) ]
361
- impl < T : ?Sized > Copy for InvariantType < T > { }
362
- #[ unstable( feature = "core" ,
363
- reason = "likely to change with new variance strategy" ) ]
364
- impl < T : ?Sized > Clone for InvariantType < T > {
365
- fn clone ( & self ) -> InvariantType < T > { * self }
366
- }
367
-
368
- /// As `CovariantType`, but for lifetime parameters. Using
369
- /// `CovariantLifetime<'a>` indicates that it is ok to substitute
370
- /// a *longer* lifetime for `'a` than the one you originally
371
- /// started with (e.g., you could convert any lifetime `'foo` to
372
- /// `'static`). You almost certainly want `ContravariantLifetime`
373
- /// instead, or possibly `InvariantLifetime`. The only case where
374
- /// it would be appropriate is that you have a (type-casted, and
375
- /// hence hidden from the type system) function pointer with a
376
- /// signature like `fn(&'a T)` (and no other uses of `'a`). In
377
- /// this case, it is ok to substitute a larger lifetime for `'a`
378
- /// (e.g., `fn(&'static T)`), because the function is only
379
- /// becoming more selective in terms of what it accepts as
380
- /// argument.
381
- ///
382
- /// For more information about variance, refer to this Wikipedia
383
- /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
384
- #[ unstable( feature = "core" ,
385
- reason = "likely to change with new variance strategy" ) ]
386
- #[ lang="covariant_lifetime" ]
387
- #[ derive( Clone , Copy , PartialEq , Eq , PartialOrd , Ord ) ]
388
- pub struct CovariantLifetime < ' a > ;
389
-
390
- /// As `ContravariantType`, but for lifetime parameters. Using
391
- /// `ContravariantLifetime<'a>` indicates that it is ok to
392
- /// substitute a *shorter* lifetime for `'a` than the one you
393
- /// originally started with (e.g., you could convert `'static` to
394
- /// any lifetime `'foo`). This is appropriate for cases where you
395
- /// have an unsafe pointer that is actually a pointer into some
396
- /// memory with lifetime `'a`, and thus you want to limit the
397
- /// lifetime of your data structure to `'a`. An example of where
398
- /// this is used is the iterator for vectors.
399
- ///
400
- /// For more information about variance, refer to this Wikipedia
401
- /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
402
- #[ unstable( feature = "core" ,
403
- reason = "likely to change with new variance strategy" ) ]
404
- #[ lang="contravariant_lifetime" ]
405
- #[ derive( Clone , Copy , PartialEq , Eq , PartialOrd , Ord ) ]
406
- pub struct ContravariantLifetime < ' a > ;
407
-
408
- /// As `InvariantType`, but for lifetime parameters. Using
409
- /// `InvariantLifetime<'a>` indicates that it is not ok to
410
- /// substitute any other lifetime for `'a` besides its original
411
- /// value. This is appropriate for cases where you have an unsafe
412
- /// pointer that is actually a pointer into memory with lifetime `'a`,
413
- /// and this pointer is itself stored in an inherently mutable
414
- /// location (such as a `Cell`).
415
- #[ unstable( feature = "core" ,
416
- reason = "likely to change with new variance strategy" ) ]
417
- #[ lang="invariant_lifetime" ]
418
- #[ derive( Clone , Copy , PartialEq , Eq , PartialOrd , Ord ) ]
419
- pub struct InvariantLifetime < ' a > ;
420
-
421
219
/// A type which is considered "not POD", meaning that it is not
422
220
/// implicitly copyable. This is typically embedded in other types to
423
221
/// ensure that they are never copied, even if they lack a destructor.
@@ -435,6 +233,83 @@ pub struct NoCopy;
435
233
#[ derive( Clone , PartialEq , Eq , PartialOrd , Ord ) ]
436
234
pub struct Managed ;
437
235
236
+ macro_rules! impls{
237
+ ( $t: ident) => (
238
+ impl <T : ?Sized , S : Hasher > Hash <S > for $t<T > {
239
+ #[ inline]
240
+ fn hash( & self , _: & mut S ) {
241
+ }
242
+ }
243
+
244
+ impl <T : ?Sized > cmp:: PartialEq for $t<T > {
245
+ fn eq( & self , _other: & $t<T >) -> bool {
246
+ true
247
+ }
248
+ }
249
+
250
+ impl <T : ?Sized > cmp:: Eq for $t<T > {
251
+ }
252
+
253
+ impl <T : ?Sized > cmp:: PartialOrd for $t<T > {
254
+ fn partial_cmp( & self , _other: & $t<T >) -> Option <cmp:: Ordering > {
255
+ Option :: Some ( cmp:: Ordering :: Equal )
256
+ }
257
+ }
258
+
259
+ impl <T : ?Sized > cmp:: Ord for $t<T > {
260
+ fn cmp( & self , _other: & $t<T >) -> cmp:: Ordering {
261
+ cmp:: Ordering :: Equal
262
+ }
263
+ }
264
+
265
+ impl <T : ?Sized > Copy for $t<T > { }
266
+
267
+ impl <T : ?Sized > Clone for $t<T > {
268
+ fn clone( & self ) -> $t<T > {
269
+ $t
270
+ }
271
+ }
272
+ )
273
+ }
274
+
275
+ /// `MarkerTrait` is intended to be used as the supertrait for traits
276
+ /// that don't have any methods but instead serve just to designate
277
+ /// categories of types. An example would be the `Send` trait, which
278
+ /// indicates types that are sendable: `Send` does not itself offer
279
+ /// any methods, but instead is used to gate access to data.
280
+ ///
281
+ /// FIXME. Better documentation needed here!
282
+ pub trait MarkerTrait : PhantomFn < Self > { }
283
+ impl < T : ?Sized > MarkerTrait for T { }
284
+
285
+ /// `PhantomFn` is a marker trait for use with traits that do not
286
+ /// include any methods.
287
+ ///
288
+ /// FIXME. Better documentation needed here!
289
+ #[ lang="phantom_fn" ]
290
+ pub trait PhantomFn < A : ?Sized , R : ?Sized =( ) > { }
291
+
292
+ #[ cfg( stage0) ] // built into the trait matching system after stage0
293
+ impl < A : ?Sized , R : ?Sized , U : ?Sized > PhantomFn < A , R > for U { }
294
+
295
+ /// Specific to stage0. You should not be seeing these docs!
296
+ #[ cfg( stage0) ]
297
+ #[ lang="covariant_type" ] // only relevant to stage0
298
+ pub struct PhantomData < T : ?Sized > ;
299
+
300
+ /// `PhantomData` is a way to tell the compiler about fake fields.
301
+ /// The idea is that if the compiler encounters a `PhantomData<T>`
302
+ /// instance, it will behave *as if* an instance of the type `T` were
303
+ /// present for the purpose of various automatic analyses.
304
+ ///
305
+ /// FIXME. Better documentation needed here!
306
+ #[ cfg( not( stage0) ) ]
307
+ #[ lang="phantom_data" ]
308
+ pub struct PhantomData < T : ?Sized > ;
309
+
310
+ impls ! { PhantomData }
311
+
312
+
438
313
#[ cfg( not( stage0) ) ]
439
314
mod impls {
440
315
use super :: { Send , Sync , Sized } ;
0 commit comments