@@ -12,6 +12,60 @@ use crate::fmt::Debug;
12
12
use crate :: hash:: Hash ;
13
13
use crate :: hash:: Hasher ;
14
14
15
+ /// Implements a given marker trait for multiple types at the same time.
16
+ ///
17
+ /// The basic syntax looks like this:
18
+ /// ```ignore private macro
19
+ /// marker_impls! { MarkerTrait for u8, i8 }
20
+ /// ```
21
+ /// You can also implement `unsafe` traits
22
+ /// ```ignore private macro
23
+ /// marker_impls! { unsafe MarkerTrait for u8, i8 }
24
+ /// ```
25
+ /// Add attributes to all impls:
26
+ /// ```ignore private macro
27
+ /// marker_impls! {
28
+ /// #[allow(lint)]
29
+ /// #[unstable(feature = "marker_trait", issue = "none")]
30
+ /// MarkerTrait for u8, i8
31
+ /// }
32
+ /// ```
33
+ /// And use generics:
34
+ /// ```ignore private macro
35
+ /// marker_impls! {
36
+ /// MarkerTrait for
37
+ /// u8, i8,
38
+ /// {T: ?Sized} *const T,
39
+ /// {T: ?Sized} *mut T,
40
+ /// {T: MarkerTrait} PhantomData<T>,
41
+ /// u32,
42
+ /// }
43
+ /// ```
44
+ #[ unstable( feature = "internal_impls_macro" , issue = "none" ) ]
45
+ macro marker_impls {
46
+ ( $( #[ $( $meta: tt) * ] ) * $Trait: ident for $( $( { $( $bounds: tt) * } ) ? $T: ty ) , + $( , ) ?) => {
47
+ // This inner macro is needed because... idk macros are weird.
48
+ // It allows repeating `meta` on all impls.
49
+ #[ unstable( feature = "internal_impls_macro" , issue = "none" ) ]
50
+ macro _impl {
51
+ ( $$( { $$( $$bounds_: tt) * } ) ? $$T_: ty ) => {
52
+ $( #[ $( $meta) * ] ) * impl<$$( $$( $$bounds_) * ) ?> $Trait for $$T_ { }
53
+ }
54
+ }
55
+ $( _impl ! { $( { $( $bounds) * } ) ? $T } ) +
56
+ } ,
57
+ ( $( #[ $( $meta: tt) * ] ) * unsafe $Trait: ident for $( $( { $( $bounds: tt) * } ) ? $T: ty ) , + $( , ) ?) => {
58
+ #[ unstable( feature = "internal_impls_macro" , issue = "none" ) ]
59
+ macro _impl {
60
+ ( $$( { $$( $$bounds_: tt) * } ) ? $$T_: ty ) => {
61
+ $( #[ $( $meta) * ] ) * unsafe impl <$$( $$( $$bounds_) * ) ?> $Trait for $$T_ { }
62
+ }
63
+ }
64
+
65
+ $( _impl ! { $( { $( $bounds) * } ) ? $T } ) +
66
+ } ,
67
+ }
68
+
15
69
/// Types that can be transferred across thread boundaries.
16
70
///
17
71
/// This trait is automatically implemented when the compiler determines it's
@@ -214,6 +268,20 @@ pub trait StructuralEq {
214
268
// Empty.
215
269
}
216
270
271
+ // FIXME: Remove special cases of these types from the compiler pattern checking code and always check `T: StructuralEq` instead
272
+ marker_impls ! {
273
+ #[ unstable( feature = "structural_match" , issue = "31434" ) ]
274
+ StructuralEq for
275
+ usize , u8 , u16 , u32 , u64 , u128 ,
276
+ isize , i8 , i16 , i32 , i64 , i128 ,
277
+ bool ,
278
+ char ,
279
+ str /* Technically requires `[u8]: StructuralEq` */ ,
280
+ { T , const N : usize } [ T ; N ] ,
281
+ { T } [ T ] ,
282
+ { T : ?Sized } & T ,
283
+ }
284
+
217
285
/// Types whose values can be duplicated simply by copying bits.
218
286
///
219
287
/// By default, variable bindings have 'move semantics.' In other
@@ -401,6 +469,30 @@ pub macro Copy($item:item) {
401
469
/* compiler built-in */
402
470
}
403
471
472
+ // Implementations of `Copy` for primitive types.
473
+ //
474
+ // Implementations that cannot be described in Rust
475
+ // are implemented in `traits::SelectionContext::copy_clone_conditions()`
476
+ // in `rustc_trait_selection`.
477
+ marker_impls ! {
478
+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
479
+ Copy for
480
+ usize , u8 , u16 , u32 , u64 , u128 ,
481
+ isize , i8 , i16 , i32 , i64 , i128 ,
482
+ f32 , f64 ,
483
+ bool , char ,
484
+ { T : ?Sized } * const T ,
485
+ { T : ?Sized } * mut T ,
486
+
487
+ }
488
+
489
+ #[ unstable( feature = "never_type" , issue = "35121" ) ]
490
+ impl Copy for ! { }
491
+
492
+ /// Shared references can be copied, but mutable references *cannot*!
493
+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
494
+ impl < T : ?Sized > Copy for & T { }
495
+
404
496
/// Types for which it is safe to share references between threads.
405
497
///
406
498
/// This trait is automatically implemented when the compiler determines
@@ -778,11 +870,14 @@ pub trait DiscriminantKind {
778
870
pub ( crate ) unsafe auto trait Freeze { }
779
871
780
872
impl < T : ?Sized > !Freeze for UnsafeCell < T > { }
781
- unsafe impl < T : ?Sized > Freeze for PhantomData < T > { }
782
- unsafe impl < T : ?Sized > Freeze for * const T { }
783
- unsafe impl < T : ?Sized > Freeze for * mut T { }
784
- unsafe impl < T : ?Sized > Freeze for & T { }
785
- unsafe impl < T : ?Sized > Freeze for & mut T { }
873
+ marker_impls ! {
874
+ unsafe Freeze for
875
+ { T : ?Sized } PhantomData <T >,
876
+ { T : ?Sized } * const T ,
877
+ { T : ?Sized } * mut T ,
878
+ { T : ?Sized } & T ,
879
+ { T : ?Sized } & mut T ,
880
+ }
786
881
787
882
/// Types that can be safely moved after being pinned.
788
883
///
@@ -843,17 +938,19 @@ pub struct PhantomPinned;
843
938
#[ stable( feature = "pin" , since = "1.33.0" ) ]
844
939
impl !Unpin for PhantomPinned { }
845
940
846
- #[ stable( feature = "pin" , since = "1.33.0" ) ]
847
- impl < ' a , T : ?Sized + ' a > Unpin for & ' a T { }
848
-
849
- #[ stable( feature = "pin" , since = "1.33.0" ) ]
850
- impl < ' a , T : ?Sized + ' a > Unpin for & ' a mut T { }
851
-
852
- #[ stable( feature = "pin_raw" , since = "1.38.0" ) ]
853
- impl < T : ?Sized > Unpin for * const T { }
941
+ marker_impls ! {
942
+ #[ stable( feature = "pin" , since = "1.33.0" ) ]
943
+ Unpin for
944
+ { T : ?Sized } & T ,
945
+ { T : ?Sized } & mut T ,
946
+ }
854
947
855
- #[ stable( feature = "pin_raw" , since = "1.38.0" ) ]
856
- impl < T : ?Sized > Unpin for * mut T { }
948
+ marker_impls ! {
949
+ #[ stable( feature = "pin_raw" , since = "1.38.0" ) ]
950
+ Unpin for
951
+ { T : ?Sized } * const T ,
952
+ { T : ?Sized } * mut T ,
953
+ }
857
954
858
955
/// A marker for types that can be dropped.
859
956
///
@@ -888,43 +985,25 @@ pub trait Tuple {}
888
985
) ]
889
986
pub trait PointerLike { }
890
987
891
- /// Implementations of `Copy` for primitive types.
892
- ///
893
- /// Implementations that cannot be described in Rust
894
- /// are implemented in `traits::SelectionContext::copy_clone_conditions()`
895
- /// in `rustc_trait_selection`.
896
- mod copy_impls {
897
-
898
- use super :: Copy ;
899
-
900
- macro_rules! impl_copy {
901
- ( $( $t: ty) * ) => {
902
- $(
903
- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
904
- impl Copy for $t { }
905
- ) *
906
- }
907
- }
908
-
909
- impl_copy ! {
910
- usize u8 u16 u32 u64 u128
911
- isize i8 i16 i32 i64 i128
912
- f32 f64
913
- bool char
914
- }
915
-
916
- #[ unstable( feature = "never_type" , issue = "35121" ) ]
917
- impl Copy for ! { }
918
-
919
- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
920
- impl < T : ?Sized > Copy for * const T { }
921
-
922
- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
923
- impl < T : ?Sized > Copy for * mut T { }
924
-
925
- /// Shared references can be copied, but mutable references *cannot*!
926
- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
927
- impl < T : ?Sized > Copy for & T { }
988
+ /// A marker for types which can be used as types of `const` generic parameters.
989
+ #[ cfg_attr( not( bootstrap) , lang = "const_param_ty" ) ]
990
+ #[ unstable( feature = "adt_const_params" , issue = "95174" ) ]
991
+ #[ rustc_on_unimplemented( message = "`{Self}` can't be used as a const parameter type" ) ]
992
+ pub trait ConstParamTy : StructuralEq { }
993
+
994
+ // FIXME(generic_const_parameter_types): handle `ty::FnDef`/`ty::Closure`
995
+ // FIXME(generic_const_parameter_types): handle `ty::Tuple`
996
+ marker_impls ! {
997
+ #[ unstable( feature = "adt_const_params" , issue = "95174" ) ]
998
+ ConstParamTy for
999
+ usize , u8 , u16 , u32 , u64 , u128 ,
1000
+ isize , i8 , i16 , i32 , i64 , i128 ,
1001
+ bool ,
1002
+ char ,
1003
+ str /* Technically requires `[u8]: ConstParamTy` */ ,
1004
+ { T : ConstParamTy , const N : usize } [ T ; N ] ,
1005
+ { T : ConstParamTy } [ T ] ,
1006
+ { T : ?Sized + ConstParamTy } & T ,
928
1007
}
929
1008
930
1009
/// A common trait implemented by all function pointers.
0 commit comments