@@ -12,6 +12,60 @@ use crate::fmt::Debug;
1212use crate :: hash:: Hash ;
1313use crate :: hash:: Hasher ;
1414
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+
1569/// Types that can be transferred across thread boundaries.
1670 ///
1771/// This trait is automatically implemented when the compiler determines it's
@@ -214,6 +268,20 @@ pub trait StructuralEq {
214268 // Empty.
215269}
216270
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+
217285/// Types whose values can be duplicated simply by copying bits.
218286///
219287/// By default, variable bindings have 'move semantics.' In other
@@ -401,6 +469,30 @@ pub macro Copy($item:item) {
401469 /* compiler built-in */
402470}
403471
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+
404496/// Types for which it is safe to share references between threads.
405497///
406498/// This trait is automatically implemented when the compiler determines
@@ -778,11 +870,14 @@ pub trait DiscriminantKind {
778870pub ( crate ) unsafe auto trait Freeze { }
779871
780872impl < 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+ }
786881
787882/// Types that can be safely moved after being pinned.
788883///
@@ -843,17 +938,19 @@ pub struct PhantomPinned;
843938#[ stable( feature = "pin" , since = "1.33.0" ) ]
844939impl !Unpin for PhantomPinned { }
845940
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+ }
854947
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+ }
857954
858955/// A marker for types that can be dropped.
859956///
@@ -888,43 +985,25 @@ pub trait Tuple {}
888985) ]
889986pub trait PointerLike { }
890987
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 ,
9281007}
9291008
9301009/// A common trait implemented by all function pointers.
0 commit comments