From ad509633a261999ba9d73aff908d48da77e0245f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 24 Sep 2023 23:38:07 +0200 Subject: [PATCH] ConstParamTy: require Eq --- .../src/deriving/bounds.rs | 2 +- library/core/src/marker.rs | 7 +++- .../const_param_ty_impl_no_structural_eq.rs | 2 ++ ...onst_param_ty_impl_no_structural_eq.stderr | 35 +++++++++++++++++-- 4 files changed, 41 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/bounds.rs index 2c8e6f99c6739..8027ca2e7bb47 100644 --- a/compiler/rustc_builtin_macros/src/deriving/bounds.rs +++ b/compiler/rustc_builtin_macros/src/deriving/bounds.rs @@ -41,7 +41,7 @@ pub fn expand_deriving_const_param_ty( path: path_std!(marker::ConstParamTy), skip_path_as_bound: false, needs_copy_as_bound_if_packed: false, - additional_bounds: Vec::new(), + additional_bounds: vec![ty::Ty::Path(path_std!(cmp::Eq))], supports_unions: false, methods: Vec::new(), associated_types: Vec::new(), diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 5ec751e5168bf..5ed82e26a0ae7 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -986,11 +986,16 @@ pub trait Tuple {} pub trait PointerLike {} /// A marker for types which can be used as types of `const` generic parameters. +/// +/// These types must have a proper equivalence relation (`Eq`) and it must be automatically +/// derived (`StructuralPartialEq`). There's a hard-coded check in the compiler ensuring +/// that all fields are also `ConstParamTy`, which implies that recursively, all fields +/// are `StructuralPartialEq`. #[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")] #[allow(multiple_supertrait_upcastable)] -pub trait ConstParamTy: StructuralEq + StructuralPartialEq {} +pub trait ConstParamTy: StructuralEq + StructuralPartialEq + Eq {} /// Derive macro generating an impl of the trait `ConstParamTy`. #[rustc_builtin_macro] 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 08f7c5cb5423e..7174d1ec4f206 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 @@ -10,10 +10,12 @@ 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)]` +//~| the trait bound `CantParam: Eq` is not satisfied #[derive(std::marker::ConstParamTy)] //~^ error: the type `CantParamDerive` does not `#[derive(Eq)]` //~| error: the type `CantParamDerive` does not `#[derive(PartialEq)]` +//~| the trait bound `CantParamDerive: Eq` is not satisfied struct CantParamDerive(ImplementsConstParamTy); fn check() {} diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr index 43c5b96dc7cb8..2cf7cc07dbe5e 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr @@ -1,3 +1,17 @@ +error[E0277]: the trait bound `CantParam: Eq` is not satisfied + --> $DIR/const_param_ty_impl_no_structural_eq.rs:10:36 + | +LL | impl std::marker::ConstParamTy for CantParam {} + | ^^^^^^^^^ the trait `Eq` is not implemented for `CantParam` + | +note: required by a bound in `ConstParamTy` + --> $SRC_DIR/core/src/marker.rs:LL:COL +help: consider annotating `CantParam` with `#[derive(Eq)]` + | +LL + #[derive(Eq)] +LL | struct CantParam(ImplementsConstParamTy); + | + error[E0277]: the type `CantParam` does not `#[derive(PartialEq)]` --> $DIR/const_param_ty_impl_no_structural_eq.rs:10:36 | @@ -16,8 +30,23 @@ LL | impl std::marker::ConstParamTy for CantParam {} note: required by a bound in `ConstParamTy` --> $SRC_DIR/core/src/marker.rs:LL:COL +error[E0277]: the trait bound `CantParamDerive: Eq` is not satisfied + --> $DIR/const_param_ty_impl_no_structural_eq.rs:15:10 + | +LL | #[derive(std::marker::ConstParamTy)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Eq` is not implemented for `CantParamDerive` + | +note: required by a bound in `ConstParamTy` + --> $SRC_DIR/core/src/marker.rs:LL:COL + = note: this error originates in the derive macro `std::marker::ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider annotating `CantParamDerive` with `#[derive(Eq)]` + | +LL + #[derive(Eq)] +LL | struct CantParamDerive(ImplementsConstParamTy); + | + error[E0277]: the type `CantParamDerive` does not `#[derive(PartialEq)]` - --> $DIR/const_param_ty_impl_no_structural_eq.rs:14:10 + --> $DIR/const_param_ty_impl_no_structural_eq.rs:15:10 | LL | #[derive(std::marker::ConstParamTy)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `StructuralPartialEq` is not implemented for `CantParamDerive` @@ -27,7 +56,7 @@ note: required by a bound in `ConstParamTy` = note: this error originates in the derive macro `std::marker::ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the type `CantParamDerive` does not `#[derive(Eq)]` - --> $DIR/const_param_ty_impl_no_structural_eq.rs:14:10 + --> $DIR/const_param_ty_impl_no_structural_eq.rs:15:10 | LL | #[derive(std::marker::ConstParamTy)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `StructuralEq` is not implemented for `CantParamDerive` @@ -36,6 +65,6 @@ note: required by a bound in `ConstParamTy` --> $SRC_DIR/core/src/marker.rs:LL:COL = note: this error originates in the derive macro `std::marker::ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 4 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0277`.