From 22197442860d95e8a3bba16e293ef4d2e2d7adc0 Mon Sep 17 00:00:00 2001
From: Oliver Scherer <github35764891676564198441@oli-obk.de>
Date: Fri, 3 Apr 2020 21:50:59 +0200
Subject: [PATCH] Make several built-in types `StructuralEq` if their contents
 are `StructuralEq`

---
 src/libcore/array/mod.rs | 17 +++++++++++++++++
 src/libcore/cmp.rs       | 15 +++++++++++++++
 src/libcore/slice/mod.rs |  7 +++++++
 src/libcore/str/mod.rs   |  7 +++++++
 src/libcore/tuple.rs     |  9 +++++++++
 5 files changed, 55 insertions(+)

diff --git a/src/libcore/array/mod.rs b/src/libcore/array/mod.rs
index 937451274cfc2..79329fac88819 100644
--- a/src/libcore/array/mod.rs
+++ b/src/libcore/array/mod.rs
@@ -12,6 +12,7 @@ use crate::convert::{Infallible, TryFrom};
 use crate::fmt;
 use crate::hash::{self, Hash};
 use crate::marker::Unsize;
+use crate::marker::{StructuralEq, StructuralPartialEq};
 use crate::slice::{Iter, IterMut};
 
 mod iter;
@@ -228,6 +229,14 @@ where
     }
 }
 
+#[unstable(feature = "structural_match", issue = "31434")]
+impl<A, const N: usize> StructuralPartialEq for [A; N]
+where
+    A: StructuralPartialEq,
+    [A; N]: LengthAtMost32,
+{
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<A, B, const N: usize> PartialEq<[B; N]> for [A; N]
 where
@@ -345,6 +354,14 @@ where
 // __impl_slice_eq2! { [A; $N], &'b [B; $N] }
 // __impl_slice_eq2! { [A; $N], &'b mut [B; $N] }
 
+#[unstable(feature = "structural_match", issue = "31434")]
+impl<A, const N: usize> StructuralEq for [A; N]
+where
+    A: StructuralEq,
+    [A; N]: LengthAtMost32,
+{
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Eq, const N: usize> Eq for [T; N] where [T; N]: LengthAtMost32 {}
 
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index 604be7d5f68d0..e0df48a8002a2 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -1043,6 +1043,7 @@ pub fn max_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
 mod impls {
     use crate::cmp::Ordering::{self, Equal, Greater, Less};
     use crate::hint::unreachable_unchecked;
+    use crate::marker::{StructuralEq, StructuralPartialEq};
 
     macro_rules! partial_eq_impl {
         ($($t:ty)*) => ($(
@@ -1209,6 +1210,9 @@ mod impls {
 
     // & pointers
 
+    #[unstable(feature = "structural_match", issue = "31434")]
+    impl<A: ?Sized> StructuralPartialEq for &A where A: StructuralPartialEq {}
+
     #[stable(feature = "rust1", since = "1.0.0")]
     impl<A: ?Sized, B: ?Sized> PartialEq<&B> for &A
     where
@@ -1259,11 +1263,18 @@ mod impls {
             Ord::cmp(*self, *other)
         }
     }
+
+    #[unstable(feature = "structural_match", issue = "31434")]
+    impl<A: ?Sized> StructuralEq for &A where A: StructuralEq {}
+
     #[stable(feature = "rust1", since = "1.0.0")]
     impl<A: ?Sized> Eq for &A where A: Eq {}
 
     // &mut pointers
 
+    #[unstable(feature = "structural_match", issue = "31434")]
+    impl<A: ?Sized> StructuralPartialEq for &mut A where A: StructuralPartialEq {}
+
     #[stable(feature = "rust1", since = "1.0.0")]
     impl<A: ?Sized, B: ?Sized> PartialEq<&mut B> for &mut A
     where
@@ -1314,6 +1325,10 @@ mod impls {
             Ord::cmp(*self, *other)
         }
     }
+
+    #[unstable(feature = "structural_match", issue = "31434")]
+    impl<A: ?Sized> StructuralEq for &mut A where A: StructuralEq {}
+
     #[stable(feature = "rust1", since = "1.0.0")]
     impl<A: ?Sized> Eq for &mut A where A: Eq {}
 
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index 2140a7be9efe8..7dce9f040209f 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -30,6 +30,7 @@ use crate::intrinsics::{assume, exact_div, is_aligned_and_not_null, unchecked_su
 use crate::isize;
 use crate::iter::*;
 use crate::marker::{self, Copy, Send, Sized, Sync};
+use crate::marker::{StructuralEq, StructuralPartialEq};
 use crate::mem;
 use crate::ops::{self, FnMut, Range};
 use crate::option::Option;
@@ -5752,6 +5753,9 @@ extern "C" {
     fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32;
 }
 
+#[unstable(feature = "structural_match", issue = "31434")]
+impl<A> StructuralPartialEq for [A] where A: StructuralPartialEq {}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<A, B> PartialEq<[B]> for [A]
 where
@@ -5766,6 +5770,9 @@ where
     }
 }
 
+#[unstable(feature = "structural_match", issue = "31434")]
+impl<A> StructuralEq for [A] where A: StructuralEq {}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Eq> Eq for [T] {}
 
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index dc7637cfdb934..34005df91e192 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -1720,6 +1720,7 @@ Section: Trait implementations
 
 mod traits {
     use crate::cmp::Ordering;
+    use crate::marker::{StructuralEq, StructuralPartialEq};
     use crate::ops;
     use crate::slice::{self, SliceIndex};
 
@@ -1738,6 +1739,9 @@ mod traits {
         }
     }
 
+    #[unstable(feature = "structural_match", issue = "31434")]
+    impl StructuralEq for str {}
+
     #[stable(feature = "rust1", since = "1.0.0")]
     impl PartialEq for str {
         #[inline]
@@ -1750,6 +1754,9 @@ mod traits {
         }
     }
 
+    #[unstable(feature = "structural_match", issue = "31434")]
+    impl StructuralPartialEq for str {}
+
     #[stable(feature = "rust1", since = "1.0.0")]
     impl Eq for str {}
 
diff --git a/src/libcore/tuple.rs b/src/libcore/tuple.rs
index 9f8a3a1de4201..39249b3047586 100644
--- a/src/libcore/tuple.rs
+++ b/src/libcore/tuple.rs
@@ -2,6 +2,7 @@
 
 use crate::cmp::Ordering::*;
 use crate::cmp::*;
+use crate::marker::{StructuralEq, StructuralPartialEq};
 
 // macro for implementing n-ary tuple functions and operations
 macro_rules! tuple_impls {
@@ -23,6 +24,14 @@ macro_rules! tuple_impls {
                 }
             }
 
+            #[unstable(feature = "structural_match", issue = "31434")]
+            impl<$($T:StructuralPartialEq),+> StructuralPartialEq for ($($T,)+)
+                where last_type!($($T,)+): ?Sized {}
+
+            #[unstable(feature = "structural_match", issue = "31434")]
+            impl<$($T:StructuralEq),+> StructuralEq for ($($T,)+)
+                where last_type!($($T,)+): ?Sized {}
+
             #[stable(feature = "rust1", since = "1.0.0")]
             impl<$($T:Eq),+> Eq for ($($T,)+) where last_type!($($T,)+): ?Sized {}