// { dg-additional-options "-w" } /* { dg-output "Foo A < B\r?\nFoo B < C\r?\nFoo C == C\r?\nBar x < y\r?\nBarFull s1 < s2\r?\n" } */ #![feature(intrinsics)] mod core { mod option { // #[rustc_diagnostic_item = "option_type"] #[stable(feature = "rust1", since = "1.0.0")] pub enum Option { /// 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; #[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 { /// 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 { // 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: PartialEq { /// 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; /// 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 { /// This method returns an [`Ordering`] between `self` and `other`. /// /// By convention, `self.cmp(&other)` returns the ordering matching the expression /// `self 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(v: &T) -> ::Discriminant; } } } use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd}; use core::marker::Sized; use core::option::Option; // for comparing discriminant_value impl PartialEq for isize { fn eq(&self, other: &Self) -> bool { *self == *other } } // for comparing discriminant_value impl PartialOrd for isize { fn partial_cmp(&self, other: &Self) -> Option { 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 PartialEq for i32 { fn eq(&self, other: &Self) -> bool { *self == *other } } impl PartialOrd for i32 { fn partial_cmp(&self, other: &Self) -> Option { 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(PartialEq, PartialOrd)] enum Foo { A, B(i32, i32, i32), C { inner: i32, outer: i32 }, } #[derive(Ord, PartialOrd, PartialEq, Eq)] struct Bar { a: i32, } #[derive(Ord, PartialOrd, PartialEq, Eq)] struct BarFull { a: i32, b: i32, c: i32, d: i32, } extern "C" { fn puts(s: *const i8); } fn print(s: &str) { unsafe { puts(s as *const str as *const i8); } } fn main() -> i32 { // Enum comparison let a = Foo::A; let b = Foo::B(15, 14, 13); let c = Foo::C { inner: 10, outer: 20, }; match a.partial_cmp(&b) { Option::Some(Ordering::Less) => print("Foo A < B"), Option::Some(Ordering::Greater) => print("Foo A > B"), Option::Some(Ordering::Equal) => print("Foo A == B"), _ => print("Foo A ? B"), } match b.partial_cmp(&c) { Option::Some(Ordering::Less) => print("Foo B < C"), Option::Some(Ordering::Greater) => print("Foo B > C"), Option::Some(Ordering::Equal) => print("Foo B == C"), _ => print("Foo B ? C"), } match c.partial_cmp(&c) { Option::Some(Ordering::Less) => print("Foo C < C ???"), Option::Some(Ordering::Greater) => print("Foo C > C ???"), Option::Some(Ordering::Equal) => print("Foo C == C"), _ => print("Foo C ? C"), } // Struct comparison: Bar let x = Bar { a: 10 }; let y = Bar { a: 20 }; if x < y { print("Bar x < y"); } else if x > y { print("Bar x > y"); } else { print("Bar x == y"); } // Struct comparison: BarFull let s1 = BarFull { a: 1, b: 2, c: 3, d: 4, }; let s2 = BarFull { a: 1, b: 2, c: 3, d: 5, }; match s1.cmp(&s2) { Ordering::Less => print("BarFull s1 < s2"), Ordering::Greater => print("BarFull s1 > s2"), Ordering::Equal => print("BarFull s1 == s2"), } 0 }