From a9fcb524ffbcccc0c0f56e9ecde431961a4619a9 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 17 May 2023 03:00:19 +0000 Subject: [PATCH] Impl ConstParamTy for tuples, make PartialStructuralEq a supertrait too --- .../rustc_trait_selection/src/traits/misc.rs | 3 ++- library/core/src/marker.rs | 26 ++++++++++++++++--- library/core/src/tuple.rs | 25 ++++++++++++++++++ .../adt_const_params/const_param_ty_good.rs | 4 ++- .../const_param_ty_impl_no_structural_eq.rs | 2 ++ .../const_param_ty_impl_union.rs | 1 + .../const_param_ty_impl_union.stderr | 14 ++++++++-- 7 files changed, 68 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index 2210ef975e6..e9cfd63e2ed 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -100,7 +100,8 @@ pub fn type_allowed_to_implement_const_param_ty<'tcx>( | ty::Str | ty::Array(..) | ty::Slice(_) - | ty::Ref(.., hir::Mutability::Not) => return Ok(()), + | ty::Ref(.., hir::Mutability::Not) + | ty::Tuple(_) => return Ok(()), &ty::Adt(adt, substs) => (adt, substs), diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 2d2d5d49175..9a541ccaeac 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -205,6 +205,20 @@ pub trait StructuralPartialEq { // Empty. } +marker_impls! { + #[unstable(feature = "structural_match", issue = "31434")] + StructuralPartialEq for + usize, u8, u16, u32, u64, u128, + isize, i8, i16, i32, i64, i128, + bool, + char, + str /* Technically requires `[u8]: StructuralEq` */, + (), + {T, const N: usize} [T; N], + {T} [T], + {T: ?Sized} &T, +} + /// Required trait for constants used in pattern matches. /// /// Any type that derives `Eq` automatically implements this trait, *regardless* @@ -267,6 +281,7 @@ marker_impls! { bool, char, str /* Technically requires `[u8]: StructuralEq` */, + (), {T, const N: usize} [T; N], {T} [T], {T: ?Sized} &T, @@ -974,7 +989,8 @@ pub trait PointerLike {} #[lang = "const_param_ty"] #[unstable(feature = "adt_const_params", issue = "95174")] #[rustc_on_unimplemented(message = "`{Self}` can't be used as a const parameter type")] -pub trait ConstParamTy: StructuralEq {} +#[allow(multiple_supertrait_upcastable)] +pub trait ConstParamTy: StructuralEq + StructuralPartialEq {} /// Derive macro generating an impl of the trait `ConstParamTy`. #[rustc_builtin_macro] @@ -983,8 +999,7 @@ pub macro ConstParamTy($item:item) { /* compiler built-in */ } -// FIXME(generic_const_parameter_types): handle `ty::FnDef`/`ty::Closure` -// FIXME(generic_const_parameter_types): handle `ty::Tuple` +// FIXME(adt_const_params): handle `ty::FnDef`/`ty::Closure` marker_impls! { #[unstable(feature = "adt_const_params", issue = "95174")] ConstParamTy for @@ -998,6 +1013,11 @@ marker_impls! { {T: ?Sized + ConstParamTy} &T, } +// FIXME(adt_const_params): Add to marker_impls call above once not in bootstrap +#[unstable(feature = "adt_const_params", issue = "95174")] +#[cfg(not(bootstrap))] +impl ConstParamTy for () {} + /// A common trait implemented by all function pointers. #[unstable( feature = "fn_ptr_trait", diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs index a1388dfeee6..ac8d04a8286 100644 --- a/library/core/src/tuple.rs +++ b/library/core/src/tuple.rs @@ -1,6 +1,9 @@ // See src/libstd/primitive_docs.rs for documentation. use crate::cmp::Ordering::{self, *}; +#[cfg(not(bootstrap))] +use crate::marker::ConstParamTy; +use crate::marker::{StructuralEq, StructuralPartialEq}; // Recursive macro for implementing n-ary tuple functions and operations // @@ -45,6 +48,28 @@ macro_rules! tuple_impls { {} } + maybe_tuple_doc! { + $($T)+ @ + #[unstable(feature = "structural_match", issue = "31434")] + #[cfg(not(bootstrap))] + impl<$($T: ConstParamTy),+> ConstParamTy for ($($T,)+) + {} + } + + maybe_tuple_doc! { + $($T)+ @ + #[unstable(feature = "structural_match", issue = "31434")] + impl<$($T),+> StructuralPartialEq for ($($T,)+) + {} + } + + maybe_tuple_doc! { + $($T)+ @ + #[unstable(feature = "structural_match", issue = "31434")] + impl<$($T),+> StructuralEq for ($($T,)+) + {} + } + maybe_tuple_doc! { $($T)+ @ #[stable(feature = "rust1", since = "1.0.0")] diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs index 87ae83dd966..100ab332a40 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs @@ -49,5 +49,7 @@ fn main() { check::>(); check::>(); - // FIXME: test tuples + check::<()>(); + check::<(i32,)>(); + check::<(D, D)>(); } diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs index 37986de481f..08f7c5cb542 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs @@ -9,9 +9,11 @@ struct CantParam(ImplementsConstParamTy); impl std::marker::ConstParamTy for CantParam {} //~^ error: the type `CantParam` does not `#[derive(Eq)]` +//~| error: the type `CantParam` does not `#[derive(PartialEq)]` #[derive(std::marker::ConstParamTy)] //~^ error: the type `CantParamDerive` does not `#[derive(Eq)]` +//~| error: the type `CantParamDerive` does not `#[derive(PartialEq)]` struct CantParamDerive(ImplementsConstParamTy); fn check() {} diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs index d70377a20c1..c04e96c569b 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs @@ -14,6 +14,7 @@ impl Eq for Union {} impl std::marker::StructuralEq for Union {} impl std::marker::ConstParamTy for Union {} +//~^ ERROR the type `Union` does not `#[derive(PartialEq)]` #[derive(std::marker::ConstParamTy)] //~^ ERROR this trait cannot be derived for unions diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr index 29370304605..985b933c40c 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr @@ -1,8 +1,18 @@ error: this trait cannot be derived for unions - --> $DIR/const_param_ty_impl_union.rs:18:10 + --> $DIR/const_param_ty_impl_union.rs:19:10 | LL | #[derive(std::marker::ConstParamTy)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error[E0277]: the type `Union` does not `#[derive(PartialEq)]` + --> $DIR/const_param_ty_impl_union.rs:16:36 + | +LL | impl std::marker::ConstParamTy for Union {} + | ^^^^^ the trait `StructuralPartialEq` is not implemented for `Union` + | +note: required by a bound in `ConstParamTy` + --> $SRC_DIR/core/src/marker.rs:LL:COL +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`.