auto merge of #19167 : japaric/rust/rhs-cmp, r=aturon

Comparison traits have gained an `Rhs` input parameter that defaults to `Self`. And now the comparison operators can be overloaded to work between different types. In particular, this PR allows the following operations (and their commutative versions):

- `&str` == `String` == `CowString`
- `&[A]` == `&mut [B]` == `Vec<C>` == `CowVec<D>` == `[E, ..N]` (for `N` up to 32)
- `&mut A` == `&B` (for `Sized` `A` and `B`)

Where `A`, `B`, `C`, `D`, `E` may be different types that implement `PartialEq`. For example, these comparisons are now valid: `string == "foo"`, and `vec_of_strings == ["Hello", "world"]`.

[breaking-change]s

Since the `==` may now work on different types, operations that relied on the old "same type restriction" to drive type inference, will need to be type annotated. These are the most common fallout cases:

- `some_vec == some_iter.collect()`: `collect` needs to be type annotated: `collect::<Vec<_>>()`
- `slice == &[a, b, c]`: RHS doesn't get coerced to an slice, use an array instead `[a, b, c]`
- `lhs == []`: Change expression to `lhs.is_empty()`
- `lhs == some_generic_function()`: Type annotate the RHS as necessary

cc #19148

r? @aturon
This commit is contained in:
bors 2014-12-04 12:02:56 +00:00
commit 6d965cc2c9
41 changed files with 421 additions and 222 deletions

View file

@ -945,7 +945,7 @@ mod tests {
let mut m = list_from(v.as_slice());
m.rotate_backward(); check_links(&m);
m.rotate_forward(); check_links(&m);
assert_eq!(v.iter().collect::<Vec<&int>>(), m.iter().collect());
assert_eq!(v.iter().collect::<Vec<&int>>(), m.iter().collect::<Vec<_>>());
m.rotate_forward(); check_links(&m);
m.rotate_forward(); check_links(&m);
m.pop_front(); check_links(&m);
@ -953,7 +953,7 @@ mod tests {
m.rotate_backward(); check_links(&m);
m.push_front(9); check_links(&m);
m.rotate_forward(); check_links(&m);
assert_eq!(vec![3i,9,5,1,2], m.into_iter().collect());
assert_eq!(vec![3i,9,5,1,2], m.into_iter().collect::<Vec<_>>());
}
#[test]

View file

@ -397,23 +397,23 @@ mod test {
fn test_iterator() {
let mut e1: EnumSet<Foo> = EnumSet::new();
let elems: Vec<Foo> = e1.iter().collect();
let elems: ::vec::Vec<Foo> = e1.iter().collect();
assert!(elems.is_empty())
e1.insert(A);
let elems = e1.iter().collect();
let elems: ::vec::Vec<_> = e1.iter().collect();
assert_eq!(vec![A], elems)
e1.insert(C);
let elems = e1.iter().collect();
let elems: ::vec::Vec<_> = e1.iter().collect();
assert_eq!(vec![A,C], elems)
e1.insert(C);
let elems = e1.iter().collect();
let elems: ::vec::Vec<_> = e1.iter().collect();
assert_eq!(vec![A,C], elems)
e1.insert(B);
let elems = e1.iter().collect();
let elems: ::vec::Vec<_> = e1.iter().collect();
assert_eq!(vec![A,B,C], elems)
}
@ -431,35 +431,35 @@ mod test {
e2.insert(C);
let e_union = e1 | e2;
let elems = e_union.iter().collect();
let elems: ::vec::Vec<_> = e_union.iter().collect();
assert_eq!(vec![A,B,C], elems)
let e_intersection = e1 & e2;
let elems = e_intersection.iter().collect();
let elems: ::vec::Vec<_> = e_intersection.iter().collect();
assert_eq!(vec![C], elems)
// Another way to express intersection
let e_intersection = e1 - (e1 - e2);
let elems = e_intersection.iter().collect();
let elems: ::vec::Vec<_> = e_intersection.iter().collect();
assert_eq!(vec![C], elems)
let e_subtract = e1 - e2;
let elems = e_subtract.iter().collect();
let elems: ::vec::Vec<_> = e_subtract.iter().collect();
assert_eq!(vec![A], elems)
// Bitwise XOR of two sets, aka symmetric difference
let e_symmetric_diff = e1 ^ e2;
let elems = e_symmetric_diff.iter().collect();
let elems: ::vec::Vec<_> = e_symmetric_diff.iter().collect();
assert_eq!(vec![A,B], elems)
// Another way to express symmetric difference
let e_symmetric_diff = (e1 - e2) | (e2 - e1);
let elems = e_symmetric_diff.iter().collect();
let elems: ::vec::Vec<_> = e_symmetric_diff.iter().collect();
assert_eq!(vec![A,B], elems)
// Yet another way to express symmetric difference
let e_symmetric_diff = (e1 | e2) - (e1 & e2);
let elems = e_symmetric_diff.iter().collect();
let elems: ::vec::Vec<_> = e_symmetric_diff.iter().collect();
assert_eq!(vec![A,B], elems)
}

View file

@ -563,6 +563,7 @@ impl<'a> Ord for MaybeOwned<'a> {
}
}
#[allow(deprecated)]
#[deprecated = "use std::str::CowString"]
impl<'a, S: Str> Equiv<S> for MaybeOwned<'a> {
#[inline]

View file

@ -30,7 +30,7 @@ use str::{CharRange, CowString, FromStr, StrAllocating, Owned};
use vec::{DerefVec, Vec, as_vec};
/// A growable string stored as a UTF-8 encoded buffer.
#[deriving(Clone, PartialEq, PartialOrd, Eq, Ord)]
#[deriving(Clone, PartialOrd, Eq, Ord)]
#[stable]
pub struct String {
vec: Vec<u8>,
@ -738,6 +738,49 @@ impl Extend<char> for String {
}
}
impl PartialEq for String {
#[inline]
fn eq(&self, other: &String) -> bool { PartialEq::eq(&**self, &**other) }
#[inline]
fn ne(&self, other: &String) -> bool { PartialEq::ne(&**self, &**other) }
}
macro_rules! impl_eq {
($lhs:ty, $rhs: ty) => {
impl<'a> PartialEq<$rhs> for $lhs {
#[inline]
fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) }
#[inline]
fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) }
}
impl<'a> PartialEq<$lhs> for $rhs {
#[inline]
fn eq(&self, other: &$lhs) -> bool { PartialEq::eq(&**self, &**other) }
#[inline]
fn ne(&self, other: &$lhs) -> bool { PartialEq::ne(&**self, &**other) }
}
}
}
impl_eq!(String, &'a str)
impl_eq!(CowString<'a>, String)
impl<'a, 'b> PartialEq<&'b str> for CowString<'a> {
#[inline]
fn eq(&self, other: &&'b str) -> bool { PartialEq::eq(&**self, &**other) }
#[inline]
fn ne(&self, other: &&'b str) -> bool { PartialEq::ne(&**self, &**other) }
}
impl<'a, 'b> PartialEq<CowString<'a>> for &'b str {
#[inline]
fn eq(&self, other: &CowString<'a>) -> bool { PartialEq::eq(&**self, &**other) }
#[inline]
fn ne(&self, other: &CowString<'a>) -> bool { PartialEq::ne(&**self, &**other) }
}
#[experimental = "waiting on Str stabilization"]
impl Str for String {
#[inline]
@ -779,7 +822,8 @@ impl<H: hash::Writer> hash::Hash<H> for String {
}
}
#[experimental = "waiting on Equiv stabilization"]
#[allow(deprecated)]
#[deprecated = "Use overloaded `core::cmp::PartialEq`"]
impl<'a, S: Str> Equiv<S> for String {
#[inline]
fn equiv(&self, other: &S) -> bool {
@ -967,10 +1011,12 @@ mod tests {
#[test]
fn test_from_utf8_lossy() {
let xs = b"hello";
assert_eq!(String::from_utf8_lossy(xs), "hello".into_cow());
let ys: str::CowString = "hello".into_cow();
assert_eq!(String::from_utf8_lossy(xs), ys);
let xs = "ศไทย中华Việt Nam".as_bytes();
assert_eq!(String::from_utf8_lossy(xs), "ศไทย中华Việt Nam".into_cow());
let ys: str::CowString = "ศไทย中华Việt Nam".into_cow();
assert_eq!(String::from_utf8_lossy(xs), ys);
let xs = b"Hello\xC2 There\xFF Goodbye";
assert_eq!(String::from_utf8_lossy(xs),

View file

@ -535,14 +535,69 @@ impl<T> Extend<T> for Vec<T> {
}
}
#[unstable = "waiting on PartialEq stability"]
impl<T: PartialEq> PartialEq for Vec<T> {
impl<A, B> PartialEq<Vec<B>> for Vec<A> where A: PartialEq<B> {
#[inline]
fn eq(&self, other: &Vec<T>) -> bool {
self.as_slice() == other.as_slice()
fn eq(&self, other: &Vec<B>) -> bool { PartialEq::eq(&**self, &**other) }
#[inline]
fn ne(&self, other: &Vec<B>) -> bool { PartialEq::ne(&**self, &**other) }
}
macro_rules! impl_eq {
($lhs:ty, $rhs:ty) => {
impl<'b, A, B> PartialEq<$rhs> for $lhs where A: PartialEq<B> {
#[inline]
fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) }
#[inline]
fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) }
}
impl<'b, A, B> PartialEq<$lhs> for $rhs where B: PartialEq<A> {
#[inline]
fn eq(&self, other: &$lhs) -> bool { PartialEq::eq(&**self, &**other) }
#[inline]
fn ne(&self, other: &$lhs) -> bool { PartialEq::ne(&**self, &**other) }
}
}
}
impl_eq!(Vec<A>, &'b [B])
impl_eq!(Vec<A>, &'b mut [B])
impl<'a, A, B> PartialEq<Vec<B>> for CowVec<'a, A> where A: PartialEq<B> + Clone {
#[inline]
fn eq(&self, other: &Vec<B>) -> bool { PartialEq::eq(&**self, &**other) }
#[inline]
fn ne(&self, other: &Vec<B>) -> bool { PartialEq::ne(&**self, &**other) }
}
impl<'a, A, B> PartialEq<CowVec<'a, A>> for Vec<B> where A: Clone, B: PartialEq<A> {
#[inline]
fn eq(&self, other: &CowVec<'a, A>) -> bool { PartialEq::eq(&**self, &**other) }
#[inline]
fn ne(&self, other: &CowVec<'a, A>) -> bool { PartialEq::ne(&**self, &**other) }
}
macro_rules! impl_eq_for_cowvec {
($rhs:ty) => {
impl<'a, 'b, A, B> PartialEq<$rhs> for CowVec<'a, A> where A: PartialEq<B> + Clone {
#[inline]
fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) }
#[inline]
fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) }
}
impl<'a, 'b, A, B> PartialEq<CowVec<'a, A>> for $rhs where A: Clone, B: PartialEq<A> {
#[inline]
fn eq(&self, other: &CowVec<'a, A>) -> bool { PartialEq::eq(&**self, &**other) }
#[inline]
fn ne(&self, other: &CowVec<'a, A>) -> bool { PartialEq::ne(&**self, &**other) }
}
}
}
impl_eq_for_cowvec!(&'b [B])
impl_eq_for_cowvec!(&'b mut [B])
#[unstable = "waiting on PartialOrd stability"]
impl<T: PartialOrd> PartialOrd for Vec<T> {
#[inline]
@ -554,7 +609,8 @@ impl<T: PartialOrd> PartialOrd for Vec<T> {
#[unstable = "waiting on Eq stability"]
impl<T: Eq> Eq for Vec<T> {}
#[experimental]
#[allow(deprecated)]
#[deprecated = "Use overloaded `core::cmp::PartialEq`"]
impl<T: PartialEq, Sized? V: AsSlice<T>> Equiv<V> for Vec<T> {
#[inline]
fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
@ -1813,13 +1869,13 @@ mod tests {
let mut values = vec![1u8,2,3,4,5];
{
let slice = values.slice_from_mut(2);
assert!(slice == &mut [3, 4, 5]);
assert!(slice == [3, 4, 5]);
for p in slice.iter_mut() {
*p += 2;
}
}
assert!(values.as_slice() == &[1, 2, 5, 6, 7]);
assert!(values.as_slice() == [1, 2, 5, 6, 7]);
}
#[test]
@ -1827,13 +1883,13 @@ mod tests {
let mut values = vec![1u8,2,3,4,5];
{
let slice = values.slice_to_mut(2);
assert!(slice == &mut [1, 2]);
assert!(slice == [1, 2]);
for p in slice.iter_mut() {
*p += 1;
}
}
assert!(values.as_slice() == &[2, 3, 3, 4, 5]);
assert!(values.as_slice() == [2, 3, 3, 4, 5]);
}
#[test]

View file

@ -18,6 +18,7 @@ use clone::Clone;
use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
use fmt;
use kinds::Copy;
use ops::Deref;
use option::Option;
// macro for implementing n-ary tuple functions and operations
@ -39,17 +40,37 @@ macro_rules! array_impls {
}
#[unstable = "waiting for PartialEq to stabilize"]
impl<T:PartialEq> PartialEq for [T, ..$N] {
impl<A, B> PartialEq<[B, ..$N]> for [A, ..$N] where A: PartialEq<B> {
#[inline]
fn eq(&self, other: &[T, ..$N]) -> bool {
fn eq(&self, other: &[B, ..$N]) -> bool {
self[] == other[]
}
#[inline]
fn ne(&self, other: &[T, ..$N]) -> bool {
fn ne(&self, other: &[B, ..$N]) -> bool {
self[] != other[]
}
}
impl<'a, A, B, Rhs> PartialEq<Rhs> for [A, ..$N] where
A: PartialEq<B>,
Rhs: Deref<[B]>,
{
#[inline(always)]
fn eq(&self, other: &Rhs) -> bool { PartialEq::eq(self[], &**other) }
#[inline(always)]
fn ne(&self, other: &Rhs) -> bool { PartialEq::ne(self[], &**other) }
}
impl<'a, A, B, Lhs> PartialEq<[B, ..$N]> for Lhs where
A: PartialEq<B>,
Lhs: Deref<[A]>
{
#[inline(always)]
fn eq(&self, other: &[B, ..$N]) -> bool { PartialEq::eq(&**self, other[]) }
#[inline(always)]
fn ne(&self, other: &[B, ..$N]) -> bool { PartialEq::ne(&**self, other[]) }
}
#[unstable = "waiting for Eq to stabilize"]
impl<T:Eq> Eq for [T, ..$N] { }

View file

@ -196,9 +196,12 @@ impl<'a, T, Sized? B> Ord for Cow<'a, T, B> where B: Ord + ToOwned<T> {
}
}
impl<'a, T, Sized? B> PartialEq for Cow<'a, T, B> where B: PartialEq + ToOwned<T> {
impl<'a, 'b, T, U, Sized? B, Sized? C> PartialEq<Cow<'b, U, C>> for Cow<'a, T, B> where
B: PartialEq<C> + ToOwned<T>,
C: ToOwned<U>,
{
#[inline]
fn eq(&self, other: &Cow<'a, T, B>) -> bool {
fn eq(&self, other: &Cow<'b, U, C>) -> bool {
PartialEq::eq(&**self, &**other)
}
}

View file

@ -61,13 +61,13 @@ use option::{Option, Some, None};
/// `Eq`.
#[lang="eq"]
#[unstable = "Definition may change slightly after trait reform"]
pub trait PartialEq for Sized? {
pub trait PartialEq<Sized? Rhs = Self> for Sized? {
/// This method tests for `self` and `other` values to be equal, and is used by `==`.
fn eq(&self, other: &Self) -> bool;
fn eq(&self, other: &Rhs) -> bool;
/// This method tests for `!=`.
#[inline]
fn ne(&self, other: &Self) -> bool { !self.eq(other) }
fn ne(&self, other: &Rhs) -> bool { !self.eq(other) }
}
/// Trait for equality comparisons which are [equivalence relations](
@ -80,7 +80,7 @@ pub trait PartialEq for Sized? {
/// - symmetric: `a == b` implies `b == a`; and
/// - transitive: `a == b` and `b == c` implies `a == c`.
#[unstable = "Definition may change slightly after trait reform"]
pub trait Eq for Sized?: PartialEq {
pub trait Eq<Sized? Rhs = Self> for Sized?: PartialEq<Rhs> {
// 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
@ -150,7 +150,7 @@ impl Ordering {
/// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for
/// both `==` and `>`.
#[unstable = "Definition may change slightly after trait reform"]
pub trait Ord for Sized?: Eq + PartialOrd {
pub trait Ord<Sized? Rhs = Self> for Sized?: Eq<Rhs> + PartialOrd<Rhs> {
/// This method returns an ordering between `self` and `other` values.
///
/// By convention, `self.cmp(&other)` returns the ordering matching
@ -161,7 +161,7 @@ pub trait Ord for Sized?: Eq + PartialOrd {
/// assert_eq!(10u.cmp(&5), Greater); // because 10 > 5
/// assert_eq!( 5u.cmp(&5), Equal); // because 5 == 5
/// ```
fn cmp(&self, other: &Self) -> Ordering;
fn cmp(&self, other: &Rhs) -> Ordering;
}
#[unstable = "Trait is unstable."]
@ -194,14 +194,14 @@ impl PartialOrd for Ordering {
/// 5.11).
#[lang="ord"]
#[unstable = "Definition may change slightly after trait reform"]
pub trait PartialOrd for Sized?: PartialEq {
pub trait PartialOrd<Sized? Rhs = Self> for Sized?: PartialEq<Rhs> {
/// This method returns an ordering between `self` and `other` values
/// if one exists.
fn partial_cmp(&self, other: &Self) -> Option<Ordering>;
fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
/// This method tests less than (for `self` and `other`) and is used by the `<` operator.
#[inline]
fn lt(&self, other: &Self) -> bool {
fn lt(&self, other: &Rhs) -> bool {
match self.partial_cmp(other) {
Some(Less) => true,
_ => false,
@ -210,7 +210,7 @@ pub trait PartialOrd for Sized?: PartialEq {
/// This method tests less than or equal to (`<=`).
#[inline]
fn le(&self, other: &Self) -> bool {
fn le(&self, other: &Rhs) -> bool {
match self.partial_cmp(other) {
Some(Less) | Some(Equal) => true,
_ => false,
@ -219,7 +219,7 @@ pub trait PartialOrd for Sized?: PartialEq {
/// This method tests greater than (`>`).
#[inline]
fn gt(&self, other: &Self) -> bool {
fn gt(&self, other: &Rhs) -> bool {
match self.partial_cmp(other) {
Some(Greater) => true,
_ => false,
@ -228,7 +228,7 @@ pub trait PartialOrd for Sized?: PartialEq {
/// This method tests greater than or equal to (`>=`).
#[inline]
fn ge(&self, other: &Self) -> bool {
fn ge(&self, other: &Rhs) -> bool {
match self.partial_cmp(other) {
Some(Greater) | Some(Equal) => true,
_ => false,
@ -240,7 +240,7 @@ pub trait PartialOrd for Sized?: PartialEq {
/// 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`
/// values to look up entries in a container with `String` keys.
#[experimental = "Better solutions may be discovered."]
#[deprecated = "Use overloaded core::cmp::PartialEq"]
pub trait Equiv<Sized? T> for Sized? {
/// Implement this function to decide equivalent values.
fn equiv(&self, other: &T) -> bool;
@ -400,11 +400,11 @@ mod impls {
// & pointers
#[unstable = "Trait is unstable."]
impl<'a, Sized? T: PartialEq> PartialEq for &'a T {
impl<'a, 'b, Sized? A, Sized? B> PartialEq<&'b B> for &'a A where A: PartialEq<B> {
#[inline]
fn eq(&self, other: & &'a T) -> bool { PartialEq::eq(*self, *other) }
fn eq(&self, other: & &'b B) -> bool { PartialEq::eq(*self, *other) }
#[inline]
fn ne(&self, other: & &'a T) -> bool { PartialEq::ne(*self, *other) }
fn ne(&self, other: & &'b B) -> bool { PartialEq::ne(*self, *other) }
}
#[unstable = "Trait is unstable."]
impl<'a, Sized? T: PartialOrd> PartialOrd for &'a T {
@ -432,11 +432,11 @@ mod impls {
// &mut pointers
#[unstable = "Trait is unstable."]
impl<'a, Sized? T: PartialEq> PartialEq for &'a mut T {
impl<'a, 'b, Sized? A, Sized? B> PartialEq<&'b mut B> for &'a mut A where A: PartialEq<B> {
#[inline]
fn eq(&self, other: &&'a mut T) -> bool { PartialEq::eq(*self, *other) }
fn eq(&self, other: &&'b mut B) -> bool { PartialEq::eq(*self, *other) }
#[inline]
fn ne(&self, other: &&'a mut T) -> bool { PartialEq::ne(*self, *other) }
fn ne(&self, other: &&'b mut B) -> bool { PartialEq::ne(*self, *other) }
}
#[unstable = "Trait is unstable."]
impl<'a, Sized? T: PartialOrd> PartialOrd for &'a mut T {
@ -460,4 +460,18 @@ mod impls {
}
#[unstable = "Trait is unstable."]
impl<'a, Sized? T: Eq> Eq for &'a mut T {}
impl<'a, 'b, Sized? A, Sized? B> PartialEq<&'b mut B> for &'a A where A: PartialEq<B> {
#[inline]
fn eq(&self, other: &&'b mut B) -> bool { PartialEq::eq(*self, *other) }
#[inline]
fn ne(&self, other: &&'b mut B) -> bool { PartialEq::ne(*self, *other) }
}
impl<'a, 'b, Sized? A, Sized? B> PartialEq<&'b B> for &'a mut A where A: PartialEq<B> {
#[inline]
fn eq(&self, other: &&'b B) -> bool { PartialEq::eq(*self, *other) }
#[inline]
fn ne(&self, other: &&'b B) -> bool { PartialEq::ne(*self, *other) }
}
}

View file

@ -226,7 +226,7 @@ extern "rust-intrinsic" {
/// use std::mem;
///
/// let v: &[u8] = unsafe { mem::transmute("L") };
/// assert!(v == &[76u8]);
/// assert!(v == [76u8]);
/// ```
pub fn transmute<T,U>(e: T) -> U;

View file

@ -2473,7 +2473,11 @@ pub mod order {
}
/// 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 {
pub fn eq<A, B, L, R>(mut a: L, mut b: R) -> bool where
A: PartialEq<B>,
L: Iterator<A>,
R: Iterator<B>,
{
loop {
match (a.next(), b.next()) {
(None, None) => return true,
@ -2484,7 +2488,11 @@ pub mod order {
}
/// Compare `a` and `b` for nonequality (Using partial equality, `PartialEq`)
pub fn ne<A: PartialEq, T: Iterator<A>, S: Iterator<A>>(mut a: T, mut b: S) -> bool {
pub fn ne<A, B, L, R>(mut a: L, mut b: R) -> bool where
A: PartialEq<B>,
L: Iterator<A>,
R: Iterator<B>,
{
loop {
match (a.next(), b.next()) {
(None, None) => return false,

View file

@ -59,6 +59,7 @@
#![allow(unknown_features)]
#![feature(globs, intrinsics, lang_items, macro_rules, phase)]
#![feature(simd, unsafe_destructor, slicing_syntax)]
#![feature(default_type_params)]
#![deny(missing_docs)]
mod macros;

View file

@ -274,9 +274,9 @@ impl<T> Option<T> {
/// let mut x = Some("Diamonds");
/// {
/// let v = x.as_mut_slice();
/// assert!(v == &mut ["Diamonds"]);
/// assert!(v == ["Diamonds"]);
/// v[0] = "Dirt";
/// assert!(v == &mut ["Dirt"]);
/// assert!(v == ["Dirt"]);
/// }
/// assert_eq!(x, Some("Dirt"));
/// ```
@ -554,7 +554,7 @@ impl<T> Option<T> {
///
/// let x = None;
/// let v: Vec<&str> = x.into_iter().collect();
/// assert_eq!(v, vec![]);
/// assert!(v.is_empty());
/// ```
#[inline]
#[unstable = "waiting for iterator conventions"]

View file

@ -321,12 +321,16 @@ impl<T> PartialEq for *mut T {
impl<T> Eq for *mut T {}
// Equivalence for pointers
#[allow(deprecated)]
#[deprecated = "Use overloaded `core::cmp::PartialEq`"]
impl<T> Equiv<*mut T> for *const T {
fn equiv(&self, other: &*mut T) -> bool {
self.to_uint() == other.to_uint()
}
}
#[allow(deprecated)]
#[deprecated = "Use overloaded `core::cmp::PartialEq`"]
impl<T> Equiv<*const T> for *mut T {
fn equiv(&self, other: &*const T) -> bool {
self.to_uint() == other.to_uint()

View file

@ -407,14 +407,14 @@ impl<T, E> Result<T, E> {
/// let mut x: Result<&str, uint> = Ok("Gold");
/// {
/// let v = x.as_mut_slice();
/// assert!(v == &mut ["Gold"]);
/// assert!(v == ["Gold"]);
/// v[0] = "Silver";
/// assert!(v == &mut ["Silver"]);
/// assert!(v == ["Silver"]);
/// }
/// assert_eq!(x, Ok("Silver"));
///
/// let mut x: Result<&str, uint> = Err(45);
/// assert!(x.as_mut_slice() == &mut []);
/// assert!(x.as_mut_slice().is_empty());
/// ```
#[inline]
#[unstable = "waiting for mut conventions"]

View file

@ -374,20 +374,20 @@ pub trait SlicePrelude<T> for Sized? {
/// // scoped to restrict the lifetime of the borrows
/// {
/// let (left, right) = v.split_at_mut(0);
/// assert!(left == &mut []);
/// assert!(right == &mut [1i, 2, 3, 4, 5, 6]);
/// assert!(left == []);
/// assert!(right == [1i, 2, 3, 4, 5, 6]);
/// }
///
/// {
/// let (left, right) = v.split_at_mut(2);
/// assert!(left == &mut [1i, 2]);
/// assert!(right == &mut [3i, 4, 5, 6]);
/// assert!(left == [1i, 2]);
/// assert!(right == [3i, 4, 5, 6]);
/// }
///
/// {
/// let (left, right) = v.split_at_mut(6);
/// assert!(left == &mut [1i, 2, 3, 4, 5, 6]);
/// assert!(right == &mut []);
/// assert!(left == [1i, 2, 3, 4, 5, 6]);
/// assert!(right == []);
/// }
/// ```
#[unstable = "waiting on final error conventions"]
@ -1802,12 +1802,12 @@ pub mod bytes {
//
#[unstable = "waiting for DST"]
impl<T: PartialEq> PartialEq for [T] {
fn eq(&self, other: &[T]) -> bool {
impl<A, B> PartialEq<[B]> for [A] where A: PartialEq<B> {
fn eq(&self, other: &[B]) -> bool {
self.len() == other.len() &&
order::eq(self.iter(), other.iter())
}
fn ne(&self, other: &[T]) -> bool {
fn ne(&self, other: &[B]) -> bool {
self.len() != other.len() ||
order::ne(self.iter(), other.iter())
}
@ -1816,13 +1816,15 @@ impl<T: PartialEq> PartialEq for [T] {
#[unstable = "waiting for DST"]
impl<T: Eq> Eq for [T] {}
#[unstable = "waiting for DST"]
#[allow(deprecated)]
#[deprecated = "Use overloaded `core::cmp::PartialEq`"]
impl<T: PartialEq, Sized? V: AsSlice<T>> Equiv<V> for [T] {
#[inline]
fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }
}
#[unstable = "waiting for DST"]
#[allow(deprecated)]
#[deprecated = "Use overloaded `core::cmp::PartialEq`"]
impl<'a,T:PartialEq, Sized? V: AsSlice<T>> Equiv<V> for &'a mut [T] {
#[inline]
fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() }

View file

@ -1248,6 +1248,8 @@ pub mod traits {
}
}
#[allow(deprecated)]
#[deprecated = "Use overloaded `core::cmp::PartialEq`"]
impl<S: Str> Equiv<S> for str {
#[inline]
fn equiv(&self, other: &S) -> bool { eq_slice(self, other.as_slice()) }

View file

@ -109,7 +109,7 @@ fn test_transmute() {
}
unsafe {
assert!(vec![76u8] == transmute("L".to_string()));
assert!(vec![76u8] == transmute::<_, Vec<u8>>("L".to_string()));
}
}

View file

@ -96,6 +96,7 @@ impl<'a, T: Ord> Ord for MaybeOwnedVector<'a, T> {
}
}
#[allow(deprecated)]
impl<'a, T: PartialEq, Sized? V: AsSlice<T>> Equiv<V> for MaybeOwnedVector<'a, T> {
fn equiv(&self, other: &V) -> bool {
self.as_slice() == other.as_slice()

View file

@ -1377,7 +1377,7 @@ impl MissingDoc {
let has_doc = attrs.iter().any(|a| {
match a.node.value.node {
ast::MetaNameValue(ref name, _) if name.equiv(&("doc")) => true,
ast::MetaNameValue(ref name, _) if *name == "doc" => true,
_ => false
}
});

View file

@ -105,7 +105,7 @@ fn warn_if_multiple_versions(diag: &SpanHandler, cstore: &CStore) {
}
fn visit_crate(e: &Env, c: &ast::Crate) {
for a in c.attrs.iter().filter(|m| m.name().equiv(&("link_args"))) {
for a in c.attrs.iter().filter(|m| m.name() == "link_args") {
match a.value_str() {
Some(ref linkarg) => e.sess.cstore.add_used_link_args(linkarg.get()),
None => { /* fallthrough */ }
@ -205,7 +205,7 @@ fn visit_item(e: &Env, i: &ast::Item) {
// First, add all of the custom link_args attributes
let link_args = i.attrs.iter()
.filter_map(|at| if at.name().equiv(&("link_args")) {
.filter_map(|at| if at.name() == "link_args" {
Some(at)
} else {
None
@ -220,7 +220,7 @@ fn visit_item(e: &Env, i: &ast::Item) {
// Next, process all of the #[link(..)]-style arguments
let link_args = i.attrs.iter()
.filter_map(|at| if at.name().equiv(&("link")) {
.filter_map(|at| if at.name() == "link" {
Some(at)
} else {
None
@ -230,18 +230,18 @@ fn visit_item(e: &Env, i: &ast::Item) {
match m.meta_item_list() {
Some(items) => {
let kind = items.iter().find(|k| {
k.name().equiv(&("kind"))
k.name() == "kind"
}).and_then(|a| a.value_str());
let kind = match kind {
Some(k) => {
if k.equiv(&("static")) {
if k == "static" {
cstore::NativeStatic
} else if e.sess.target.target.options.is_like_osx
&& k.equiv(&("framework")) {
&& k == "framework" {
cstore::NativeFramework
} else if k.equiv(&("framework")) {
} else if k == "framework" {
cstore::NativeFramework
} else if k.equiv(&("dylib")) {
} else if k == "dylib" {
cstore::NativeUnknown
} else {
e.sess.span_err(m.span,
@ -253,7 +253,7 @@ fn visit_item(e: &Env, i: &ast::Item) {
None => cstore::NativeUnknown
};
let n = items.iter().find(|n| {
n.name().equiv(&("name"))
n.name() == "name"
}).and_then(|a| a.value_str());
let n = match n {
Some(n) => n,

View file

@ -40,7 +40,7 @@ fn replace_newline_with_backslash_l(s: String) -> String {
let mut last_two: Vec<_> =
s.as_slice().chars().rev().take(2).collect();
last_two.reverse();
if last_two.as_slice() != &['\\', 'l'] {
if last_two != ['\\', 'l'] {
s.push_str("\\l");
}
s

View file

@ -944,7 +944,7 @@ mod test {
let sessopts = build_session_options(matches);
let sess = build_session(sessopts, None, registry);
let cfg = build_configuration(&sess);
let mut test_items = cfg.iter().filter(|m| m.name().equiv(&("test")));
let mut test_items = cfg.iter().filter(|m| m.name() == "test");
assert!(test_items.next().is_some());
assert!(test_items.next().is_none());
}

View file

@ -156,7 +156,7 @@ mod test {
"rpath2".to_string(),
"rpath1".to_string()
]);
assert!(res.as_slice() == &[
assert!(res.as_slice() == [
"rpath1".to_string(),
"rpath2".to_string()
]);
@ -176,7 +176,7 @@ mod test {
"4a".to_string(),
"3".to_string()
]);
assert!(res.as_slice() == &[
assert!(res.as_slice() == [
"1a".to_string(),
"2".to_string(),
"4a".to_string(),

View file

@ -679,19 +679,19 @@ pub fn collect_crate_types(session: &Session,
let attr_types: Vec<config::CrateType> = attrs.iter().filter_map(|a| {
if a.check_name("crate_type") {
match a.value_str() {
Some(ref n) if n.equiv(&("rlib")) => {
Some(ref n) if *n == "rlib" => {
Some(config::CrateTypeRlib)
}
Some(ref n) if n.equiv(&("dylib")) => {
Some(ref n) if *n == "dylib" => {
Some(config::CrateTypeDylib)
}
Some(ref n) if n.equiv(&("lib")) => {
Some(ref n) if *n == "lib" => {
Some(config::default_lib_output())
}
Some(ref n) if n.equiv(&("staticlib")) => {
Some(ref n) if *n == "staticlib" => {
Some(config::CrateTypeStaticlib)
}
Some(ref n) if n.equiv(&("bin")) => Some(config::CrateTypeExecutable),
Some(ref n) if *n == "bin" => Some(config::CrateTypeExecutable),
Some(_) => {
session.add_lint(lint::builtin::UNKNOWN_CRATE_TYPES,
ast::CRATE_NODE_ID,

View file

@ -1545,7 +1545,7 @@ fn compile_unit_metadata(cx: &CrateContext) {
Some(ref p) if p.is_relative() => {
// prepend "./" if necessary
let dotdot = b"..";
let prefix = &[dotdot[0], ::std::path::SEP_BYTE];
let prefix = [dotdot[0], ::std::path::SEP_BYTE];
let mut path_bytes = p.as_vec().to_vec();
if path_bytes.slice_to(2) != prefix &&

View file

@ -172,7 +172,7 @@ pub fn main_args(args: &[String]) -> int {
}
}
if matches.opt_strs("passes").as_slice() == &["list".to_string()] {
if matches.opt_strs("passes") == ["list"] {
println!("Available passes for running rustdoc:");
for &(name, _, description) in PASSES.iter() {
println!("{:>20} - {}", name, description);

View file

@ -432,12 +432,14 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
table::make_hash(&self.hasher, x)
}
#[allow(deprecated)]
fn search_equiv<'a, Sized? Q: Hash<S> + Equiv<K>>(&'a self, q: &Q)
-> Option<FullBucketImm<'a, K, V>> {
let hash = self.make_hash(q);
search_hashed(&self.table, &hash, |k| q.equiv(k)).into_option()
}
#[allow(deprecated)]
fn search_equiv_mut<'a, Sized? Q: Hash<S> + Equiv<K>>(&'a mut self, q: &Q)
-> Option<FullBucketMut<'a, K, V>> {
let hash = self.make_hash(q);

View file

@ -1528,7 +1528,7 @@ mod test {
check!(File::create(&tmpdir.join("test")).write(&bytes));
let actual = check!(File::open(&tmpdir.join("test")).read_to_end());
assert!(actual.as_slice() == &bytes);
assert!(actual == bytes.as_slice());
}
#[test]

View file

@ -2034,7 +2034,7 @@ mod tests {
fn split_paths_windows() {
fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
split_paths(unparsed) ==
parsed.iter().map(|s| Path::new(*s)).collect()
parsed.iter().map(|s| Path::new(*s)).collect::<Vec<_>>()
}
assert!(check_parse("", &mut [""]));
@ -2054,7 +2054,7 @@ mod tests {
fn split_paths_unix() {
fn check_parse(unparsed: &str, parsed: &[&str]) -> bool {
split_paths(unparsed) ==
parsed.iter().map(|s| Path::new(*s)).collect()
parsed.iter().map(|s| Path::new(*s)).collect::<Vec<_>>()
}
assert!(check_parse("", &mut [""]));

View file

@ -443,7 +443,6 @@ static dot_dot_static: &'static [u8] = b"..";
mod tests {
use prelude::*;
use super::*;
use mem;
use str;
use str::StrPrelude;
@ -601,10 +600,8 @@ mod tests {
macro_rules! t(
(s: $path:expr, $op:ident, $exp:expr) => (
{
unsafe {
let path = Path::new($path);
assert!(path.$op() == mem::transmute(($exp).as_bytes()));
}
let path = Path::new($path);
assert!(path.$op() == ($exp).as_bytes());
}
);
(s: $path:expr, $op:ident, $exp:expr, opt) => (
@ -616,11 +613,9 @@ mod tests {
);
(v: $path:expr, $op:ident, $exp:expr) => (
{
unsafe {
let arg = $path;
let path = Path::new(arg);
assert!(path.$op() == mem::transmute($exp));
}
let arg = $path;
let path = Path::new(arg);
assert!(path.$op() == $exp);
}
);
)
@ -668,9 +663,8 @@ mod tests {
t!(v: b"hi/there.txt", extension, Some(b"txt"));
t!(v: b"hi/there\x80.txt", extension, Some(b"txt"));
t!(v: b"hi/there.t\x80xt", extension, Some(b"t\x80xt"));
let no: Option<&'static [u8]> = None;
t!(v: b"hi/there", extension, no);
t!(v: b"hi/there\x80", extension, no);
t!(v: b"hi/there", extension, None);
t!(v: b"hi/there\x80", extension, None);
t!(s: "hi/there.txt", extension, Some("txt"), opt);
t!(s: "hi/there", extension, None, opt);
t!(s: "there.txt", extension, Some("txt"), opt);
@ -959,62 +953,57 @@ mod tests {
macro_rules! t(
(s: $path:expr, $filename:expr, $dirname:expr, $filestem:expr, $ext:expr) => (
{
unsafe {
let path = $path;
let filename = $filename;
assert!(path.filename_str() == filename,
"{}.filename_str(): Expected `{}`, found {}",
path.as_str().unwrap(), filename, path.filename_str());
let dirname = $dirname;
assert!(path.dirname_str() == dirname,
"`{}`.dirname_str(): Expected `{}`, found `{}`",
path.as_str().unwrap(), dirname, path.dirname_str());
let filestem = $filestem;
assert!(path.filestem_str() == filestem,
"`{}`.filestem_str(): Expected `{}`, found `{}`",
path.as_str().unwrap(), filestem, path.filestem_str());
let ext = $ext;
assert!(path.extension_str() == mem::transmute(ext),
"`{}`.extension_str(): Expected `{}`, found `{}`",
path.as_str().unwrap(), ext, path.extension_str());
}
let path = $path;
let filename = $filename;
assert!(path.filename_str() == filename,
"{}.filename_str(): Expected `{}`, found {}",
path.as_str().unwrap(), filename, path.filename_str());
let dirname = $dirname;
assert!(path.dirname_str() == dirname,
"`{}`.dirname_str(): Expected `{}`, found `{}`",
path.as_str().unwrap(), dirname, path.dirname_str());
let filestem = $filestem;
assert!(path.filestem_str() == filestem,
"`{}`.filestem_str(): Expected `{}`, found `{}`",
path.as_str().unwrap(), filestem, path.filestem_str());
let ext = $ext;
assert!(path.extension_str() == ext,
"`{}`.extension_str(): Expected `{}`, found `{}`",
path.as_str().unwrap(), ext, path.extension_str());
}
);
(v: $path:expr, $filename:expr, $dirname:expr, $filestem:expr, $ext:expr) => (
{
unsafe {
let path = $path;
assert!(path.filename() == mem::transmute($filename));
assert!(path.dirname() == mem::transmute($dirname));
assert!(path.filestem() == mem::transmute($filestem));
assert!(path.extension() == mem::transmute($ext));
}
let path = $path;
assert!(path.filename() == $filename);
assert!(path.dirname() == $dirname);
assert!(path.filestem() == $filestem);
assert!(path.extension() == $ext);
}
)
)
let no: Option<&'static str> = None;
t!(v: Path::new(b"a/b/c"), Some(b"c"), b"a/b", Some(b"c"), no);
t!(v: Path::new(b"a/b/\xFF"), Some(b"\xFF"), b"a/b", Some(b"\xFF"), no);
t!(v: Path::new(b"a/b/c"), Some(b"c"), b"a/b", Some(b"c"), None);
t!(v: Path::new(b"a/b/\xFF"), Some(b"\xFF"), b"a/b", Some(b"\xFF"), None);
t!(v: Path::new(b"hi/there.\xFF"), Some(b"there.\xFF"), b"hi",
Some(b"there"), Some(b"\xFF"));
t!(s: Path::new("a/b/c"), Some("c"), Some("a/b"), Some("c"), no);
t!(s: Path::new("."), None, Some("."), None, no);
t!(s: Path::new("/"), None, Some("/"), None, no);
t!(s: Path::new(".."), None, Some(".."), None, no);
t!(s: Path::new("../.."), None, Some("../.."), None, no);
t!(s: Path::new("a/b/c"), Some("c"), Some("a/b"), Some("c"), None);
t!(s: Path::new("."), None, Some("."), None, None);
t!(s: Path::new("/"), None, Some("/"), None, None);
t!(s: Path::new(".."), None, Some(".."), None, None);
t!(s: Path::new("../.."), None, Some("../.."), None, None);
t!(s: Path::new("hi/there.txt"), Some("there.txt"), Some("hi"),
Some("there"), Some("txt"));
t!(s: Path::new("hi/there"), Some("there"), Some("hi"), Some("there"), no);
t!(s: Path::new("hi/there"), Some("there"), Some("hi"), Some("there"), None);
t!(s: Path::new("hi/there."), Some("there."), Some("hi"),
Some("there"), Some(""));
t!(s: Path::new("hi/.there"), Some(".there"), Some("hi"), Some(".there"), no);
t!(s: Path::new("hi/.there"), Some(".there"), Some("hi"), Some(".there"), None);
t!(s: Path::new("hi/..there"), Some("..there"), Some("hi"),
Some("."), Some("there"));
t!(s: Path::new(b"a/b/\xFF"), None, Some("a/b"), None, no);
t!(s: Path::new(b"a/b/\xFF"), None, Some("a/b"), None, None);
t!(s: Path::new(b"a/b/\xFF.txt"), None, Some("a/b"), None, Some("txt"));
t!(s: Path::new(b"a/b/c.\x80"), None, Some("a/b"), Some("c"), no);
t!(s: Path::new(b"\xFF/b"), Some("b"), None, Some("b"), no);
t!(s: Path::new(b"a/b/c.\x80"), None, Some("a/b"), Some("c"), None);
t!(s: Path::new(b"\xFF/b"), Some("b"), None, Some("b"), None);
}
#[test]

View file

@ -1115,7 +1115,6 @@ fn prefix_len(p: Option<PathPrefix>) -> uint {
#[cfg(test)]
mod tests {
use mem;
use prelude::*;
use super::*;
use super::parse_prefix;
@ -1358,11 +1357,9 @@ mod tests {
macro_rules! t(
(s: $path:expr, $op:ident, $exp:expr) => (
{
unsafe {
let path = $path;
let path = Path::new(path);
assert!(path.$op() == Some(mem::transmute($exp)));
}
let path = $path;
let path = Path::new(path);
assert!(path.$op() == Some($exp));
}
);
(s: $path:expr, $op:ident, $exp:expr, opt) => (
@ -1375,11 +1372,9 @@ mod tests {
);
(v: $path:expr, $op:ident, $exp:expr) => (
{
unsafe {
let path = $path;
let path = Path::new(path);
assert!(path.$op() == mem::transmute($exp));
}
let path = $path;
let path = Path::new(path);
assert!(path.$op() == $exp);
}
)
)
@ -1464,8 +1459,7 @@ mod tests {
// filestem is based on filename, so we don't need the full set of prefix tests
t!(v: b"hi\\there.txt", extension, Some(b"txt"));
let no: Option<&'static [u8]> = None;
t!(v: b"hi\\there", extension, no);
t!(v: b"hi\\there", extension, None);
t!(s: "hi\\there.txt", extension_str, Some("txt"), opt);
t!(s: "hi\\there", extension_str, None, opt);
t!(s: "there.txt", extension_str, Some("txt"), opt);
@ -1872,53 +1866,48 @@ mod tests {
macro_rules! t(
(s: $path:expr, $filename:expr, $dirname:expr, $filestem:expr, $ext:expr) => (
{
unsafe {
let path = $path;
let filename = $filename;
assert!(path.filename_str() == filename,
"`{}`.filename_str(): Expected `{}`, found `{}`",
path.as_str().unwrap(), filename, path.filename_str());
let dirname = $dirname;
assert!(path.dirname_str() == dirname,
"`{}`.dirname_str(): Expected `{}`, found `{}`",
path.as_str().unwrap(), dirname, path.dirname_str());
let filestem = $filestem;
assert!(path.filestem_str() == filestem,
"`{}`.filestem_str(): Expected `{}`, found `{}`",
path.as_str().unwrap(), filestem, path.filestem_str());
let ext = $ext;
assert!(path.extension_str() == mem::transmute(ext),
"`{}`.extension_str(): Expected `{}`, found `{}`",
path.as_str().unwrap(), ext, path.extension_str());
}
let path = $path;
let filename = $filename;
assert!(path.filename_str() == filename,
"`{}`.filename_str(): Expected `{}`, found `{}`",
path.as_str().unwrap(), filename, path.filename_str());
let dirname = $dirname;
assert!(path.dirname_str() == dirname,
"`{}`.dirname_str(): Expected `{}`, found `{}`",
path.as_str().unwrap(), dirname, path.dirname_str());
let filestem = $filestem;
assert!(path.filestem_str() == filestem,
"`{}`.filestem_str(): Expected `{}`, found `{}`",
path.as_str().unwrap(), filestem, path.filestem_str());
let ext = $ext;
assert!(path.extension_str() == ext,
"`{}`.extension_str(): Expected `{}`, found `{}`",
path.as_str().unwrap(), ext, path.extension_str());
}
);
(v: $path:expr, $filename:expr, $dirname:expr, $filestem:expr, $ext:expr) => (
{
unsafe {
let path = $path;
assert!(path.filename() == mem::transmute($filename));
assert!(path.dirname() == mem::transmute($dirname));
assert!(path.filestem() == mem::transmute($filestem));
assert!(path.extension() == mem::transmute($ext));
}
let path = $path;
assert!(path.filename() == $filename);
assert!(path.dirname() == $dirname);
assert!(path.filestem() == $filestem);
assert!(path.extension() == $ext);
}
)
)
let no: Option<&'static str> = None;
t!(v: Path::new(b"a\\b\\c"), Some(b"c"), b"a\\b", Some(b"c"), no);
t!(s: Path::new("a\\b\\c"), Some("c"), Some("a\\b"), Some("c"), no);
t!(s: Path::new("."), None, Some("."), None, no);
t!(s: Path::new("\\"), None, Some("\\"), None, no);
t!(s: Path::new(".."), None, Some(".."), None, no);
t!(s: Path::new("..\\.."), None, Some("..\\.."), None, no);
t!(v: Path::new(b"a\\b\\c"), Some(b"c"), b"a\\b", Some(b"c"), None);
t!(s: Path::new("a\\b\\c"), Some("c"), Some("a\\b"), Some("c"), None);
t!(s: Path::new("."), None, Some("."), None, None);
t!(s: Path::new("\\"), None, Some("\\"), None, None);
t!(s: Path::new(".."), None, Some(".."), None, None);
t!(s: Path::new("..\\.."), None, Some("..\\.."), None, None);
t!(s: Path::new("hi\\there.txt"), Some("there.txt"), Some("hi"),
Some("there"), Some("txt"));
t!(s: Path::new("hi\\there"), Some("there"), Some("hi"), Some("there"), no);
t!(s: Path::new("hi\\there"), Some("there"), Some("hi"), Some("there"), None);
t!(s: Path::new("hi\\there."), Some("there."), Some("hi"),
Some("there"), Some(""));
t!(s: Path::new("hi\\.there"), Some(".there"), Some("hi"), Some(".there"), no);
t!(s: Path::new("hi\\.there"), Some(".there"), Some("hi"), Some(".there"), None);
t!(s: Path::new("hi\\..there"), Some("..there"), Some("hi"),
Some("."), Some("there"));

View file

@ -287,11 +287,11 @@ pub fn find_inline_attr(attrs: &[Attribute]) -> InlineAttr {
// FIXME (#2809)---validate the usage of #[inline] and #[inline]
attrs.iter().fold(InlineNone, |ia,attr| {
match attr.node.value.node {
MetaWord(ref n) if n.equiv(&("inline")) => {
MetaWord(ref n) if *n == "inline" => {
mark_used(attr);
InlineHint
}
MetaList(ref n, ref items) if n.equiv(&("inline")) => {
MetaList(ref n, ref items) if *n == "inline" => {
mark_used(attr);
if contains_name(items.as_slice(), "always") {
InlineAlways
@ -409,7 +409,7 @@ pub fn require_unique_names(diagnostic: &SpanHandler, metas: &[P<MetaItem>]) {
pub fn find_repr_attrs(diagnostic: &SpanHandler, attr: &Attribute) -> Vec<ReprAttr> {
let mut acc = Vec::new();
match attr.node.value.node {
ast::MetaList(ref s, ref items) if s.equiv(&("repr")) => {
ast::MetaList(ref s, ref items) if *s == "repr" => {
mark_used(attr);
for item in items.iter() {
match item.node {

View file

@ -148,7 +148,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
let (s, _str_style) = p.parse_str();
if OPTIONS.iter().any(|opt| s.equiv(opt)) {
if OPTIONS.iter().any(|&opt| s == opt) {
cx.span_warn(p.last_span, "expected a clobber, found an option");
}
clobs.push(s);
@ -157,13 +157,13 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
Options => {
let (option, _str_style) = p.parse_str();
if option.equiv(&("volatile")) {
if option == "volatile" {
// Indicates that the inline assembly has side effects
// and must not be optimized out along with its outputs.
volatile = true;
} else if option.equiv(&("alignstack")) {
} else if option == "alignstack" {
alignstack = true;
} else if option.equiv(&("intel")) {
} else if option == "intel" {
dialect = ast::AsmIntel;
} else {
cx.span_warn(p.last_span, "unrecognized option");

View file

@ -172,12 +172,12 @@ impl<'a, 'v> Visitor<'v> for Context<'a> {
fn visit_item(&mut self, i: &ast::Item) {
for attr in i.attrs.iter() {
if attr.name().equiv(&("thread_local")) {
if attr.name() == "thread_local" {
self.gate_feature("thread_local", i.span,
"`#[thread_local]` is an experimental feature, and does not \
currently handle destructors. There is no corresponding \
`#[task_local]` mapping to the task model");
} else if attr.name().equiv(&("linkage")) {
} else if attr.name() == "linkage" {
self.gate_feature("linkage", i.span,
"the `linkage` attribute is experimental \
and not portable across platforms")
@ -429,7 +429,7 @@ pub fn check_crate(span_handler: &SpanHandler, krate: &ast::Crate) -> (Features,
}
};
match KNOWN_FEATURES.iter()
.find(|& &(n, _)| name.equiv(&n)) {
.find(|& &(n, _)| name == n) {
Some(&(name, Active)) => { cx.features.push(name); }
Some(&(_, Removed)) => {
span_handler.span_err(mi.span, "feature has been removed");

View file

@ -117,7 +117,7 @@ impl<'a> ParserObsoleteMethods for parser::Parser<'a> {
fn is_obsolete_ident(&mut self, ident: &str) -> bool {
match self.token {
token::Ident(sid, _) => {
token::get_ident(sid).equiv(&ident)
token::get_ident(sid) == ident
}
_ => false
}

View file

@ -623,12 +623,35 @@ impl fmt::Show for InternedString {
}
}
#[allow(deprecated)]
impl<'a> Equiv<&'a str> for InternedString {
fn equiv(&self, other: & &'a str) -> bool {
(*other) == self.string.as_slice()
}
}
impl<'a> PartialEq<&'a str> for InternedString {
#[inline(always)]
fn eq(&self, other: & &'a str) -> bool {
PartialEq::eq(self.string.as_slice(), *other)
}
#[inline(always)]
fn ne(&self, other: & &'a str) -> bool {
PartialEq::ne(self.string.as_slice(), *other)
}
}
impl<'a> PartialEq<InternedString > for &'a str {
#[inline(always)]
fn eq(&self, other: &InternedString) -> bool {
PartialEq::eq(*self, other.string.as_slice())
}
#[inline(always)]
fn ne(&self, other: &InternedString) -> bool {
PartialEq::ne(*self, other.string.as_slice())
}
}
impl<D:Decoder<E>, E> Decodable<D, E> for InternedString {
fn decode(d: &mut D) -> Result<InternedString, E> {
Ok(get_name(get_ident_interner().intern(

View file

@ -224,10 +224,10 @@ mod test {
assert_eq!(Vec::new(), v);
let v = SmallVector::one(1i);
assert_eq!(vec!(1i), v.into_iter().collect());
assert_eq!(vec!(1i), v.into_iter().collect::<Vec<_>>());
let v = SmallVector::many(vec!(1i, 2i, 3i));
assert_eq!(vec!(1i, 2i, 3i), v.into_iter().collect());
assert_eq!(vec!(1i, 2i, 3i), v.into_iter().collect::<Vec<_>>());
}
#[test]

View file

@ -582,13 +582,13 @@ mod test {
fn test_basic_setabf() {
let s = b"\\E[48;5;%p1%dm";
assert_eq!(expand(s, &[Number(1)], &mut Variables::new()).unwrap(),
"\\E[48;5;1m".bytes().collect());
"\\E[48;5;1m".bytes().collect::<Vec<_>>());
}
#[test]
fn test_multiple_int_constants() {
assert_eq!(expand(b"%{1}%{2}%d%d", &[], &mut Variables::new()).unwrap(),
"21".bytes().collect());
"21".bytes().collect::<Vec<_>>());
}
#[test]
@ -596,9 +596,9 @@ mod test {
let mut vars = Variables::new();
assert_eq!(expand(b"%p1%d%p2%d%p3%d%i%p1%d%p2%d%p3%d",
&[Number(1),Number(2),Number(3)], &mut vars),
Ok("123233".bytes().collect()));
Ok("123233".bytes().collect::<Vec<_>>()));
assert_eq!(expand(b"%p1%d%p2%d%i%p1%d%p2%d", &[], &mut vars),
Ok("0011".bytes().collect()));
Ok("0011".bytes().collect::<Vec<_>>()));
}
#[test]
@ -672,15 +672,15 @@ mod test {
let res = expand(s, &[Number(1)], &mut vars);
assert!(res.is_ok(), res.unwrap_err());
assert_eq!(res.unwrap(),
"\\E[31m".bytes().collect());
"\\E[31m".bytes().collect::<Vec<_>>());
let res = expand(s, &[Number(8)], &mut vars);
assert!(res.is_ok(), res.unwrap_err());
assert_eq!(res.unwrap(),
"\\E[90m".bytes().collect());
"\\E[90m".bytes().collect::<Vec<_>>());
let res = expand(s, &[Number(42)], &mut vars);
assert!(res.is_ok(), res.unwrap_err());
assert_eq!(res.unwrap(),
"\\E[38;5;42m".bytes().collect());
"\\E[38;5;42m".bytes().collect::<Vec<_>>());
}
#[test]
@ -692,13 +692,13 @@ mod test {
Words("foo".to_string()),
Words("f".to_string()),
Words("foo".to_string())], vars),
Ok("foofoo ffo".bytes().collect()));
Ok("foofoo ffo".bytes().collect::<Vec<_>>()));
assert_eq!(expand(b"%p1%:-4.2s", &[Words("foo".to_string())], vars),
Ok("fo ".bytes().collect()));
Ok("fo ".bytes().collect::<Vec<_>>()));
assert_eq!(expand(b"%p1%d%p1%.3d%p1%5d%p1%:+d", &[Number(1)], vars),
Ok("1001 1+1".bytes().collect()));
Ok("1001 1+1".bytes().collect::<Vec<_>>()));
assert_eq!(expand(b"%p1%o%p1%#o%p2%6.4x%p2%#6.4X", &[Number(15), Number(27)], vars),
Ok("17017 001b0X001B".bytes().collect()));
Ok("17017 001b0X001B".bytes().collect::<Vec<_>>()));
}
}

View file

@ -0,0 +1,37 @@
// 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(default_type_params)]
#[deriving(PartialEq)]
struct Bar;
struct Baz;
struct Foo;
struct Fu;
impl PartialEq for Baz { fn eq(&self, _: &Baz) -> bool { true } }
impl PartialEq<Fu> for Foo { fn eq(&self, _: &Fu) -> bool { true } }
impl PartialEq<Foo> for Fu { fn eq(&self, _: &Foo) -> bool { true } }
impl PartialEq<Bar> for Foo { fn eq(&self, _: &Bar) -> bool { false } }
impl PartialEq<Foo> for Bar { fn eq(&self, _: &Foo) -> bool { false } }
fn main() {
assert!(Bar != Foo);
assert!(Foo != Bar);
assert!(Bar == Bar);
assert!(Baz == Baz);
assert!(Foo == Fu);
assert!(Fu == Foo);
}

View file

@ -26,5 +26,5 @@ fn main() {
break
}
}
assert!(result.as_slice() == &[2, 4]);
assert!(result == [2, 4]);
}

View file

@ -33,6 +33,6 @@ fn main() {
let out = bar("baz", "foo");
let [a, xs.., d] = out;
assert_eq!(a, "baz");
assert!(xs == &["foo", "foo"]);
assert!(xs == ["foo", "foo"]);
assert_eq!(d, "baz");
}