Skip to content

Commit 470ca1c

Browse files
committed
Auto merge of #32794 - Manishearth:rollup, r=Manishearth
Rollup of 7 pull requests - Successful merges: #32674, #32699, #32711, #32745, #32748, #32757, #32789 - Failed merges:
2 parents 444a118 + b0f81a3 commit 470ca1c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+815
-521
lines changed

src/liballoc/arc.rs

+1
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ impl<T: ?Sized> Arc<T> {
263263
loop {
264264
// check if the weak counter is currently "locked"; if so, spin.
265265
if cur == usize::MAX {
266+
cur = this.inner().weak.load(Relaxed);
266267
continue;
267268
}
268269

src/libcollectionstest/slice.rs

+36-6
Original file line numberDiff line numberDiff line change
@@ -574,18 +574,48 @@ fn test_slice_2() {
574574
assert_eq!(v[1], 3);
575575
}
576576

577+
macro_rules! assert_order {
578+
(Greater, $a:expr, $b:expr) => {
579+
assert_eq!($a.cmp($b), Greater);
580+
assert!($a > $b);
581+
};
582+
(Less, $a:expr, $b:expr) => {
583+
assert_eq!($a.cmp($b), Less);
584+
assert!($a < $b);
585+
};
586+
(Equal, $a:expr, $b:expr) => {
587+
assert_eq!($a.cmp($b), Equal);
588+
assert_eq!($a, $b);
589+
}
590+
}
591+
592+
#[test]
593+
fn test_total_ord_u8() {
594+
let c = &[1u8, 2, 3];
595+
assert_order!(Greater, &[1u8, 2, 3, 4][..], &c[..]);
596+
let c = &[1u8, 2, 3, 4];
597+
assert_order!(Less, &[1u8, 2, 3][..], &c[..]);
598+
let c = &[1u8, 2, 3, 6];
599+
assert_order!(Equal, &[1u8, 2, 3, 6][..], &c[..]);
600+
let c = &[1u8, 2, 3, 4, 5, 6];
601+
assert_order!(Less, &[1u8, 2, 3, 4, 5, 5, 5, 5][..], &c[..]);
602+
let c = &[1u8, 2, 3, 4];
603+
assert_order!(Greater, &[2u8, 2][..], &c[..]);
604+
}
605+
606+
577607
#[test]
578-
fn test_total_ord() {
608+
fn test_total_ord_i32() {
579609
let c = &[1, 2, 3];
580-
[1, 2, 3, 4][..].cmp(c) == Greater;
610+
assert_order!(Greater, &[1, 2, 3, 4][..], &c[..]);
581611
let c = &[1, 2, 3, 4];
582-
[1, 2, 3][..].cmp(c) == Less;
612+
assert_order!(Less, &[1, 2, 3][..], &c[..]);
583613
let c = &[1, 2, 3, 6];
584-
[1, 2, 3, 4][..].cmp(c) == Equal;
614+
assert_order!(Equal, &[1, 2, 3, 6][..], &c[..]);
585615
let c = &[1, 2, 3, 4, 5, 6];
586-
[1, 2, 3, 4, 5, 5, 5, 5][..].cmp(c) == Less;
616+
assert_order!(Less, &[1, 2, 3, 4, 5, 5, 5, 5][..], &c[..]);
587617
let c = &[1, 2, 3, 4];
588-
[2, 2][..].cmp(c) == Greater;
618+
assert_order!(Greater, &[2, 2][..], &c[..]);
589619
}
590620

591621
#[test]

src/libcore/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
#![feature(unwind_attributes)]
7676
#![feature(repr_simd, platform_intrinsics)]
7777
#![feature(rustc_attrs)]
78+
#![feature(specialization)]
7879
#![feature(staged_api)]
7980
#![feature(unboxed_closures)]
8081
#![feature(question_mark)]

src/libcore/slice.rs

+139-16
Original file line numberDiff line numberDiff line change
@@ -1630,12 +1630,60 @@ pub unsafe fn from_raw_parts_mut<'a, T>(p: *mut T, len: usize) -> &'a mut [T] {
16301630
}
16311631

16321632
//
1633-
// Boilerplate traits
1633+
// Comparison traits
16341634
//
16351635

1636+
extern {
1637+
/// Call implementation provided memcmp
1638+
///
1639+
/// Interprets the data as u8.
1640+
///
1641+
/// Return 0 for equal, < 0 for less than and > 0 for greater
1642+
/// than.
1643+
// FIXME(#32610): Return type should be c_int
1644+
fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32;
1645+
}
1646+
16361647
#[stable(feature = "rust1", since = "1.0.0")]
16371648
impl<A, B> PartialEq<[B]> for [A] where A: PartialEq<B> {
16381649
fn eq(&self, other: &[B]) -> bool {
1650+
SlicePartialEq::equal(self, other)
1651+
}
1652+
1653+
fn ne(&self, other: &[B]) -> bool {
1654+
SlicePartialEq::not_equal(self, other)
1655+
}
1656+
}
1657+
1658+
#[stable(feature = "rust1", since = "1.0.0")]
1659+
impl<T: Eq> Eq for [T] {}
1660+
1661+
#[stable(feature = "rust1", since = "1.0.0")]
1662+
impl<T: Ord> Ord for [T] {
1663+
fn cmp(&self, other: &[T]) -> Ordering {
1664+
SliceOrd::compare(self, other)
1665+
}
1666+
}
1667+
1668+
#[stable(feature = "rust1", since = "1.0.0")]
1669+
impl<T: PartialOrd> PartialOrd for [T] {
1670+
fn partial_cmp(&self, other: &[T]) -> Option<Ordering> {
1671+
SlicePartialOrd::partial_compare(self, other)
1672+
}
1673+
}
1674+
1675+
#[doc(hidden)]
1676+
// intermediate trait for specialization of slice's PartialEq
1677+
trait SlicePartialEq<B> {
1678+
fn equal(&self, other: &[B]) -> bool;
1679+
fn not_equal(&self, other: &[B]) -> bool;
1680+
}
1681+
1682+
// Generic slice equality
1683+
impl<A, B> SlicePartialEq<B> for [A]
1684+
where A: PartialEq<B>
1685+
{
1686+
default fn equal(&self, other: &[B]) -> bool {
16391687
if self.len() != other.len() {
16401688
return false;
16411689
}
@@ -1648,7 +1696,8 @@ impl<A, B> PartialEq<[B]> for [A] where A: PartialEq<B> {
16481696

16491697
true
16501698
}
1651-
fn ne(&self, other: &[B]) -> bool {
1699+
1700+
default fn not_equal(&self, other: &[B]) -> bool {
16521701
if self.len() != other.len() {
16531702
return true;
16541703
}
@@ -1663,12 +1712,36 @@ impl<A, B> PartialEq<[B]> for [A] where A: PartialEq<B> {
16631712
}
16641713
}
16651714

1666-
#[stable(feature = "rust1", since = "1.0.0")]
1667-
impl<T: Eq> Eq for [T] {}
1715+
// Use memcmp for bytewise equality when the types allow
1716+
impl<A> SlicePartialEq<A> for [A]
1717+
where A: PartialEq<A> + BytewiseEquality
1718+
{
1719+
fn equal(&self, other: &[A]) -> bool {
1720+
if self.len() != other.len() {
1721+
return false;
1722+
}
1723+
unsafe {
1724+
let size = mem::size_of_val(self);
1725+
memcmp(self.as_ptr() as *const u8,
1726+
other.as_ptr() as *const u8, size) == 0
1727+
}
1728+
}
16681729

1669-
#[stable(feature = "rust1", since = "1.0.0")]
1670-
impl<T: Ord> Ord for [T] {
1671-
fn cmp(&self, other: &[T]) -> Ordering {
1730+
fn not_equal(&self, other: &[A]) -> bool {
1731+
!self.equal(other)
1732+
}
1733+
}
1734+
1735+
#[doc(hidden)]
1736+
// intermediate trait for specialization of slice's PartialOrd
1737+
trait SlicePartialOrd<B> {
1738+
fn partial_compare(&self, other: &[B]) -> Option<Ordering>;
1739+
}
1740+
1741+
impl<A> SlicePartialOrd<A> for [A]
1742+
where A: PartialOrd
1743+
{
1744+
default fn partial_compare(&self, other: &[A]) -> Option<Ordering> {
16721745
let l = cmp::min(self.len(), other.len());
16731746

16741747
// Slice to the loop iteration range to enable bound check
@@ -1677,19 +1750,33 @@ impl<T: Ord> Ord for [T] {
16771750
let rhs = &other[..l];
16781751

16791752
for i in 0..l {
1680-
match lhs[i].cmp(&rhs[i]) {
1681-
Ordering::Equal => (),
1753+
match lhs[i].partial_cmp(&rhs[i]) {
1754+
Some(Ordering::Equal) => (),
16821755
non_eq => return non_eq,
16831756
}
16841757
}
16851758

1686-
self.len().cmp(&other.len())
1759+
self.len().partial_cmp(&other.len())
16871760
}
16881761
}
16891762

1690-
#[stable(feature = "rust1", since = "1.0.0")]
1691-
impl<T: PartialOrd> PartialOrd for [T] {
1692-
fn partial_cmp(&self, other: &[T]) -> Option<Ordering> {
1763+
impl SlicePartialOrd<u8> for [u8] {
1764+
#[inline]
1765+
fn partial_compare(&self, other: &[u8]) -> Option<Ordering> {
1766+
Some(SliceOrd::compare(self, other))
1767+
}
1768+
}
1769+
1770+
#[doc(hidden)]
1771+
// intermediate trait for specialization of slice's Ord
1772+
trait SliceOrd<B> {
1773+
fn compare(&self, other: &[B]) -> Ordering;
1774+
}
1775+
1776+
impl<A> SliceOrd<A> for [A]
1777+
where A: Ord
1778+
{
1779+
default fn compare(&self, other: &[A]) -> Ordering {
16931780
let l = cmp::min(self.len(), other.len());
16941781

16951782
// Slice to the loop iteration range to enable bound check
@@ -1698,12 +1785,48 @@ impl<T: PartialOrd> PartialOrd for [T] {
16981785
let rhs = &other[..l];
16991786

17001787
for i in 0..l {
1701-
match lhs[i].partial_cmp(&rhs[i]) {
1702-
Some(Ordering::Equal) => (),
1788+
match lhs[i].cmp(&rhs[i]) {
1789+
Ordering::Equal => (),
17031790
non_eq => return non_eq,
17041791
}
17051792
}
17061793

1707-
self.len().partial_cmp(&other.len())
1794+
self.len().cmp(&other.len())
17081795
}
17091796
}
1797+
1798+
// memcmp compares a sequence of unsigned bytes lexicographically.
1799+
// this matches the order we want for [u8], but no others (not even [i8]).
1800+
impl SliceOrd<u8> for [u8] {
1801+
#[inline]
1802+
fn compare(&self, other: &[u8]) -> Ordering {
1803+
let order = unsafe {
1804+
memcmp(self.as_ptr(), other.as_ptr(),
1805+
cmp::min(self.len(), other.len()))
1806+
};
1807+
if order == 0 {
1808+
self.len().cmp(&other.len())
1809+
} else if order < 0 {
1810+
Less
1811+
} else {
1812+
Greater
1813+
}
1814+
}
1815+
}
1816+
1817+
#[doc(hidden)]
1818+
/// Trait implemented for types that can be compared for equality using
1819+
/// their bytewise representation
1820+
trait BytewiseEquality { }
1821+
1822+
macro_rules! impl_marker_for {
1823+
($traitname:ident, $($ty:ty)*) => {
1824+
$(
1825+
impl $traitname for $ty { }
1826+
)*
1827+
}
1828+
}
1829+
1830+
impl_marker_for!(BytewiseEquality,
1831+
u8 i8 u16 i16 u32 i32 u64 i64 usize isize char bool);
1832+

src/libcore/str/mod.rs

+3-22
Original file line numberDiff line numberDiff line change
@@ -1150,16 +1150,7 @@ Section: Comparing strings
11501150
#[lang = "str_eq"]
11511151
#[inline]
11521152
fn eq_slice(a: &str, b: &str) -> bool {
1153-
a.len() == b.len() && unsafe { cmp_slice(a, b, a.len()) == 0 }
1154-
}
1155-
1156-
/// Bytewise slice comparison.
1157-
/// NOTE: This uses the system's memcmp, which is currently dramatically
1158-
/// faster than comparing each byte in a loop.
1159-
#[inline]
1160-
unsafe fn cmp_slice(a: &str, b: &str, len: usize) -> i32 {
1161-
extern { fn memcmp(s1: *const i8, s2: *const i8, n: usize) -> i32; }
1162-
memcmp(a.as_ptr() as *const i8, b.as_ptr() as *const i8, len)
1153+
a.as_bytes() == b.as_bytes()
11631154
}
11641155

11651156
/*
@@ -1328,8 +1319,7 @@ Section: Trait implementations
13281319
*/
13291320

13301321
mod traits {
1331-
use cmp::{self, Ordering, Ord, PartialEq, PartialOrd, Eq};
1332-
use cmp::Ordering::{Less, Greater};
1322+
use cmp::{Ord, Ordering, PartialEq, PartialOrd, Eq};
13331323
use iter::Iterator;
13341324
use option::Option;
13351325
use option::Option::Some;
@@ -1340,16 +1330,7 @@ mod traits {
13401330
impl Ord for str {
13411331
#[inline]
13421332
fn cmp(&self, other: &str) -> Ordering {
1343-
let cmp = unsafe {
1344-
super::cmp_slice(self, other, cmp::min(self.len(), other.len()))
1345-
};
1346-
if cmp == 0 {
1347-
self.len().cmp(&other.len())
1348-
} else if cmp < 0 {
1349-
Less
1350-
} else {
1351-
Greater
1352-
}
1333+
self.as_bytes().cmp(other.as_bytes())
13531334
}
13541335
}
13551336

0 commit comments

Comments
 (0)