I ended up altering the semantics of Json's PartialOrd implementation.
It used to be the case that Null < Null, but I can't think of any reason
for an ordering other than the default one so I just switched it over to
using the derived implementation.
This also fixes broken `PartialOrd` implementations for `Vec` and
`TreeMap`.
RFC: 0028-partial-cmp
use core::intrinsics;
use core::kinds::Send;
use core::mem;
+use core::option::Option;
use core::raw::TraitObject;
use core::result::{Ok, Err, Result};
fn ne(&self, other: &Box<T>) -> bool { *(*self) != *(*other) }
}
impl<T:PartialOrd> PartialOrd for Box<T> {
+ #[inline]
+ fn partial_cmp(&self, other: &Box<T>) -> Option<Ordering> {
+ (**self).partial_cmp(*other)
+ }
#[inline]
fn lt(&self, other: &Box<T>) -> bool { *(*self) < *(*other) }
#[inline]
impl<T: Eq> Eq for Rc<T> {}
impl<T: PartialOrd> PartialOrd for Rc<T> {
+ #[inline(always)]
+ fn partial_cmp(&self, other: &Rc<T>) -> Option<Ordering> {
+ (**self).partial_cmp(&**other)
+ }
+
#[inline(always)]
fn lt(&self, other: &Rc<T>) -> bool { **self < **other }
impl<K: Ord, V: Eq> Eq for BTree<K, V> {}
impl<K: Ord, V: Eq> PartialOrd for BTree<K, V> {
- fn lt(&self, other: &BTree<K, V>) -> bool {
- self.cmp(other) == Less
+ fn partial_cmp(&self, other: &BTree<K, V>) -> Option<Ordering> {
+ Some(self.cmp(other))
}
}
impl<K: Ord, V: Eq> Eq for Node<K, V> {}
impl<K: Ord, V: Eq> PartialOrd for Node<K, V> {
- fn lt(&self, other: &Node<K, V>) -> bool {
- self.cmp(other) == Less
+ fn partial_cmp(&self, other: &Node<K, V>) -> Option<Ordering> {
+ Some(self.cmp(other))
}
}
impl<K: Ord, V: Eq> Eq for Leaf<K, V> {}
impl<K: Ord, V: Eq> PartialOrd for Leaf<K, V> {
- fn lt(&self, other: &Leaf<K, V>) -> bool {
- self.cmp(other) == Less
+ fn partial_cmp(&self, other: &Leaf<K, V>) -> Option<Ordering> {
+ Some(self.cmp(other))
}
}
impl<K: Ord, V: Eq> Eq for Branch<K, V> {}
impl<K: Ord, V: Eq> PartialOrd for Branch<K, V> {
- fn lt(&self, other: &Branch<K, V>) -> bool {
- self.cmp(other) == Less
+ fn partial_cmp(&self, other: &Branch<K, V>) -> Option<Ordering> {
+ Some(self.cmp(other))
}
}
impl<K: Ord, V: Eq> Eq for LeafElt<K, V> {}
impl<K: Ord, V: Eq> PartialOrd for LeafElt<K, V> {
- fn lt(&self, other: &LeafElt<K, V>) -> bool {
- self.cmp(other) == Less
+ fn partial_cmp(&self, other: &LeafElt<K, V>) -> Option<Ordering> {
+ Some(self.cmp(other))
}
}
impl<K: Ord, V: Eq> Eq for BranchElt<K, V>{}
impl<K: Ord, V: Eq> PartialOrd for BranchElt<K, V> {
- fn lt(&self, other: &BranchElt<K, V>) -> bool {
- self.cmp(other) == Less
+ fn partial_cmp(&self, other: &BranchElt<K, V>) -> Option<Ordering> {
+ Some(self.cmp(other))
}
}
}
impl<A: PartialOrd> PartialOrd for DList<A> {
- fn lt(&self, other: &DList<A>) -> bool {
- iter::order::lt(self.iter(), other.iter())
- }
- fn le(&self, other: &DList<A>) -> bool {
- iter::order::le(self.iter(), other.iter())
- }
- fn gt(&self, other: &DList<A>) -> bool {
- iter::order::gt(self.iter(), other.iter())
- }
- fn ge(&self, other: &DList<A>) -> bool {
- iter::order::ge(self.iter(), other.iter())
+ fn partial_cmp(&self, other: &DList<A>) -> Option<Ordering> {
+ iter::order::partial_cmp(self.iter(), other.iter())
}
}
impl<'a> PartialOrd for MaybeOwned<'a> {
#[inline]
- fn lt(&self, other: &MaybeOwned) -> bool {
- self.as_slice().lt(&other.as_slice())
+ fn partial_cmp(&self, other: &MaybeOwned) -> Option<Ordering> {
+ Some(self.cmp(other))
}
}
}
}
-// Lexicographical comparison
-fn lt<K: PartialOrd + Ord, V: PartialOrd>(a: &TreeMap<K, V>,
- b: &TreeMap<K, V>) -> bool {
- // the Zip iterator is as long as the shortest of a and b.
- for ((key_a, value_a), (key_b, value_b)) in a.iter().zip(b.iter()) {
- if *key_a < *key_b { return true; }
- if *key_a > *key_b { return false; }
- if *value_a < *value_b { return true; }
- if *value_a > *value_b { return false; }
- }
-
- a.len() < b.len()
-}
-
-impl<K: PartialOrd + Ord, V: PartialOrd> PartialOrd for TreeMap<K, V> {
+impl<K: Ord, V: PartialOrd> PartialOrd for TreeMap<K, V> {
#[inline]
- fn lt(&self, other: &TreeMap<K, V>) -> bool { lt(self, other) }
+ fn partial_cmp(&self, other: &TreeMap<K, V>) -> Option<Ordering> {
+ iter::order::partial_cmp(self.iter(), other.iter())
+ }
}
impl<K: Ord + Show, V: Show> Show for TreeMap<K, V> {
fn eq(&self, other: &TreeSet<T>) -> bool { self.map == other.map }
}
-impl<T: PartialOrd + Ord> PartialOrd for TreeSet<T> {
+impl<T: Ord> PartialOrd for TreeSet<T> {
#[inline]
- fn lt(&self, other: &TreeSet<T>) -> bool { self.map < other.map }
+ fn partial_cmp(&self, other: &TreeSet<T>) -> Option<Ordering> {
+ self.map.partial_cmp(&other.map)
+ }
}
impl<T: Ord + Show> Show for TreeSet<T> {
impl<T: PartialOrd> PartialOrd for Vec<T> {
#[inline]
- fn lt(&self, other: &Vec<T>) -> bool {
- self.as_slice() < other.as_slice()
+ fn partial_cmp(&self, other: &Vec<T>) -> Option<Ordering> {
+ self.as_slice().partial_cmp(&other.as_slice())
}
}
//! assert!(SketchyNum {num: 25} != SketchyNum {num: 57});
//! ```
+use option::{Option, Some};
+#[cfg(stage0)]
+use option::None;
+
/// Trait for values that can be compared for equality and inequality.
///
/// This trait allows for partial equality, for types that do not have an
impl PartialOrd for Ordering {
#[inline]
- fn lt(&self, other: &Ordering) -> bool { (*self as int) < (*other as int) }
+ fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> {
+ (*self as int).partial_cmp(&(*other as int))
+ }
}
/// Combine orderings, lexically.
/// Trait for values that can be compared for a sort-order.
///
-/// PartialOrd only requires implementation of the `lt` method,
+/// PartialOrd only requires implementation of the `partial_cmp` method,
/// with the others generated from default implementations.
///
/// However it remains possible to implement the others separately for types
/// 5.11).
#[lang="ord"]
pub trait PartialOrd: PartialEq {
+ /// This method returns an ordering between `self` and `other` values
+ /// if one exists.
+ #[cfg(stage0)]
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ match (!self.lt(other), !other.lt(self)) {
+ (false, false) => None,
+ (false, true) => Some(Less),
+ (true, false) => Some(Greater),
+ (true, true) => Some(Equal),
+ }
+ }
+
+ /// This method returns an ordering between `self` and `other` values
+ /// if one exists.
+ #[cfg(not(stage0))]
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering>;
+
/// This method tests less than (for `self` and `other`) and is used by the `<` operator.
- fn lt(&self, other: &Self) -> bool;
+ fn lt(&self, other: &Self) -> bool {
+ match self.partial_cmp(other) {
+ Some(Less) => true,
+ _ => false,
+ }
+ }
/// This method tests less than or equal to (`<=`).
#[inline]
- fn le(&self, other: &Self) -> bool { !other.lt(self) }
+ fn le(&self, other: &Self) -> bool {
+ match self.partial_cmp(other) {
+ Some(Less) | Some(Equal) => true,
+ _ => false,
+ }
+ }
/// This method tests greater than (`>`).
#[inline]
- fn gt(&self, other: &Self) -> bool { other.lt(self) }
+ fn gt(&self, other: &Self) -> bool {
+ match self.partial_cmp(other) {
+ Some(Greater) => true,
+ _ => false,
+ }
+ }
/// This method tests greater than or equal to (`>=`).
#[inline]
- fn ge(&self, other: &Self) -> bool { !self.lt(other) }
+ fn ge(&self, other: &Self) -> bool {
+ match self.partial_cmp(other) {
+ Some(Greater) | Some(Equal) => true,
+ _ => false,
+ }
+ }
}
/// The equivalence relation. Two values may be equivalent even if they are
mod impls {
use cmp::{PartialOrd, Ord, PartialEq, Eq, Ordering,
Less, Greater, Equal};
+ use option::{Option, Some, None};
macro_rules! eq_impl(
($($t:ty)*) => ($(
macro_rules! ord_impl(
($($t:ty)*) => ($(
impl PartialOrd for $t {
+ #[inline]
+ fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
+ match (self <= other, self >= other) {
+ (false, false) => None,
+ (false, true) => Some(Greater),
+ (true, false) => Some(Less),
+ (true, true) => Some(Equal),
+ }
+ }
#[inline]
fn lt(&self, other: &$t) -> bool { (*self) < (*other) }
#[inline]
impl PartialOrd for () {
#[inline]
- fn lt(&self, _other: &()) -> bool { false }
+ fn partial_cmp(&self, _: &()) -> Option<Ordering> {
+ Some(Equal)
+ }
}
impl PartialOrd for bool {
#[inline]
- fn lt(&self, other: &bool) -> bool {
- (*self as u8) < (*other as u8)
+ fn partial_cmp(&self, other: &bool) -> Option<Ordering> {
+ (*self as u8).partial_cmp(&(*other as u8))
}
}
fn ne(&self, other: & &'a T) -> bool { *(*self) != *(*other) }
}
impl<'a, T: PartialOrd> PartialOrd for &'a T {
+ #[inline]
+ fn partial_cmp(&self, other: &&'a T) -> Option<Ordering> {
+ (**self).partial_cmp(*other)
+ }
#[inline]
fn lt(&self, other: & &'a T) -> bool { *(*self) < *(*other) }
#[inline]
fn ne(&self, other: &&'a mut T) -> bool { **self != *(*other) }
}
impl<'a, T: PartialOrd> PartialOrd for &'a mut T {
+ #[inline]
+ fn partial_cmp(&self, other: &&'a mut T) -> Option<Ordering> {
+ (**self).partial_cmp(*other)
+ }
#[inline]
fn lt(&self, other: &&'a mut T) -> bool { **self < **other }
#[inline]
pub mod order {
use cmp;
use cmp::{Eq, Ord, PartialOrd, PartialEq};
- use option::{Some, None};
+ use option::{Option, Some, None};
use super::Iterator;
/// Compare `a` and `b` for equality using `Eq`
}
}
+ /// Order `a` and `b` lexicographically using `PartialOrd`
+ pub fn partial_cmp<A: PartialOrd, T: Iterator<A>, S: Iterator<A>>(mut a: T, mut b: S)
+ -> Option<cmp::Ordering> {
+ loop {
+ match (a.next(), b.next()) {
+ (None, None) => return Some(cmp::Equal),
+ (None, _ ) => return Some(cmp::Less),
+ (_ , None) => return Some(cmp::Greater),
+ (Some(x), Some(y)) => match x.partial_cmp(&y) {
+ Some(cmp::Equal) => (),
+ non_eq => return non_eq,
+ },
+ }
+ }
+ }
+
/// Compare `a` and `b` for equality (Using partial equality, `PartialEq`)
pub fn eq<A: PartialEq, T: Iterator<A>, S: Iterator<A>>(mut a: T, mut b: S) -> bool {
loop {
use iter::{range, Iterator};
use option::{Some, None, Option};
-use cmp::{PartialEq, Eq, PartialOrd, Equiv};
+use cmp::{PartialEq, Eq, PartialOrd, Equiv, Ordering, Less, Equal, Greater};
/// Create a null pointer.
///
// Comparison for pointers
impl<T> PartialOrd for *const T {
+ #[inline]
+ fn partial_cmp(&self, other: &*const T) -> Option<Ordering> {
+ if self < other {
+ Some(Less)
+ } else if self == other {
+ Some(Equal)
+ } else {
+ Some(Greater)
+ }
+ }
+
#[inline]
fn lt(&self, other: &*const T) -> bool { *self < *other }
+
+ #[inline]
+ fn le(&self, other: &*const T) -> bool { *self <= *other }
+
+ #[inline]
+ fn gt(&self, other: &*const T) -> bool { *self > *other }
+
+ #[inline]
+ fn ge(&self, other: &*const T) -> bool { *self >= *other }
}
impl<T> PartialOrd for *mut T {
+ #[inline]
+ fn partial_cmp(&self, other: &*mut T) -> Option<Ordering> {
+ if self < other {
+ Some(Less)
+ } else if self == other {
+ Some(Equal)
+ } else {
+ Some(Greater)
+ }
+ }
+
#[inline]
fn lt(&self, other: &*mut T) -> bool { *self < *other }
+
+ #[inline]
+ fn le(&self, other: &*mut T) -> bool { *self <= *other }
+
+ #[inline]
+ fn gt(&self, other: &*mut T) -> bool { *self > *other }
+
+ #[inline]
+ fn ge(&self, other: &*mut T) -> bool { *self >= *other }
}
use cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering, Equiv};
use iter::order;
use collections::Collection;
+ use option::Option;
impl<'a,T:PartialEq> PartialEq for &'a [T] {
fn eq(&self, other: & &'a [T]) -> bool {
}
impl<'a, T: PartialOrd> PartialOrd for &'a [T] {
+ #[inline]
+ fn partial_cmp(&self, other: &&'a [T]) -> Option<Ordering> {
+ order::partial_cmp(self.iter(), other.iter())
+ }
+ #[inline]
fn lt(&self, other: & &'a [T]) -> bool {
order::lt(self.iter(), other.iter())
}
use cmp::{Ord, Ordering, Less, Equal, Greater, PartialEq, PartialOrd, Equiv, Eq};
use collections::Collection;
use iter::Iterator;
- use option::{Some, None};
+ use option::{Option, Some, None};
use str::{Str, StrSlice, eq_slice};
impl<'a> Ord for &'a str {
impl<'a> PartialOrd for &'a str {
#[inline]
- fn lt(&self, other: & &'a str) -> bool { self.cmp(other) == Less }
+ fn partial_cmp(&self, other: &&'a str) -> Option<Ordering> {
+ Some(self.cmp(other))
+ }
}
impl<'a, S: Str> Equiv<S> for &'a str {
use clone::Clone;
use cmp::*;
use default::Default;
+use option::{Option, Some};
// macro for implementing n-ary tuple functions and operations
macro_rules! tuple_impls {
impl<$($T:Eq),+> Eq for ($($T,)+) {}
impl<$($T:PartialOrd + PartialEq),+> PartialOrd for ($($T,)+) {
+ #[inline]
+ fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
+ lexical_partial_cmp!($(self.$refN(), other.$refN()),+)
+ }
#[inline]
fn lt(&self, other: &($($T,)+)) -> bool {
lexical_ord!(lt, $(self.$refN(), other.$refN()),+)
($rel: ident, $a:expr, $b:expr) => { (*$a) . $rel ($b) };
}
+macro_rules! lexical_partial_cmp {
+ ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
+ match ($a).partial_cmp($b) {
+ Some(Equal) => lexical_partial_cmp!($($rest_a, $rest_b),+),
+ ordering => ordering
+ }
+ };
+ ($a:expr, $b:expr) => { ($a).partial_cmp($b) };
+}
+
macro_rules! lexical_cmp {
($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
match ($a).cmp($b) {
}
impl PartialOrd for Foo {
- fn lt(&self, _: &Foo) -> bool {
- false
+ fn partial_cmp(&self, _: &Foo) -> Option<Ordering> {
+ None
}
}
impl<'a, T: Eq> Eq for MaybeOwnedVector<'a, T> {}
impl<'a, T: PartialOrd> PartialOrd for MaybeOwnedVector<'a, T> {
- fn lt(&self, other: &MaybeOwnedVector<T>) -> bool {
- self.as_slice().lt(&other.as_slice())
+ fn partial_cmp(&self, other: &MaybeOwnedVector<T>) -> Option<Ordering> {
+ self.as_slice().partial_cmp(&other.as_slice())
}
}
impl PartialOrd for BigUint {
#[inline]
- fn lt(&self, other: &BigUint) -> bool {
- self.cmp(other) == Less
+ fn partial_cmp(&self, other: &BigUint) -> Option<Ordering> {
+ Some(self.cmp(other))
}
}
impl PartialOrd for BigInt {
#[inline]
- fn lt(&self, other: &BigInt) -> bool {
- self.cmp(other) == Less
+ fn partial_cmp(&self, other: &BigInt) -> Option<Ordering> {
+ Some(self.cmp(other))
}
}
};
}
cmp_impl!(impl PartialEq, eq, ne)
-cmp_impl!(impl PartialOrd, lt, gt, le, ge)
+cmp_impl!(impl PartialOrd, lt -> bool, gt -> bool, le -> bool, ge -> bool,
+ partial_cmp -> Option<cmp::Ordering>)
cmp_impl!(impl Eq, )
cmp_impl!(impl Ord, cmp -> cmp::Ordering)
impl cmp::PartialOrd for Identifier {
#[inline]
- fn lt(&self, other: &Identifier) -> bool {
+ fn partial_cmp(&self, other: &Identifier) -> Option<Ordering> {
match (self, other) {
- (&Numeric(a), &Numeric(b)) => a < b,
- (&Numeric(_), _) => true,
- (&AlphaNumeric(ref a), &AlphaNumeric(ref b)) => *a < *b,
- (&AlphaNumeric(_), _) => false
+ (&Numeric(a), &Numeric(ref b)) => a.partial_cmp(b),
+ (&Numeric(_), _) => Some(Less),
+ (&AlphaNumeric(ref a), &AlphaNumeric(ref b)) => a.partial_cmp(b),
+ (&AlphaNumeric(_), _) => Some(Greater)
}
}
}
impl cmp::PartialOrd for Version {
#[inline]
- fn lt(&self, other: &Version) -> bool {
-
- self.major < other.major ||
-
- (self.major == other.major &&
- self.minor < other.minor) ||
-
- (self.major == other.major &&
- self.minor == other.minor &&
- self.patch < other.patch) ||
-
- (self.major == other.major &&
- self.minor == other.minor &&
- self.patch == other.patch &&
- // NB: semver spec says 0.0.0-pre < 0.0.0
- // but the version of ord defined for vec
- // says that [] < [pre], so we alter it
- // here.
- (match (self.pre.len(), other.pre.len()) {
- (0, 0) => false,
- (0, _) => false,
- (_, 0) => true,
- (_, _) => self.pre < other.pre
- }))
+ fn partial_cmp(&self, other: &Version) -> Option<Ordering> {
+ match self.major.partial_cmp(&other.major) {
+ Some(Equal) => {}
+ r => return r,
+ }
+
+ match self.minor.partial_cmp(&other.minor) {
+ Some(Equal) => {}
+ r => return r,
+ }
+
+ match self.patch.partial_cmp(&other.patch) {
+ Some(Equal) => {}
+ r => return r,
+ }
+
+ // NB: semver spec says 0.0.0-pre < 0.0.0
+ // but the version of ord defined for vec
+ // says that [] < [pre] so we alter it here
+ match (self.pre.len(), other.pre.len()) {
+ (0, 0) => Some(Equal),
+ (0, _) => Some(Greater),
+ (_, 0) => Some(Less),
+ (_, _) => self.pre.partial_cmp(&other.pre)
+ }
}
}
use Encodable;
/// Represents a json value
-#[deriving(Clone, PartialEq)]
+#[deriving(Clone, PartialEq, PartialOrd)]
pub enum Json {
Number(f64),
String(String),
}
}
-/// Test if two json values are less than one another
-impl PartialOrd for Json {
- fn lt(&self, other: &Json) -> bool {
- match *self {
- Number(f0) => {
- match *other {
- Number(f1) => f0 < f1,
- String(_) | Boolean(_) | List(_) | Object(_) |
- Null => true
- }
- }
-
- String(ref s0) => {
- match *other {
- Number(_) => false,
- String(ref s1) => s0 < s1,
- Boolean(_) | List(_) | Object(_) | Null => true
- }
- }
-
- Boolean(b0) => {
- match *other {
- Number(_) | String(_) => false,
- Boolean(b1) => b0 < b1,
- List(_) | Object(_) | Null => true
- }
- }
-
- List(ref l0) => {
- match *other {
- Number(_) | String(_) | Boolean(_) => false,
- List(ref l1) => (*l0) < (*l1),
- Object(_) | Null => true
- }
- }
-
- Object(ref d0) => {
- match *other {
- Number(_) | String(_) | Boolean(_) | List(_) => false,
- Object(ref d1) => d0 < d1,
- Null => true
- }
- }
-
- Null => {
- match *other {
- Number(_) | String(_) | Boolean(_) | List(_) |
- Object(_) =>
- false,
- Null => true
- }
- }
- }
- }
-}
-
/// A trait for converting values to JSON
pub trait ToJson {
/// Converts the value of `self` to an instance of JSON
use fmt;
use hash;
use kinds::marker;
+use option::Option;
use ops::Deref;
use raw;
fn ne(&self, other: &Gc<T>) -> bool { *(*self) != *(*other) }
}
impl<T: PartialOrd + 'static> PartialOrd for Gc<T> {
+ #[inline]
+ fn partial_cmp(&self, other: &Gc<T>) -> Option<Ordering> {
+ (**self).partial_cmp(&**other)
+ }
#[inline]
fn lt(&self, other: &Gc<T>) -> bool { *(*self) < *(*other) }
#[inline]
} }
);
+ let ordering_ty = Literal(Path::new(vec!["std", "cmp", "Ordering"]));
+ let ret_ty = Literal(Path::new_(vec!["std", "option", "Option"],
+ None,
+ vec![box ordering_ty],
+ true));
+
+ let inline = cx.meta_word(span, InternedString::new("inline"));
+ let attrs = vec!(cx.attribute(span, inline));
+
+ let partial_cmp_def = MethodDef {
+ name: "partial_cmp",
+ generics: LifetimeBounds::empty(),
+ explicit_self: borrowed_explicit_self(),
+ args: vec![borrowed_self()],
+ ret_ty: ret_ty,
+ attributes: attrs,
+ const_nonmatching: false,
+ combine_substructure: combine_substructure(|cx, span, substr| {
+ cs_partial_cmp(cx, span, substr)
+ })
+ };
+
let trait_def = TraitDef {
span: span,
- attributes: Vec::new(),
- path: Path::new(vec!("std", "cmp", "PartialOrd")),
- additional_bounds: Vec::new(),
+ attributes: vec![],
+ path: Path::new(vec!["std", "cmp", "PartialOrd"]),
+ additional_bounds: vec![],
generics: LifetimeBounds::empty(),
- methods: vec!(
+ methods: vec![
+ partial_cmp_def,
md!("lt", true, false),
md!("le", true, true),
md!("gt", false, false),
md!("ge", false, true)
- )
+ ]
};
trait_def.expand(cx, mitem, item, push)
}
+pub fn some_ordering_const(cx: &mut ExtCtxt, span: Span, cnst: Ordering) -> Gc<ast::Expr> {
+ let cnst = match cnst {
+ Less => "Less",
+ Equal => "Equal",
+ Greater => "Greater"
+ };
+ let ordering = cx.path_global(span,
+ vec!(cx.ident_of("std"),
+ cx.ident_of("cmp"),
+ cx.ident_of(cnst)));
+ let ordering = cx.expr_path(ordering);
+ cx.expr_some(span, ordering)
+}
+
+pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span,
+ substr: &Substructure) -> Gc<Expr> {
+ let test_id = cx.ident_of("__test");
+ let equals_expr = some_ordering_const(cx, span, Equal);
+
+ /*
+ Builds:
+
+ let __test = self_field1.partial_cmp(&other_field2);
+ if __test == ::std::option::Some(::std::cmp::Equal) {
+ let __test = self_field2.partial_cmp(&other_field2);
+ if __test == ::std::option::Some(::std::cmp::Equal) {
+ ...
+ } else {
+ __test
+ }
+ } else {
+ __test
+ }
+
+ FIXME #6449: These `if`s could/should be `match`es.
+ */
+ cs_same_method_fold(
+ // foldr nests the if-elses correctly, leaving the first field
+ // as the outermost one, and the last as the innermost.
+ false,
+ |cx, span, old, new| {
+ // let __test = new;
+ // if __test == Some(::std::cmp::Equal) {
+ // old
+ // } else {
+ // __test
+ // }
+
+ let assign = cx.stmt_let(span, false, test_id, new);
+
+ let cond = cx.expr_binary(span, ast::BiEq,
+ cx.expr_ident(span, test_id),
+ equals_expr.clone());
+ let if_ = cx.expr_if(span,
+ cond,
+ old, Some(cx.expr_ident(span, test_id)));
+ cx.expr_block(cx.block(span, vec!(assign), Some(if_)))
+ },
+ equals_expr.clone(),
+ |cx, span, list, _| {
+ match list {
+ // an earlier nonmatching variant is Less than a
+ // later one.
+ [(self_var, _, _), (other_var, _, _)] =>
+ some_ordering_const(cx, span, self_var.cmp(&other_var)),
+ _ => cx.span_bug(span, "not exactly 2 arguments in `deriving(Ord)`")
+ }
+ },
+ cx, span, substr)
+}
+
/// Strict inequality.
fn cs_op(less: bool, equal: bool, cx: &mut ExtCtxt, span: Span,
substr: &Substructure) -> Gc<Expr> {
//~^^^^^ ERROR
//~^^^^^^ ERROR
//~^^^^^^^ ERROR
+//~^^^^^^^^ ERROR
}
}
//~^^^^^ ERROR
//~^^^^^^ ERROR
//~^^^^^^^ ERROR
+//~^^^^^^^^ ERROR
)
}
//~^^^^^ ERROR
//~^^^^^^ ERROR
//~^^^^^^^ ERROR
+//~^^^^^^^^ ERROR
}
fn main() {}
//~^^^^^ ERROR
//~^^^^^^ ERROR
//~^^^^^^^ ERROR
+//~^^^^^^^^ ERROR
);
fn main() {}
#[deriving(PartialEq)]
struct thing(uint);
-impl PartialOrd for thing { //~ ERROR not all trait methods implemented, missing: `lt`
+impl PartialOrd for thing { //~ ERROR not all trait methods implemented, missing: `partial_cmp`
fn le(&self, other: &thing) -> bool { true }
fn ge(&self, other: &thing) -> bool { true }
}
}
impl PartialOrd for Int {
- fn lt(&self, other: &Int) -> bool {
+ fn partial_cmp(&self, other: &Int) -> Option<Ordering> {
let Int(this) = *self;
let Int(other) = *other;
- this < other
+ this.partial_cmp(&other)
}
}
}
impl PartialOrd for RevInt {
- fn lt(&self, other: &RevInt) -> bool {
+ fn partial_cmp(&self, other: &RevInt) -> Option<Ordering> {
let RevInt(this) = *self;
let RevInt(other) = *other;
- this > other
+ other.partial_cmp(&this)
}
}
}
impl PartialOrd for FailCmp {
- fn lt(&self, _: &FailCmp) -> bool { fail!("lt") }
+ fn partial_cmp(&self, _: &FailCmp) -> Option<Ordering> { fail!("partial_cmp") }
}
impl Eq for FailCmp {}