});
}
+ // TODO: Replace with `reconstruct()` instead of building these twice
+ auto self_variant_path = builder.variant_path (enum_path, variant_path);
+ auto other_variant_path = builder.variant_path (enum_path, variant_path);
+
auto self_pattern_items = std::unique_ptr<TupleStructItems> (
new TupleStructItemsNoRange (std::move (self_patterns)));
auto other_pattern_items = std::unique_ptr<TupleStructItems> (
auto self_pattern = std::unique_ptr<Pattern> (
new ReferencePattern (std::unique_ptr<Pattern> (new TupleStructPattern (
- variant_path, std::move (self_pattern_items))),
- false, false, builder.loc));
- auto other_pattern = std::unique_ptr<Pattern> (
- new ReferencePattern (std::unique_ptr<Pattern> (new TupleStructPattern (
- variant_path, std::move (other_pattern_items))),
+ self_variant_path, std::move (self_pattern_items))),
false, false, builder.loc));
+ auto other_pattern = std::unique_ptr<Pattern> (new ReferencePattern (
+ std::unique_ptr<Pattern> (new TupleStructPattern (
+ other_variant_path, std::move (other_pattern_items))),
+ false, false, builder.loc));
auto tuple_items = std::make_unique<TuplePatternItemsMultiple> (
vec (std::move (self_pattern), std::move (other_pattern)));
});
}
+ // TODO: Replace with `reconstruct()` instead of building these twice
+ auto self_variant_path = builder.variant_path (enum_path, variant_path);
+ auto other_variant_path = builder.variant_path (enum_path, variant_path);
+
auto self_elts = StructPatternElements (std::move (self_fields));
auto other_elts = StructPatternElements (std::move (other_fields));
- auto self_pattern = std::unique_ptr<Pattern> (
- new ReferencePattern (std::unique_ptr<Pattern> (new StructPattern (
- variant_path, builder.loc, std::move (self_elts))),
- false, false, builder.loc));
+ auto self_pattern = std::unique_ptr<Pattern> (new ReferencePattern (
+ std::unique_ptr<Pattern> (new StructPattern (self_variant_path, builder.loc,
+ std::move (self_elts))),
+ false, false, builder.loc));
auto other_pattern = std::unique_ptr<Pattern> (
- new ReferencePattern (std::unique_ptr<Pattern> (new StructPattern (
- variant_path, builder.loc, std::move (other_elts))),
+ new ReferencePattern (std::unique_ptr<Pattern> (
+ new StructPattern (other_variant_path, builder.loc,
+ std::move (other_elts))),
false, false, builder.loc));
auto tuple_items = std::make_unique<TuplePatternItemsMultiple> (
--- /dev/null
+// { dg-additional-options "-frust-compile-until=typecheck" }
+
+#![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;
+
+// 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 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(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() {
+ let a = Foo::A;
+ let b = Foo::B(15, 14, 13);
+
+ match a.partial_cmp(&b) {
+ Option::Some(Ordering::Less) => print("less"),
+ Option::Some(Ordering::Greater) => print("greater"),
+ Option::Some(Ordering::Equal) => print("equal"),
+ _ => print("uuuuh woops lol"),
+ }
+}