about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_trait_selection/src/traits/misc.rs3
-rw-r--r--library/core/src/marker.rs26
-rw-r--r--library/core/src/tuple.rs25
-rw-r--r--tests/ui/const-generics/adt_const_params/const_param_ty_good.rs4
-rw-r--r--tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs2
-rw-r--r--tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs1
-rw-r--r--tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr14
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
 //
@@ -47,6 +50,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")]
             impl<$($T: PartialOrd),+> PartialOrd for ($($T,)+)
             where
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::<D<u8>>();
     check::<D<[&[bool]; 8]>>();
 
-    // FIXME: test tuples
+    check::<()>();
+    check::<(i32,)>();
+    check::<(D<u8>, D<i32>)>();
 }
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<T: std::marker::ConstParamTy>() {}
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`.