about summary refs log tree commit diff
path: root/library/core/src/tuple.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-12-13 06:37:08 +0000
committerbors <bors@rust-lang.org>2023-12-13 06:37:08 +0000
commitf651b436ce70a6f89ec1636fbedb128a473d809b (patch)
treed695dd95ea7e29d2f6afe1947dd430a3eae66bc2 /library/core/src/tuple.rs
parent9f1bfe53b60101962501cbfef0456bab5f9bebfc (diff)
parent027850569165192ce8912a985e9489e2ca5e8b65 (diff)
downloadrust-f651b436ce70a6f89ec1636fbedb128a473d809b.tar.gz
rust-f651b436ce70a6f89ec1636fbedb128a473d809b.zip
Auto merge of #117050 - c410-f3r:here-we-go-again, r=petrochenkov
[`RFC 3086`] Attempt to try to resolve blocking concerns

Implements what is described at https://github.com/rust-lang/rust/issues/83527#issuecomment-1744822345 to hopefully make some progress.

It is unknown if such approach is or isn't desired due to the lack of further feedback, as such, it is probably best to nominate this PR to the official entities.

`@rustbot` labels +I-compiler-nominated
Diffstat (limited to 'library/core/src/tuple.rs')
-rw-r--r--library/core/src/tuple.rs143
1 files changed, 143 insertions, 0 deletions
diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs
index 765f73636fb..3689312e6ae 100644
--- a/library/core/src/tuple.rs
+++ b/library/core/src/tuple.rs
@@ -8,6 +8,7 @@ use crate::marker::{StructuralEq, StructuralPartialEq};
 //
 // Also provides implementations for tuples with lesser arity. For example, tuple_impls!(A B C)
 // will implement everything for (A, B, C), (A, B) and (A,).
+#[cfg(bootstrap)]
 macro_rules! tuple_impls {
     // Stopping criteria (1-ary tuple)
     ($T:ident) => {
@@ -142,6 +143,148 @@ macro_rules! tuple_impls {
     }
 }
 
+// Recursive macro for implementing n-ary tuple functions and operations
+//
+// Also provides implementations for tuples with lesser arity. For example, tuple_impls!(A B C)
+// will implement everything for (A, B, C), (A, B) and (A,).
+#[cfg(not(bootstrap))]
+macro_rules! tuple_impls {
+    // Stopping criteria (1-ary tuple)
+    ($T:ident) => {
+        tuple_impls!(@impl $T);
+    };
+    // Running criteria (n-ary tuple, with n >= 2)
+    ($T:ident $( $U:ident )+) => {
+        tuple_impls!($( $U )+);
+        tuple_impls!(@impl $T $( $U )+);
+    };
+    // "Private" internal implementation
+    (@impl $( $T:ident )+) => {
+        maybe_tuple_doc! {
+            $($T)+ @
+            #[stable(feature = "rust1", since = "1.0.0")]
+            impl<$($T: PartialEq),+> PartialEq for ($($T,)+)
+            where
+                last_type!($($T,)+): ?Sized
+            {
+                #[inline]
+                fn eq(&self, other: &($($T,)+)) -> bool {
+                    $( ${ignore($T)} self.${index()} == other.${index()} )&&+
+                }
+                #[inline]
+                fn ne(&self, other: &($($T,)+)) -> bool {
+                    $( ${ignore($T)} self.${index()} != other.${index()} )||+
+                }
+            }
+        }
+
+        maybe_tuple_doc! {
+            $($T)+ @
+            #[stable(feature = "rust1", since = "1.0.0")]
+            impl<$($T: Eq),+> Eq for ($($T,)+)
+            where
+                last_type!($($T,)+): ?Sized
+            {}
+        }
+
+        maybe_tuple_doc! {
+            $($T)+ @
+            #[unstable(feature = "structural_match", issue = "31434")]
+            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
+                last_type!($($T,)+): ?Sized
+            {
+                #[inline]
+                fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
+                    lexical_partial_cmp!($( ${ignore($T)} self.${index()}, other.${index()} ),+)
+                }
+                #[inline]
+                fn lt(&self, other: &($($T,)+)) -> bool {
+                    lexical_ord!(lt, Less, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
+                }
+                #[inline]
+                fn le(&self, other: &($($T,)+)) -> bool {
+                    lexical_ord!(le, Less, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
+                }
+                #[inline]
+                fn ge(&self, other: &($($T,)+)) -> bool {
+                    lexical_ord!(ge, Greater, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
+                }
+                #[inline]
+                fn gt(&self, other: &($($T,)+)) -> bool {
+                    lexical_ord!(gt, Greater, $( ${ignore($T)} self.${index()}, other.${index()} ),+)
+                }
+            }
+        }
+
+        maybe_tuple_doc! {
+            $($T)+ @
+            #[stable(feature = "rust1", since = "1.0.0")]
+            impl<$($T: Ord),+> Ord for ($($T,)+)
+            where
+                last_type!($($T,)+): ?Sized
+            {
+                #[inline]
+                fn cmp(&self, other: &($($T,)+)) -> Ordering {
+                    lexical_cmp!($( ${ignore($T)} self.${index()}, other.${index()} ),+)
+                }
+            }
+        }
+
+        maybe_tuple_doc! {
+            $($T)+ @
+            #[stable(feature = "rust1", since = "1.0.0")]
+            impl<$($T: Default),+> Default for ($($T,)+) {
+                #[inline]
+                fn default() -> ($($T,)+) {
+                    ($({ let x: $T = Default::default(); x},)+)
+                }
+            }
+        }
+
+        #[stable(feature = "array_tuple_conv", since = "1.71.0")]
+        impl<T> From<[T; ${count($T)}]> for ($(${ignore($T)} T,)+) {
+            #[inline]
+            #[allow(non_snake_case)]
+            fn from(array: [T; ${count($T)}]) -> Self {
+                let [$($T,)+] = array;
+                ($($T,)+)
+            }
+        }
+
+        #[stable(feature = "array_tuple_conv", since = "1.71.0")]
+        impl<T> From<($(${ignore($T)} T,)+)> for [T; ${count($T)}] {
+            #[inline]
+            #[allow(non_snake_case)]
+            fn from(tuple: ($(${ignore($T)} T,)+)) -> Self {
+                let ($($T,)+) = tuple;
+                [$($T,)+]
+            }
+        }
+    }
+}
+
 // If this is a unary tuple, it adds a doc comment.
 // Otherwise, it hides the docs entirely.
 macro_rules! maybe_tuple_doc {