https://gcc.gnu.org/g:a7c999f8fea93e22af8e38489903f645531f2448

commit r16-2936-ga7c999f8fea93e22af8e38489903f645531f2448
Author: Philip Herron <herron.phi...@googlemail.com>
Date:   Fri Jul 11 13:51:10 2025 +0100

    gccrs: Add test case showing all derives working on enum
    
    We have more complex test cases already but this will close out this issue.
    
    Fixes Rust-GCC#2005
    
    gcc/testsuite/ChangeLog:
    
            * rust/execute/torture/issue-2005.rs: New test.
    
    Signed-off-by: Philip Herron <herron.phi...@googlemail.com>

Diff:
---
 gcc/testsuite/rust/execute/torture/issue-2005.rs | 465 +++++++++++++++++++++++
 1 file changed, 465 insertions(+)

diff --git a/gcc/testsuite/rust/execute/torture/issue-2005.rs 
b/gcc/testsuite/rust/execute/torture/issue-2005.rs
new file mode 100644
index 000000000000..87edb95988dc
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-2005.rs
@@ -0,0 +1,465 @@
+// { dg-additional-options "-w" }
+/* { dg-output "WORKS\r?\n" } */
+#![feature(intrinsics)]
+
+mod core {
+    mod option {
+        // #[rustc_diagnostic_item = "option_type"]
+        #[stable(feature = "rust1", since = "1.0.0")]
+        pub enum Option<T> {
+            /// No value
+            #[lang = "None"]
+            #[stable(feature = "rust1", since = "1.0.0")]
+            None,
+            /// Some value `T`
+            #[lang = "Some"]
+            #[stable(feature = "rust1", since = "1.0.0")]
+            Some(#[stable(feature = "rust1", since = "1.0.0")] T),
+        }
+    }
+
+    mod marker {
+        #[lang = "phantom_data"]
+        #[stable(feature = "rust1", since = "1.0.0")]
+        pub struct PhantomData<T: ?Sized>;
+
+        #[unstable(feature = "structural_match", issue = "31434")]
+        // #[rustc_on_unimplemented(message = "the type `{Self}` does not 
`#[derive(PartialEq)]`")]
+        #[lang = "structural_peq"]
+        pub trait StructuralPartialEq {
+            // Empty.
+        }
+
+        #[unstable(feature = "structural_match", issue = "31434")]
+        // #[rustc_on_unimplemented(message = "the type `{Self}` does not 
`#[derive(Eq)]`")]
+        #[lang = "structural_teq"]
+        pub trait StructuralEq {
+            // Empty.
+        }
+
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[lang = "sized"]
+        // #[rustc_on_unimplemented(
+        //     message = "the size for values of type `{Self}` cannot be known 
at compilation time",
+        //     label = "doesn't have a size known at compile-time"
+        // )]
+        // #[fundamental] // for Default, for example, which requires that 
`[T]: !Default` be evaluatable
+        // #[rustc_specialization_trait]
+        pub trait Sized {
+            // Empty.
+        }
+    }
+
+    mod cmp {
+        use super::marker::Sized;
+        use super::option::Option;
+
+        // #[derive(Clone, Copy, PartialEq, Debug, Hash)]
+        #[stable(feature = "rust1", since = "1.0.0")]
+        pub enum Ordering {
+            /// An ordering where a compared value is less than another.
+            #[stable(feature = "rust1", since = "1.0.0")]
+            Less = -1,
+            /// An ordering where a compared value is equal to another.
+            #[stable(feature = "rust1", since = "1.0.0")]
+            Equal = 0,
+            /// An ordering where a compared value is greater than another.
+            #[stable(feature = "rust1", since = "1.0.0")]
+            Greater = 1,
+        }
+
+        #[lang = "eq"]
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[doc(alias = "==")]
+        #[doc(alias = "!=")]
+        // #[rustc_on_unimplemented(
+        //     message = "can't compare `{Self}` with `{Rhs}`",
+        //     label = "no implementation for `{Self} == {Rhs}`"
+        // )]
+        pub trait PartialEq<Rhs: ?Sized = Self> {
+            /// This method tests for `self` and `other` values to be equal, 
and is used
+            /// by `==`.
+            #[must_use]
+            #[stable(feature = "rust1", since = "1.0.0")]
+            fn eq(&self, other: &Rhs) -> bool;
+
+            fn ne(&self, other: &Rhs) -> bool {
+                !self.eq(other)
+            }
+        }
+
+        #[doc(alias = "==")]
+        #[doc(alias = "!=")]
+        #[stable(feature = "rust1", since = "1.0.0")]
+        pub trait Eq: PartialEq<Self> {
+            // this method is used solely by #[deriving] to assert
+            // that every component of a type implements #[deriving]
+            // itself, the current deriving infrastructure means doing this
+            // assertion without using a method on this trait is nearly
+            // impossible.
+            //
+            // This should never be implemented by hand.
+            #[doc(hidden)]
+            #[stable(feature = "rust1", since = "1.0.0")]
+            fn assert_receiver_is_total_eq(&self) {}
+        }
+
+        #[lang = "partial_ord"]
+        #[stable(feature = "rust1", since = "1.0.0")]
+        #[doc(alias = ">")]
+        #[doc(alias = "<")]
+        #[doc(alias = "<=")]
+        #[doc(alias = ">=")]
+        // #[rustc_on_unimplemented(
+        //     message = "can't compare `{Self}` with `{Rhs}`",
+        //     label = "no implementation for `{Self} < {Rhs}` and `{Self} > 
{Rhs}`"
+        // )]
+        pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
+            /// This method returns an ordering between `self` and `other` 
values if one exists.
+            ///
+            /// # Examples
+            ///
+            /// ```
+            /// use std::cmp::Ordering;
+            ///
+            /// let result = 1.0.partial_cmp(&2.0);
+            /// assert_eq!(result, Some(Ordering::Less));
+            ///
+            /// let result = 1.0.partial_cmp(&1.0);
+            /// assert_eq!(result, Some(Ordering::Equal));
+            ///
+            /// let result = 2.0.partial_cmp(&1.0);
+            /// assert_eq!(result, Some(Ordering::Greater));
+            /// ```
+            ///
+            /// When comparison is impossible:
+            ///
+            /// ```
+            /// let result = f64::NAN.partial_cmp(&1.0);
+            /// assert_eq!(result, None);
+            /// ```
+            #[must_use]
+            #[stable(feature = "rust1", since = "1.0.0")]
+            fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+
+            /// This method tests less than (for `self` and `other`) and is 
used by the `<` operator.
+            ///
+            /// # Examples
+            ///
+            /// ```
+            /// let result = 1.0 < 2.0;
+            /// assert_eq!(result, true);
+            ///
+            /// let result = 2.0 < 1.0;
+            /// assert_eq!(result, false);
+            /// ```
+            #[inline]
+            #[must_use]
+            #[stable(feature = "rust1", since = "1.0.0")]
+            fn lt(&self, other: &Rhs) -> bool {
+                match self.partial_cmp(other) {
+                    Option::Some(Ordering::Less) => true,
+                    _ => false,
+                }
+            }
+
+            /// This method tests less than or equal to (for `self` and 
`other`) and is used by the `<=`
+            /// operator.
+            ///
+            /// # Examples
+            ///
+            /// ```
+            /// let result = 1.0 <= 2.0;
+            /// assert_eq!(result, true);
+            ///
+            /// let result = 2.0 <= 2.0;
+            /// assert_eq!(result, true);
+            /// ```
+            #[inline]
+            #[must_use]
+            #[stable(feature = "rust1", since = "1.0.0")]
+            fn le(&self, other: &Rhs) -> bool {
+                match self.partial_cmp(other) {
+                    Option::Some(Ordering::Less | Ordering::Equal) => true,
+                    _ => false,
+                }
+            }
+
+            /// This method tests greater than (for `self` and `other`) and is 
used by the `>` operator.
+            ///
+            /// # Examples
+            ///
+            /// ```
+            /// let result = 1.0 > 2.0;
+            /// assert_eq!(result, false);
+            ///
+            /// let result = 2.0 > 2.0;
+            /// assert_eq!(result, false);
+            /// ```
+            #[inline]
+            #[must_use]
+            #[stable(feature = "rust1", since = "1.0.0")]
+            fn gt(&self, other: &Rhs) -> bool {
+                match self.partial_cmp(other) {
+                    Option::Some(Ordering::Greater) => true,
+                    _ => false,
+                }
+            }
+
+            /// This method tests greater than or equal to (for `self` and 
`other`) and is used by the `>=`
+            /// operator.
+            ///
+            /// # Examples
+            ///
+            /// ```
+            /// let result = 2.0 >= 1.0;
+            /// assert_eq!(result, true);
+            ///
+            /// let result = 2.0 >= 2.0;
+            /// assert_eq!(result, true);
+            /// ```
+            #[inline]
+            #[must_use]
+            #[stable(feature = "rust1", since = "1.0.0")]
+            fn ge(&self, other: &Rhs) -> bool {
+                match self.partial_cmp(other) {
+                    Option::Some(Ordering::Greater | Ordering::Equal) => true,
+                    _ => false,
+                }
+            }
+        }
+
+        #[doc(alias = "<")]
+        #[doc(alias = ">")]
+        #[doc(alias = "<=")]
+        #[doc(alias = ">=")]
+        #[stable(feature = "rust1", since = "1.0.0")]
+        pub trait Ord: Eq + PartialOrd<Self> {
+            /// This method returns an [`Ordering`] between `self` and `other`.
+            ///
+            /// By convention, `self.cmp(&other)` returns the ordering 
matching the expression
+            /// `self <operator> other` if true.
+            ///
+            /// # Examples
+            ///
+            /// ```
+            /// use std::cmp::Ordering;
+            ///
+            /// assert_eq!(5.cmp(&10), Ordering::Less);
+            /// assert_eq!(10.cmp(&5), Ordering::Greater);
+            /// assert_eq!(5.cmp(&5), Ordering::Equal);
+            /// ```
+            #[must_use]
+            #[stable(feature = "rust1", since = "1.0.0")]
+            fn cmp(&self, other: &Self) -> Ordering;
+
+            /// Compares and returns the maximum of two values.
+            ///
+            /// Returns the second argument if the comparison determines them 
to be equal.
+            ///
+            /// # Examples
+            ///
+            /// ```
+            /// assert_eq!(2, 1.max(2));
+            /// assert_eq!(2, 2.max(2));
+            /// ```
+            #[stable(feature = "ord_max_min", since = "1.21.0")]
+            #[must_use]
+            fn max(self, other: Self) -> Self
+            where
+                Self: Sized,
+            {
+                self
+            }
+
+            /// Compares and returns the minimum of two values.
+            ///
+            /// Returns the first argument if the comparison determines them 
to be equal.
+            ///
+            /// # Examples
+            ///
+            /// ```
+            /// assert_eq!(1, 1.min(2));
+            /// assert_eq!(2, 2.min(2));
+            /// ```
+            #[stable(feature = "ord_max_min", since = "1.21.0")]
+            #[must_use]
+            fn min(self, other: Self) -> Self
+            where
+                Self: Sized,
+            {
+                self
+            }
+
+            /// Restrict a value to a certain interval.
+            ///
+            /// Returns `max` if `self` is greater than `max`, and `min` if 
`self` is
+            /// less than `min`. Otherwise this returns `self`.
+            ///
+            /// # Panics
+            ///
+            /// Panics if `min > max`.
+            ///
+            /// # Examples
+            ///
+            /// ```
+            /// #![feature(clamp)]
+            ///
+            /// assert!((-3).clamp(-2, 1) == -2);
+            /// assert!(0.clamp(-2, 1) == 0);
+            /// assert!(2.clamp(-2, 1) == 1);
+            /// ```
+            #[must_use]
+            #[unstable(feature = "clamp", issue = "44095")]
+            fn clamp(self, min: Self, max: Self) -> Self
+            where
+                Self: Sized,
+            {
+                if self < min {
+                    min
+                } else if self > max {
+                    max
+                } else {
+                    self
+                }
+            }
+        }
+    }
+
+    pub mod intrinsics {
+        #[lang = "discriminant_kind"]
+        pub trait DiscriminantKind {
+            #[lang = "discriminant_type"]
+            type Discriminant;
+        }
+
+        extern "rust-intrinsic" {
+            pub fn discriminant_value<T>(v: &T) -> <T as 
DiscriminantKind>::Discriminant;
+        }
+    }
+}
+
+use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::marker::Sized;
+use core::option::Option;
+
+// --------------
+
+impl PartialEq for isize {
+    fn eq(&self, other: &Self) -> bool {
+        *self == *other
+    }
+}
+
+impl PartialOrd for isize {
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+        if *self > *other {
+            Option::Some(Ordering::Greater)
+        } else if *self < *other {
+            Option::Some(Ordering::Less)
+        } else {
+            Option::Some(Ordering::Equal)
+        }
+    }
+
+    fn lt(&self, other: &Self) -> bool {
+        *self < *other
+    }
+    fn le(&self, other: &Self) -> bool {
+        *self <= *other
+    }
+    fn ge(&self, other: &Self) -> bool {
+        *self >= *other
+    }
+    fn gt(&self, other: &Self) -> bool {
+        *self > *other
+    }
+}
+
+impl Eq for isize {}
+
+impl Ord for isize {
+    fn cmp(&self, other: &Self) -> Ordering {
+        if *self > *other {
+            Ordering::Greater
+        } else if *self < *other {
+            Ordering::Less
+        } else {
+            Ordering::Equal
+        }
+    }
+}
+
+// ----------------------------------
+
+impl PartialEq for i32 {
+    fn eq(&self, other: &Self) -> bool {
+        *self == *other
+    }
+}
+
+impl PartialOrd for i32 {
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+        if *self > *other {
+            Option::Some(Ordering::Greater)
+        } else if *self < *other {
+            Option::Some(Ordering::Less)
+        } else {
+            Option::Some(Ordering::Equal)
+        }
+    }
+
+    fn lt(&self, other: &Self) -> bool {
+        *self < *other
+    }
+    fn le(&self, other: &Self) -> bool {
+        *self <= *other
+    }
+    fn ge(&self, other: &Self) -> bool {
+        *self >= *other
+    }
+    fn gt(&self, other: &Self) -> bool {
+        *self > *other
+    }
+}
+
+impl Ord for i32 {
+    fn cmp(&self, other: &Self) -> Ordering {
+        if *self > *other {
+            Ordering::Greater
+        } else if *self < *other {
+            Ordering::Less
+        } else {
+            Ordering::Equal
+        }
+    }
+}
+
+impl Eq for i32 {}
+
+#[derive(Ord, PartialOrd, PartialEq, Eq)]
+enum Foo {
+    A,
+    B(i32),
+}
+
+extern "C" {
+    fn puts(s: *const i8);
+}
+
+fn print(s: &str) {
+    unsafe {
+        puts(s as *const str as *const i8);
+    }
+}
+
+fn main() -> i32 {
+    let a = Foo::A;
+    let b = Foo::B(15);
+
+    if (a != b) {
+        print("WORKS");
+    }
+
+    0
+}

Reply via email to