From 88ed2d1c41a0a80c98cb84be076e6447eeed3f36 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 29 Oct 2014 18:31:41 -0500 Subject: [PATCH 1/7] Use operator sugar in the expansion of `#[deriving(PartialEq)]` --- src/libsyntax/ext/deriving/cmp/eq.rs | 36 ++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/src/libsyntax/ext/deriving/cmp/eq.rs b/src/libsyntax/ext/deriving/cmp/eq.rs index a27016fde6156..c3b1a52925d45 100644 --- a/src/libsyntax/ext/deriving/cmp/eq.rs +++ b/src/libsyntax/ext/deriving/cmp/eq.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use ast::{MetaItem, Item, Expr}; +use ast::{MetaItem, Item, Expr, mod}; use codemap::Span; use ext::base::ExtCtxt; use ext::build::AstBuilder; @@ -25,12 +25,38 @@ pub fn expand_deriving_eq(cx: &mut ExtCtxt, // structures are equal if all fields are equal, and non equal, if // any fields are not equal or if the enum variants are different fn cs_eq(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P { - cs_and(|cx, span, _, _| cx.expr_bool(span, false), - cx, span, substr) + cs_fold( + true, // use foldl + |cx, span, subexpr, self_f, other_fs| { + let other_f = match other_fs { + [ref o_f] => o_f, + _ => cx.span_bug(span, "not exactly 2 arguments in `deriving(Eq)`") + }; + + let eq = cx.expr_binary(span, ast::BiEq, self_f, other_f.clone()); + + cx.expr_binary(span, ast::BiAnd, subexpr, eq) + }, + cx.expr_bool(span, true), + |cx, span, _, _| cx.expr_bool(span, false), + cx, span, substr) } fn cs_ne(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P { - cs_or(|cx, span, _, _| cx.expr_bool(span, true), - cx, span, substr) + cs_fold( + true, // use foldl + |cx, span, subexpr, self_f, other_fs| { + let other_f = match other_fs { + [ref o_f] => o_f, + _ => cx.span_bug(span, "not exactly 2 arguments in `deriving(Eq)`") + }; + + let eq = cx.expr_binary(span, ast::BiNe, self_f, other_f.clone()); + + cx.expr_binary(span, ast::BiOr, subexpr, eq) + }, + cx.expr_bool(span, false), + |cx, span, _, _| cx.expr_bool(span, true), + cx, span, substr) } macro_rules! md ( From 1a943754262a621fb06db4de7ca657a225706531 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 29 Oct 2014 18:48:20 -0500 Subject: [PATCH 2/7] Fix fallout of changing the expansion of `#[deriving(PartialEq)]` --- src/libcore/option.rs | 2 +- src/libcore/result.rs | 1 - src/libcore/str.rs | 3 +-- src/libgetopts/lib.rs | 1 - 4 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/libcore/option.rs b/src/libcore/option.rs index b787de4423aac..2964a6b68534e 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -143,7 +143,7 @@ #![stable] -use cmp::{PartialEq, Eq, Ord}; +use cmp::{Eq, Ord}; use default::Default; use iter::{Iterator, DoubleEndedIterator, FromIterator, ExactSize}; use mem; diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 2ad5521bb76cd..c4cb298724153 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -276,7 +276,6 @@ #![stable] -use cmp::PartialEq; use std::fmt::Show; use slice; use slice::AsSlice; diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 8937f2a946a85..10c0f68dd5d88 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -19,8 +19,7 @@ use mem; use char; use char::Char; -use cmp; -use cmp::{PartialEq, Eq}; +use cmp::{Eq, mod}; use default::Default; use iter::{Map, Iterator}; use iter::{DoubleEndedIterator, ExactSize}; diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs index a8a91283a1128..d60835dff1745 100644 --- a/src/libgetopts/lib.rs +++ b/src/libgetopts/lib.rs @@ -93,7 +93,6 @@ #[cfg(test)] #[phase(plugin, link)] extern crate log; -use std::cmp::PartialEq; use std::fmt; use std::result::{Err, Ok}; use std::result; From 2896278313ede1b24b47c88bafe684adabbc92d4 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 29 Oct 2014 20:11:16 -0500 Subject: [PATCH 3/7] DSTify PartialEq, PartialOrd, Eq, Ord --- src/libcore/cmp.rs | 222 +++++++++++++++++++++++++++++++++++++++++++ src/libcore/slice.rs | 62 ++++++++++++ src/libcore/str.rs | 45 +++++++++ 3 files changed, 329 insertions(+) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index d7c2b52b8dea4..6e87fe4ced02d 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -55,6 +55,8 @@ use option::{Option, Some, None}; /// /// Eventually, this will be implemented by default for types that implement /// `Eq`. +// NOTE(stage0): remove trait after a snapshot +#[cfg(stage0)] #[lang="eq"] #[unstable = "Definition may change slightly after trait reform"] pub trait PartialEq { @@ -66,6 +68,31 @@ pub trait PartialEq { fn ne(&self, other: &Self) -> bool { !self.eq(other) } } +/// Trait for values that can be compared for equality and inequality. +/// +/// This trait allows for partial equality, for types that do not have an +/// equivalence relation. For example, in floating point numbers `NaN != NaN`, +/// so floating point types implement `PartialEq` but not `Eq`. +/// +/// PartialEq only requires the `eq` method to be implemented; `ne` is defined +/// in terms of it by default. Any manual implementation of `ne` *must* respect +/// the rule that `eq` is a strict inverse of `ne`; that is, `!(a == b)` if and +/// only if `a != b`. +/// +/// Eventually, this will be implemented by default for types that implement +/// `Eq`. +#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot +#[lang="eq"] +#[unstable = "Definition may change slightly after trait reform"] +pub trait PartialEq for Sized? { + /// This method tests for `self` and `other` values to be equal, and is used by `==`. + fn eq(&self, other: &Self) -> bool; + + /// This method tests for `!=`. + #[inline] + fn ne(&self, other: &Self) -> bool { !self.eq(other) } +} + /// Trait for equality comparisons which are [equivalence relations]( /// https://en.wikipedia.org/wiki/Equivalence_relation). /// @@ -75,6 +102,8 @@ pub trait PartialEq { /// - reflexive: `a == a`; /// - symmetric: `a == b` implies `b == a`; and /// - transitive: `a == b` and `b == c` implies `a == c`. +// NOTE(stage0): remove trait after a snapshot +#[cfg(stage0)] #[unstable = "Definition may change slightly after trait reform"] pub trait Eq: PartialEq { // FIXME #13101: this method is used solely by #[deriving] to @@ -89,6 +118,30 @@ pub trait Eq: PartialEq { fn assert_receiver_is_total_eq(&self) {} } +/// Trait for equality comparisons which are [equivalence relations]( +/// https://en.wikipedia.org/wiki/Equivalence_relation). +/// +/// This means, that in addition to `a == b` and `a != b` being strict +/// inverses, the equality must be (for all `a`, `b` and `c`): +/// +/// - reflexive: `a == a`; +/// - symmetric: `a == b` implies `b == a`; and +/// - transitive: `a == b` and `b == c` implies `a == c`. +#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot +#[unstable = "Definition may change slightly after trait reform"] +pub trait Eq for Sized?: PartialEq { + // FIXME #13101: 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)] + #[inline(always)] + fn assert_receiver_is_total_eq(&self) {} +} + /// An ordering is, e.g, a result of a comparison between two values. #[deriving(Clone, PartialEq, Show)] #[stable] @@ -145,6 +198,8 @@ impl Ordering { /// true; and /// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for /// both `==` and `>`. +// NOTE(stage0): remove trait after a snapshot +#[cfg(stage0)] #[unstable = "Definition may change slightly after trait reform"] pub trait Ord: Eq + PartialOrd { /// This method returns an ordering between `self` and `other` values. @@ -160,6 +215,31 @@ pub trait Ord: Eq + PartialOrd { fn cmp(&self, other: &Self) -> Ordering; } +/// Trait for types that form a [total order]( +/// https://en.wikipedia.org/wiki/Total_order). +/// +/// An order is a total order if it is (for all `a`, `b` and `c`): +/// +/// - total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is +/// true; and +/// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for +/// both `==` and `>`. +#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot +#[unstable = "Definition may change slightly after trait reform"] +pub trait Ord for Sized?: Eq + PartialOrd { + /// This method returns an ordering between `self` and `other` values. + /// + /// By convention, `self.cmp(&other)` returns the ordering matching + /// the expression `self other` if true. For example: + /// + /// ``` + /// assert_eq!( 5u.cmp(&10), Less); // because 5 < 10 + /// assert_eq!(10u.cmp(&5), Greater); // because 10 > 5 + /// assert_eq!( 5u.cmp(&5), Equal); // because 5 == 5 + /// ``` + fn cmp(&self, other: &Self) -> Ordering; +} + #[unstable = "Trait is unstable."] impl Eq for Ordering {} @@ -188,6 +268,8 @@ impl PartialOrd for Ordering { /// which do not have a total order. For example, for floating point numbers, /// `NaN < 0 == false` and `NaN >= 0 == false` (cf. IEEE 754-2008 section /// 5.11). +// NOTE(stage0): remove trait after a snapshot +#[cfg(stage0)] #[lang="ord"] #[unstable = "Definition may change slightly after trait reform"] pub trait PartialOrd: PartialEq { @@ -232,6 +314,60 @@ pub trait PartialOrd: PartialEq { } } +/// Trait for values that can be compared for a sort-order. +/// +/// 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 +/// which do not have a total order. For example, for floating point numbers, +/// `NaN < 0 == false` and `NaN >= 0 == false` (cf. IEEE 754-2008 section +/// 5.11). +#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot +#[lang="ord"] +#[unstable = "Definition may change slightly after trait reform"] +pub trait PartialOrd for Sized?: PartialEq { + /// This method returns an ordering between `self` and `other` values + /// if one exists. + fn partial_cmp(&self, other: &Self) -> Option; + + /// This method tests less than (for `self` and `other`) and is used by the `<` operator. + #[inline] + 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 { + match self.partial_cmp(other) { + Some(Less) | Some(Equal) => true, + _ => false, + } + } + + /// This method tests greater than (`>`). + #[inline] + 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 { + match self.partial_cmp(other) { + Some(Greater) | Some(Equal) => true, + _ => false, + } + } +} + /// The equivalence relation. Two values may be equivalent even if they are /// of different types. The most common use case for this relation is /// container types; e.g. it is often desirable to be able to use `&str` @@ -286,6 +422,8 @@ pub fn partial_max(v1: T, v2: T) -> Option { mod impls { use cmp::{PartialOrd, Ord, PartialEq, Eq, Ordering, Less, Greater, Equal}; + #[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot + use kinds::Sized; use option::{Option, Some, None}; macro_rules! partial_eq_impl( @@ -393,6 +531,8 @@ mod impls { ord_impl!(char uint u8 u16 u32 u64 int i8 i16 i32 i64) // & pointers + // NOTE(stage0): remove impl after a snapshot + #[cfg(stage0)] #[unstable = "Trait is unstable."] impl<'a, T: PartialEq> PartialEq for &'a T { #[inline] @@ -400,6 +540,8 @@ mod impls { #[inline] fn ne(&self, other: & &'a T) -> bool { *(*self) != *(*other) } } + // NOTE(stage0): remove impl after a snapshot + #[cfg(stage0)] #[unstable = "Trait is unstable."] impl<'a, T: PartialOrd> PartialOrd for &'a T { #[inline] @@ -415,15 +557,55 @@ mod impls { #[inline] fn gt(&self, other: & &'a T) -> bool { *(*self) > *(*other) } } + // NOTE(stage0): remove impl after a snapshot + #[cfg(stage0)] #[unstable = "Trait is unstable."] impl<'a, T: Ord> Ord for &'a T { #[inline] fn cmp(&self, other: & &'a T) -> Ordering { (**self).cmp(*other) } } + // NOTE(stage0): remove impl after a snapshot + #[cfg(stage0)] #[unstable = "Trait is unstable."] impl<'a, T: Eq> Eq for &'a T {} + #[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot + #[unstable = "Trait is unstable."] + impl<'a, Sized? T: PartialEq> PartialEq for &'a T { + #[inline] + fn eq(&self, other: & &'a T) -> bool { PartialEq::eq(*self, *other) } + #[inline] + fn ne(&self, other: & &'a T) -> bool { PartialEq::ne(*self, *other) } + } + #[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot + #[unstable = "Trait is unstable."] + impl<'a, Sized? T: PartialOrd> PartialOrd for &'a T { + #[inline] + fn partial_cmp(&self, other: &&'a T) -> Option { + PartialOrd::partial_cmp(*self, *other) + } + #[inline] + fn lt(&self, other: & &'a T) -> bool { PartialOrd::lt(*self, *other) } + #[inline] + fn le(&self, other: & &'a T) -> bool { PartialOrd::le(*self, *other) } + #[inline] + fn ge(&self, other: & &'a T) -> bool { PartialOrd::ge(*self, *other) } + #[inline] + fn gt(&self, other: & &'a T) -> bool { PartialOrd::gt(*self, *other) } + } + #[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot + #[unstable = "Trait is unstable."] + impl<'a, Sized? T: Ord> Ord for &'a T { + #[inline] + fn cmp(&self, other: & &'a T) -> Ordering { Ord::cmp(*self, *other) } + } + #[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot + #[unstable = "Trait is unstable."] + impl<'a, Sized? T: Eq> Eq for &'a T {} + // &mut pointers + // NOTE(stage0): remove impl after a snapshot + #[cfg(stage0)] #[unstable = "Trait is unstable."] impl<'a, T: PartialEq> PartialEq for &'a mut T { #[inline] @@ -431,6 +613,8 @@ mod impls { #[inline] fn ne(&self, other: &&'a mut T) -> bool { **self != *(*other) } } + // NOTE(stage0): remove impl after a snapshot + #[cfg(stage0)] #[unstable = "Trait is unstable."] impl<'a, T: PartialOrd> PartialOrd for &'a mut T { #[inline] @@ -446,11 +630,49 @@ mod impls { #[inline] fn gt(&self, other: &&'a mut T) -> bool { **self > **other } } + // NOTE(stage0): remove impl after a snapshot + #[cfg(stage0)] #[unstable = "Trait is unstable."] impl<'a, T: Ord> Ord for &'a mut T { #[inline] fn cmp(&self, other: &&'a mut T) -> Ordering { (**self).cmp(*other) } } + // NOTE(stage0): remove impl after a snapshot + #[cfg(stage0)] #[unstable = "Trait is unstable."] impl<'a, T: Eq> Eq for &'a mut T {} + + #[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot + #[unstable = "Trait is unstable."] + impl<'a, Sized? T: PartialEq> PartialEq for &'a mut T { + #[inline] + fn eq(&self, other: &&'a mut T) -> bool { PartialEq::eq(*self, *other) } + #[inline] + fn ne(&self, other: &&'a mut T) -> bool { PartialEq::ne(*self, *other) } + } + #[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot + #[unstable = "Trait is unstable."] + impl<'a, Sized? T: PartialOrd> PartialOrd for &'a mut T { + #[inline] + fn partial_cmp(&self, other: &&'a mut T) -> Option { + PartialOrd::partial_cmp(*self, *other) + } + #[inline] + fn lt(&self, other: &&'a mut T) -> bool { PartialOrd::lt(*self, *other) } + #[inline] + fn le(&self, other: &&'a mut T) -> bool { PartialOrd::le(*self, *other) } + #[inline] + fn ge(&self, other: &&'a mut T) -> bool { PartialOrd::ge(*self, *other) } + #[inline] + fn gt(&self, other: &&'a mut T) -> bool { PartialOrd::gt(*self, *other) } + } + #[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot + #[unstable = "Trait is unstable."] + impl<'a, Sized? T: Ord> Ord for &'a mut T { + #[inline] + fn cmp(&self, other: &&'a mut T) -> Ordering { Ord::cmp(*self, *other) } + } + #[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot + #[unstable = "Trait is unstable."] + impl<'a, Sized? T: Eq> Eq for &'a mut T {} } diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 317a6e224bce9..3cc904162a134 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -1555,6 +1555,8 @@ pub mod bytes { // Boilerplate traits // +// NOTE(stage0): remove impl after a snapshot +#[cfg(stage0)] #[unstable = "waiting for DST"] impl<'a,T:PartialEq> PartialEq for &'a [T] { fn eq(&self, other: & &'a [T]) -> bool { @@ -1567,15 +1569,36 @@ impl<'a,T:PartialEq> PartialEq for &'a [T] { } } +#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot +#[unstable = "waiting for DST"] +impl PartialEq for [T] { + fn eq(&self, other: &[T]) -> bool { + self.len() == other.len() && + order::eq(self.iter(), other.iter()) + } + fn ne(&self, other: &[T]) -> bool { + self.len() != other.len() || + order::ne(self.iter(), other.iter()) + } +} + +// NOTE(stage0): remove impl after a snapshot +#[cfg(stage0)] #[unstable = "waiting for DST"] impl<'a,T:Eq> Eq for &'a [T] {} +#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot +#[unstable = "waiting for DST"] +impl Eq for [T] {} + #[unstable = "waiting for DST"] impl> Equiv for [T] { #[inline] fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() } } +// NOTE(stage0): remove impl after a snapshot +#[cfg(stage0)] #[unstable = "waiting for DST"] impl<'a,T:PartialEq> PartialEq for &'a mut [T] { fn eq(&self, other: & &'a mut [T]) -> bool { @@ -1588,6 +1611,8 @@ impl<'a,T:PartialEq> PartialEq for &'a mut [T] { } } +// NOTE(stage0): remove impl after a snapshot +#[cfg(stage0)] #[unstable = "waiting for DST"] impl<'a,T:Eq> Eq for &'a mut [T] {} @@ -1597,6 +1622,8 @@ impl<'a,T:PartialEq, V: AsSlice> Equiv for &'a mut [T] { fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() } } +// NOTE(stage0): remove impl after a snapshot +#[cfg(stage0)] #[unstable = "waiting for DST"] impl<'a,T:Ord> Ord for &'a [T] { fn cmp(&self, other: & &'a [T]) -> Ordering { @@ -1604,6 +1631,16 @@ impl<'a,T:Ord> Ord for &'a [T] { } } +#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot +#[unstable = "waiting for DST"] +impl Ord for [T] { + fn cmp(&self, other: &[T]) -> Ordering { + order::cmp(self.iter(), other.iter()) + } +} + +// NOTE(stage0): remove impl after a snapshot +#[cfg(stage0)] #[unstable = "waiting for DST"] impl<'a, T: PartialOrd> PartialOrd for &'a [T] { #[inline] @@ -1628,6 +1665,31 @@ impl<'a, T: PartialOrd> PartialOrd for &'a [T] { } } +#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot +#[unstable = "waiting for DST"] +impl PartialOrd for [T] { + #[inline] + fn partial_cmp(&self, other: &[T]) -> Option { + order::partial_cmp(self.iter(), other.iter()) + } + #[inline] + fn lt(&self, other: &[T]) -> bool { + order::lt(self.iter(), other.iter()) + } + #[inline] + fn le(&self, other: &[T]) -> bool { + order::le(self.iter(), other.iter()) + } + #[inline] + fn ge(&self, other: &[T]) -> bool { + order::ge(self.iter(), other.iter()) + } + #[inline] + fn gt(&self, other: &[T]) -> bool { + order::gt(self.iter(), other.iter()) + } +} + /// Extension methods for immutable slices containing integers. #[experimental] pub trait ImmutableIntSlice for Sized? { diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 10c0f68dd5d88..175f9f3f5771c 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -1122,6 +1122,8 @@ pub mod traits { use ops; use str::{Str, StrSlice, eq_slice}; + // NOTE(stage0): remove impl after a snapshot + #[cfg(stage0)] impl<'a> Ord for &'a str { #[inline] fn cmp(&self, other: & &'a str) -> Ordering { @@ -1137,6 +1139,24 @@ pub mod traits { } } + #[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot + impl Ord for str { + #[inline] + fn cmp(&self, other: &str) -> Ordering { + for (s_b, o_b) in self.bytes().zip(other.bytes()) { + match s_b.cmp(&o_b) { + Greater => return Greater, + Less => return Less, + Equal => () + } + } + + self.len().cmp(&other.len()) + } + } + + // NOTE(stage0): remove impl after a snapshot + #[cfg(stage0)] impl<'a> PartialEq for &'a str { #[inline] fn eq(&self, other: & &'a str) -> bool { @@ -1146,8 +1166,25 @@ pub mod traits { fn ne(&self, other: & &'a str) -> bool { !(*self).eq(other) } } + #[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot + impl PartialEq for str { + #[inline] + fn eq(&self, other: &str) -> bool { + eq_slice(self, other) + } + #[inline] + fn ne(&self, other: &str) -> bool { !(*self).eq(other) } + } + + // NOTE(stage0): remove impl after a snapshot + #[cfg(stage0)] impl<'a> Eq for &'a str {} + #[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot + impl Eq for str {} + + // NOTE(stage0): remove impl after a snapshot + #[cfg(stage0)] impl<'a> PartialOrd for &'a str { #[inline] fn partial_cmp(&self, other: &&'a str) -> Option { @@ -1155,6 +1192,14 @@ pub mod traits { } } + #[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot + impl PartialOrd for str { + #[inline] + fn partial_cmp(&self, other: &str) -> Option { + Some(self.cmp(other)) + } + } + impl Equiv for str { #[inline] fn equiv(&self, other: &S) -> bool { eq_slice(self, other.as_slice()) } From 1e5f311d1615ab4bca5b23d09dd678c2662022e6 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Wed, 29 Oct 2014 20:21:37 -0500 Subject: [PATCH 4/7] Fix fallout of DSTifying PartialEq, PartialOrd, Eq, Ord --- src/libcollections/str.rs | 7 +++++ src/libcollections/vec.rs | 14 +++++++++ src/libgraphviz/maybe_owned_vec.rs | 12 +++++++ src/libregex/parse.rs | 10 ++++++ src/librustc/driver/mod.rs | 28 +++++++++++++++++ src/librustrt/c_str.rs | 7 +++++ src/libserialize/json.rs | 38 +++++++++++++++++++++++ src/libsyntax/util/interner.rs | 6 ++++ src/libtest/lib.rs | 50 ++++++++++++++++++++++++++++++ 9 files changed, 172 insertions(+) diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index ff756a8eef3c3..79c1f720794f2 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -532,10 +532,17 @@ impl<'a> PartialOrd for MaybeOwned<'a> { } impl<'a> Ord for MaybeOwned<'a> { + // NOTE(stage0): remove method after a snapshot + #[cfg(stage0)] #[inline] fn cmp(&self, other: &MaybeOwned) -> Ordering { self.as_slice().cmp(&other.as_slice()) } + #[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot + #[inline] + fn cmp(&self, other: &MaybeOwned) -> Ordering { + self.as_slice().cmp(other.as_slice()) + } } impl<'a, S: Str> Equiv for MaybeOwned<'a> { diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 40e7c949972b5..4b6921ed0c0d9 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -506,10 +506,17 @@ impl PartialEq for Vec { #[unstable = "waiting on PartialOrd stability"] impl PartialOrd for Vec { + // NOTE(stage0): remove method after a snapshot + #[cfg(stage0)] #[inline] fn partial_cmp(&self, other: &Vec) -> Option { self.as_slice().partial_cmp(&other.as_slice()) } + #[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot + #[inline] + fn partial_cmp(&self, other: &Vec) -> Option { + self.as_slice().partial_cmp(other.as_slice()) + } } #[unstable = "waiting on Eq stability"] @@ -523,10 +530,17 @@ impl> Equiv for Vec { #[unstable = "waiting on Ord stability"] impl Ord for Vec { + // NOTE(stage0): remove method after a snapshot + #[cfg(stage0)] #[inline] fn cmp(&self, other: &Vec) -> Ordering { self.as_slice().cmp(&other.as_slice()) } + #[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot + #[inline] + fn cmp(&self, other: &Vec) -> Ordering { + self.as_slice().cmp(other.as_slice()) + } } // FIXME: #13996: need a way to mark the return value as `noalias` diff --git a/src/libgraphviz/maybe_owned_vec.rs b/src/libgraphviz/maybe_owned_vec.rs index d465d1407513b..3a89d8b3f81cd 100644 --- a/src/libgraphviz/maybe_owned_vec.rs +++ b/src/libgraphviz/maybe_owned_vec.rs @@ -76,15 +76,27 @@ impl<'a, T: PartialEq> PartialEq for MaybeOwnedVector<'a, T> { impl<'a, T: Eq> Eq for MaybeOwnedVector<'a, T> {} impl<'a, T: PartialOrd> PartialOrd for MaybeOwnedVector<'a, T> { + // NOTE(stage0): remove method after a snapshot + #[cfg(stage0)] fn partial_cmp(&self, other: &MaybeOwnedVector) -> Option { self.as_slice().partial_cmp(&other.as_slice()) } + #[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot + fn partial_cmp(&self, other: &MaybeOwnedVector) -> Option { + self.as_slice().partial_cmp(other.as_slice()) + } } impl<'a, T: Ord> Ord for MaybeOwnedVector<'a, T> { + // NOTE(stage0): remove method after a snapshot + #[cfg(stage0)] fn cmp(&self, other: &MaybeOwnedVector) -> Ordering { self.as_slice().cmp(&other.as_slice()) } + #[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot + fn cmp(&self, other: &MaybeOwnedVector) -> Ordering { + self.as_slice().cmp(other.as_slice()) + } } impl<'a, T: PartialEq, V: AsSlice> Equiv for MaybeOwnedVector<'a, T> { diff --git a/src/libregex/parse.rs b/src/libregex/parse.rs index 3115161682f02..6723ea725a356 100644 --- a/src/libregex/parse.rs +++ b/src/libregex/parse.rs @@ -1020,6 +1020,8 @@ fn is_valid_cap(c: char) -> bool { || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') } +// NOTE(stage0): remove function after a snapshot +#[cfg(stage0)] fn find_class(classes: NamedClasses, name: &str) -> Option> { match classes.binary_search(|&(s, _)| s.cmp(&name)) { slice::Found(i) => Some(classes[i].val1().to_vec()), @@ -1027,6 +1029,14 @@ fn find_class(classes: NamedClasses, name: &str) -> Option> { } } +#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot +fn find_class(classes: NamedClasses, name: &str) -> Option> { + match classes.binary_search(|&(s, _)| s.cmp(name)) { + slice::Found(i) => Some(classes[i].val1().to_vec()), + slice::NotFound(_) => None, + } +} + type Class = &'static [(char, char)]; type NamedClasses = &'static [(&'static str, &'static Class)]; diff --git a/src/librustc/driver/mod.rs b/src/librustc/driver/mod.rs index 7715f0e10f559..8753795d9e25d 100644 --- a/src/librustc/driver/mod.rs +++ b/src/librustc/driver/mod.rs @@ -182,6 +182,8 @@ Available lint options: "); + // NOTE(stage0): remove function after a snapshot + #[cfg(stage0)] fn sort_lints(lints: Vec<(&'static Lint, bool)>) -> Vec<&'static Lint> { let mut lints: Vec<_> = lints.into_iter().map(|(x, _)| x).collect(); lints.sort_by(|x: &&Lint, y: &&Lint| { @@ -194,6 +196,21 @@ Available lint options: lints } + #[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot + fn sort_lints(lints: Vec<(&'static Lint, bool)>) -> Vec<&'static Lint> { + let mut lints: Vec<_> = lints.into_iter().map(|(x, _)| x).collect(); + lints.sort_by(|x: &&Lint, y: &&Lint| { + match x.default_level.cmp(&y.default_level) { + // The sort doesn't case-fold but it's doubtful we care. + Equal => x.name.cmp(y.name), + r => r, + } + }); + lints + } + + // NOTE(stage0): remove function after a snapshot + #[cfg(stage0)] fn sort_lint_groups(lints: Vec<(&'static str, Vec, bool)>) -> Vec<(&'static str, Vec)> { let mut lints: Vec<_> = lints.into_iter().map(|(x, y, _)| (x, y)).collect(); @@ -204,6 +221,17 @@ Available lint options: lints } + #[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot + fn sort_lint_groups(lints: Vec<(&'static str, Vec, bool)>) + -> Vec<(&'static str, Vec)> { + let mut lints: Vec<_> = lints.into_iter().map(|(x, y, _)| (x, y)).collect(); + lints.sort_by(|&(x, _): &(&'static str, Vec), + &(y, _): &(&'static str, Vec)| { + x.cmp(y) + }); + lints + } + let (plugin, builtin) = lint_store.get_lints().partitioned(|&(_, p)| p); let plugin = sort_lints(plugin); let builtin = sort_lints(builtin); diff --git a/src/librustrt/c_str.rs b/src/librustrt/c_str.rs index b15cdb88b6783..b7a2c8f947341 100644 --- a/src/librustrt/c_str.rs +++ b/src/librustrt/c_str.rs @@ -121,10 +121,17 @@ impl PartialEq for CString { } impl PartialOrd for CString { + // NOTE(stage0): remove method after a snapshot + #[cfg(stage0)] #[inline] fn partial_cmp(&self, other: &CString) -> Option { self.as_bytes().partial_cmp(&other.as_bytes()) } + #[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot + #[inline] + fn partial_cmp(&self, other: &CString) -> Option { + self.as_bytes().partial_cmp(other.as_bytes()) + } } impl Eq for CString {} diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index e0d436f5e0eb6..dbdfa17bfc228 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -890,6 +890,8 @@ impl Json { /// If the Json value is an Object, returns the value associated with the provided key. /// Otherwise, returns None. + // NOTE(stage0): remove function after a snapshot + #[cfg(stage0)] pub fn find<'a>(&'a self, key: &str) -> Option<&'a Json>{ match self { &Object(ref map) => map.find_with(|s| key.cmp(&s.as_slice())), @@ -897,6 +899,16 @@ impl Json { } } + /// If the Json value is an Object, returns the value associated with the provided key. + /// Otherwise, returns None. + #[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot + pub fn find<'a>(&'a self, key: &str) -> Option<&'a Json>{ + match self { + &Object(ref map) => map.find_with(|s| key.cmp(s.as_slice())), + _ => None + } + } + /// Attempts to get a nested Json Object for each key in `keys`. /// If any key is found not to exist, find_path will return None. /// Otherwise, it will return the Json value associated with the final key. @@ -914,6 +926,8 @@ impl Json { /// If the Json value is an Object, performs a depth-first search until /// a value associated with the provided key is found. If no value is found /// or the Json value is not an Object, returns None. + // NOTE(stage0): remove function after a snapshot + #[cfg(stage0)] pub fn search<'a>(&'a self, key: &str) -> Option<&'a Json> { match self { &Object(ref map) => { @@ -934,6 +948,30 @@ impl Json { } } + /// If the Json value is an Object, performs a depth-first search until + /// a value associated with the provided key is found. If no value is found + /// or the Json value is not an Object, returns None. + #[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot + pub fn search<'a>(&'a self, key: &str) -> Option<&'a Json> { + match self { + &Object(ref map) => { + match map.find_with(|s| key.cmp(s.as_slice())) { + Some(json_value) => Some(json_value), + None => { + for (_, v) in map.iter() { + match v.search(key) { + x if x.is_some() => return x, + _ => () + } + } + None + } + } + }, + _ => None + } + } + /// Returns true if the Json value is an Object. Returns false otherwise. pub fn is_object<'a>(&'a self) -> bool { self.as_object().is_some() diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index 105118ff76a9d..e6c98a9e3d09a 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -97,9 +97,15 @@ pub struct RcStr { impl Eq for RcStr {} impl Ord for RcStr { + // NOTE(stage0): remove method after a snapshot + #[cfg(stage0)] fn cmp(&self, other: &RcStr) -> Ordering { self.as_slice().cmp(&other.as_slice()) } + #[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot + fn cmp(&self, other: &RcStr) -> Ordering { + self.as_slice().cmp(other.as_slice()) + } } impl Str for RcStr { diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 81d0bb76d1497..74bead9e5f2dd 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -973,6 +973,8 @@ fn get_concurrency() -> uint { } } +// NOTE(stage0): remove function after a snapshot +#[cfg(stage0)] pub fn filter_tests(opts: &TestOpts, tests: Vec) -> Vec { let mut filtered = tests; @@ -1020,6 +1022,54 @@ pub fn filter_tests(opts: &TestOpts, tests: Vec) -> Vec) -> Vec { + let mut filtered = tests; + + // Remove tests that don't match the test filter + filtered = match opts.filter { + None => filtered, + Some(ref re) => { + filtered.into_iter() + .filter(|test| re.is_match(test.desc.name.as_slice())).collect() + } + }; + + // Maybe pull out the ignored test and unignore them + filtered = if !opts.run_ignored { + filtered + } else { + fn filter(test: TestDescAndFn) -> Option { + if test.desc.ignore { + let TestDescAndFn {desc, testfn} = test; + Some(TestDescAndFn { + desc: TestDesc {ignore: false, ..desc}, + testfn: testfn + }) + } else { + None + } + }; + filtered.into_iter().filter_map(|x| filter(x)).collect() + }; + + // Sort the tests alphabetically + filtered.sort_by(|t1, t2| t1.desc.name.as_slice().cmp(t2.desc.name.as_slice())); + + // Shard the remaining tests, if sharding requested. + match opts.test_shard { + None => filtered, + Some((a,b)) => { + filtered.into_iter().enumerate() + // note: using a - 1 so that the valid shards, for example, are + // 1.2 and 2.2 instead of 0.2 and 1.2 + .filter(|&(i,_)| i % b == (a - 1)) + .map(|(_,t)| t) + .collect() + } + } +} + pub fn run_test(opts: &TestOpts, force_ignore: bool, test: TestDescAndFn, From 4c3b42271ba74ff905dd722e6480701713408d60 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Thu, 30 Oct 2014 15:33:47 -0500 Subject: [PATCH 5/7] DSTify Box implementation of PartialEq, PartialOrd, Eq, Ord --- src/liballoc/boxed.rs | 40 +++++++++++++++++++ .../run-pass/deriving-eq-ord-boxed-slice.rs | 24 +++++++++++ 2 files changed, 64 insertions(+) create mode 100644 src/test/run-pass/deriving-eq-ord-boxed-slice.rs diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index de98bc63183a2..d1fc921ffdab5 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -61,12 +61,16 @@ impl Clone for Box { } } +// NOTE(stage0): remove impl after a snapshot +#[cfg(stage0)] impl PartialEq for Box { #[inline] fn eq(&self, other: &Box) -> bool { *(*self) == *(*other) } #[inline] fn ne(&self, other: &Box) -> bool { *(*self) != *(*other) } } +// NOTE(stage0): remove impl after a snapshot +#[cfg(stage0)] impl PartialOrd for Box { #[inline] fn partial_cmp(&self, other: &Box) -> Option { @@ -81,14 +85,50 @@ impl PartialOrd for Box { #[inline] fn gt(&self, other: &Box) -> bool { *(*self) > *(*other) } } +// NOTE(stage0): remove impl after a snapshot +#[cfg(stage0)] impl Ord for Box { #[inline] fn cmp(&self, other: &Box) -> Ordering { (**self).cmp(&**other) } } +// NOTE(stage0): remove impl after a snapshot +#[cfg(stage0)] impl Eq for Box {} +#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot +impl PartialEq for Box { + #[inline] + fn eq(&self, other: &Box) -> bool { PartialEq::eq(&**self, &**other) } + #[inline] + fn ne(&self, other: &Box) -> bool { PartialEq::ne(&**self, &**other) } +} +#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot +impl PartialOrd for Box { + #[inline] + fn partial_cmp(&self, other: &Box) -> Option { + PartialOrd::partial_cmp(&**self, &**other) + } + #[inline] + fn lt(&self, other: &Box) -> bool { PartialOrd::lt(&**self, &**other) } + #[inline] + fn le(&self, other: &Box) -> bool { PartialOrd::le(&**self, &**other) } + #[inline] + fn ge(&self, other: &Box) -> bool { PartialOrd::ge(&**self, &**other) } + #[inline] + fn gt(&self, other: &Box) -> bool { PartialOrd::gt(&**self, &**other) } +} +#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot +impl Ord for Box { + #[inline] + fn cmp(&self, other: &Box) -> Ordering { + Ord::cmp(&**self, &**other) + } +} +#[cfg(not(stage0))] // NOTE(stage0): remove cfg after a snapshot +impl Eq for Box {} + /// Extension methods for an owning `Any` trait object. #[unstable = "post-DST and coherence changes, this will not be a trait but \ rather a direct `impl` on `Box`"] diff --git a/src/test/run-pass/deriving-eq-ord-boxed-slice.rs b/src/test/run-pass/deriving-eq-ord-boxed-slice.rs new file mode 100644 index 0000000000000..b16c2ccb46eb8 --- /dev/null +++ b/src/test/run-pass/deriving-eq-ord-boxed-slice.rs @@ -0,0 +1,24 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[deriving(PartialEq, PartialOrd, Eq, Ord)] +struct Foo(Box<[u8]>); + +pub fn main() { + let a = Foo(box [0, 1, 2]); + let b = Foo(box [0, 1, 2]); + assert!(a == b); + println!("{}", a != b); + println!("{}", a < b); + println!("{}", a <= b); + println!("{}", a == b); + println!("{}", a > b); + println!("{}", a >= b); +} From 62168222493c8302e9f6b4291f0ba9e124e196cb Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Mon, 3 Nov 2014 09:42:17 -0500 Subject: [PATCH 6/7] Add test for the first half of issue #15689 cc #15689 --- src/test/run-pass/issue-15689-1.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/test/run-pass/issue-15689-1.rs diff --git a/src/test/run-pass/issue-15689-1.rs b/src/test/run-pass/issue-15689-1.rs new file mode 100644 index 0000000000000..8d17fc4600614 --- /dev/null +++ b/src/test/run-pass/issue-15689-1.rs @@ -0,0 +1,18 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[deriving(PartialEq)] +enum Test<'a> { + Slice(&'a int) +} + +fn main() { + assert!(Slice(&1) == Slice(&1)) +} From 11f4baeafb83459befd0196b2b82cda7ed5ea2f1 Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Mon, 3 Nov 2014 14:55:19 -0500 Subject: [PATCH 7/7] Fix tests --- src/libcollections/slice.rs | 10 +++++----- src/libcollections/str.rs | 10 +++++----- src/libcollections/tree/map.rs | 14 +++++++------- .../deriving-no-inner-impl-error-message.rs | 4 ++-- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index eb4ff345b5133..e4af5795e1cc9 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -1598,15 +1598,15 @@ mod tests { #[test] fn test_total_ord() { let c: &[int] = &[1, 2, 3]; - [1, 2, 3, 4][].cmp(& c) == Greater; + [1, 2, 3, 4][].cmp(c) == Greater; let c: &[int] = &[1, 2, 3, 4]; - [1, 2, 3][].cmp(& c) == Less; + [1, 2, 3][].cmp(c) == Less; let c: &[int] = &[1, 2, 3, 6]; - [1, 2, 3, 4][].cmp(& c) == Equal; + [1, 2, 3, 4][].cmp(c) == Equal; let c: &[int] = &[1, 2, 3, 4, 5, 6]; - [1, 2, 3, 4, 5, 5, 5, 5][].cmp(& c) == Less; + [1, 2, 3, 4, 5, 5, 5, 5][].cmp(c) == Less; let c: &[int] = &[1, 2, 3, 4]; - [2, 2][].cmp(& c) == Greater; + [2, 2][].cmp(c) == Greater; } #[test] diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 79c1f720794f2..cdca0d10eedde 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -1530,11 +1530,11 @@ mod tests { #[test] fn test_total_ord() { - "1234".cmp(&("123")) == Greater; - "123".cmp(&("1234")) == Less; - "1234".cmp(&("1234")) == Equal; - "12345555".cmp(&("123456")) == Less; - "22".cmp(&("1234")) == Greater; + "1234".cmp("123") == Greater; + "123".cmp("1234") == Less; + "1234".cmp("1234") == Equal; + "12345555".cmp("123456") == Less; + "22".cmp("1234") == Greater; } #[test] diff --git a/src/libcollections/tree/map.rs b/src/libcollections/tree/map.rs index 9742bddb1f659..8e24eabfccfe6 100644 --- a/src/libcollections/tree/map.rs +++ b/src/libcollections/tree/map.rs @@ -579,7 +579,7 @@ impl TreeMap { /// let headers = get_headers(); /// let ua_key = "User-Agent"; /// let ua = headers.find_with(|k| { - /// ua_key.cmp(&k.as_slice()) + /// ua_key.cmp(k.as_slice()) /// }); /// /// assert_eq!((*ua.unwrap()).as_slice(), "Curl-Rust/0.1"); @@ -603,7 +603,7 @@ impl TreeMap { /// t.insert("User-Agent", "Curl-Rust/0.1"); /// /// let new_ua = "Safari/156.0"; - /// match t.find_with_mut(|k| "User-Agent".cmp(k)) { + /// match t.find_with_mut(|&k| "User-Agent".cmp(k)) { /// Some(x) => *x = new_ua, /// None => panic!(), /// } @@ -1302,7 +1302,7 @@ mod test_treemap { #[test] fn find_with_empty() { let m: TreeMap<&'static str,int> = TreeMap::new(); - assert!(m.find_with(|k| "test".cmp(k)) == None); + assert!(m.find_with(|&k| "test".cmp(k)) == None); } #[test] @@ -1311,7 +1311,7 @@ mod test_treemap { assert!(m.insert("test1", 2i)); assert!(m.insert("test2", 3i)); assert!(m.insert("test3", 3i)); - assert_eq!(m.find_with(|k| "test4".cmp(k)), None); + assert_eq!(m.find_with(|&k| "test4".cmp(k)), None); } #[test] @@ -1320,7 +1320,7 @@ mod test_treemap { assert!(m.insert("test1", 2i)); assert!(m.insert("test2", 3i)); assert!(m.insert("test3", 4i)); - assert_eq!(m.find_with(|k| "test2".cmp(k)), Some(&3i)); + assert_eq!(m.find_with(|&k| "test2".cmp(k)), Some(&3i)); } #[test] @@ -1343,10 +1343,10 @@ mod test_treemap { assert!(m.insert("t2", 8)); assert!(m.insert("t5", 14)); let new = 100; - match m.find_with_mut(|k| "t5".cmp(k)) { + match m.find_with_mut(|&k| "t5".cmp(k)) { None => panic!(), Some(x) => *x = new } - assert_eq!(m.find_with(|k| "t5".cmp(k)), Some(&new)); + assert_eq!(m.find_with(|&k| "t5".cmp(k)), Some(&new)); } #[test] diff --git a/src/test/compile-fail/deriving-no-inner-impl-error-message.rs b/src/test/compile-fail/deriving-no-inner-impl-error-message.rs index 15a7bc01c3ae7..18be03f97d934 100644 --- a/src/test/compile-fail/deriving-no-inner-impl-error-message.rs +++ b/src/test/compile-fail/deriving-no-inner-impl-error-message.rs @@ -12,8 +12,8 @@ struct NoCloneOrEq; #[deriving(PartialEq)] struct E { - x: NoCloneOrEq //~ ERROR does not implement any method in scope named `eq` - //~^ ERROR does not implement any method in scope named `ne` + x: NoCloneOrEq //~ ERROR binary operation `==` cannot be applied to type `NoCloneOrEq` + //~^ ERROR binary operation `!=` cannot be applied to type `NoCloneOrEq` } #[deriving(Clone)] struct C {