Skip to content

Commit 3e90228

Browse files
authored
Rollup merge of rust-lang#108161 - WaffleLapkin:const_param_ty, r=BoxyUwU
Add `ConstParamTy` trait This is a bit sketch, but idk. r? `@BoxyUwU` Yet to be done: - [x] ~~Figure out if it's okay to implement `StructuralEq` for primitives / possibly remove their special casing~~ (it should be okay, but maybe not in this PR...) - [ ] Maybe refactor the code a little bit - [x] Use a macro to make impls a bit nicer Future work: - [ ] Actually™ use the trait when checking if a `const` generic type is allowed - [ ] _Really_ refactor the surrounding code - [ ] Refactor `marker.rs` into multiple modules for each "theme" of markers
2 parents 24b35f1 + 9920a55 commit 3e90228

File tree

2 files changed

+132
-52
lines changed

2 files changed

+132
-52
lines changed

core/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@
162162
#![feature(const_waker)]
163163
#![feature(core_panic)]
164164
#![feature(duration_consts_float)]
165+
#![feature(internal_impls_macro)]
165166
#![feature(ip)]
166167
#![feature(is_ascii_octdigit)]
167168
#![feature(maybe_uninit_uninit_array)]

core/src/marker.rs

Lines changed: 131 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,60 @@ use crate::fmt::Debug;
1212
use crate::hash::Hash;
1313
use 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 {
778870
pub(crate) unsafe auto trait Freeze {}
779871

780872
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+
}
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")]
844939
impl !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
)]
889986
pub 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

Comments
 (0)