blob: 5c9373675812c081bc1a9ef6bd8e90eee4ccbd0e [file] [log] [blame]
// { dg-options "-w" }
// { dg-output "less\r*\n" }
#![feature(intrinsics, lang_items)]
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;
// 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<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 PartialEq for i32 {
fn eq(&self, other: &Self) -> bool {
*self == *other
}
}
impl Eq for i32 {}
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
}
}
}
// ------------
#[derive(Ord, PartialOrd, PartialEq, Eq)]
struct Bar {
a: i32,
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 x = Bar { a: 1, b: 2 };
let y = Bar { a: 1, b: 3 };
match x.partial_cmp(&y) {
Option::Some(Ordering::Less) => print("less"),
Option::Some(Ordering::Greater) => print("greater"),
Option::Some(Ordering::Equal) => print("equal"),
_ => print("none"),
}
0
}