Skip to content

Commit 0669a43

Browse files
committed
auto merge of #19448 : japaric/rust/binops-by-value, r=nikomatsakis
- The following operator traits now take their arguments by value: `Add`, `Sub`, `Mul`, `Div`, `Rem`, `BitAnd`, `BitOr`, `BitXor`, `Shl`, `Shr`. This breaks all existing implementations of these traits. - The binary operation `a OP b` now "desugars" to `OpTrait::op_method(a, b)` and consumes both arguments. - `String` and `Vec` addition have been changed to reuse the LHS owned value, and to avoid internal cloning. Only the following asymmetric operations are available: `String + &str` and `Vec<T> + &[T]`, which are now a short-hand for the "append" operation. [breaking-change] --- This passes `make check` locally. I haven't touch the unary operators in this PR, but converting them to by value should be very similar to this PR. I can work on them after this gets the thumbs up. @nikomatsakis r? the compiler changes @aturon r? the library changes. I think the only controversial bit is the semantic change of the `Vec`/`String` `Add` implementation. cc #19148
2 parents 92e9e70 + 89d2061 commit 0669a43

Some content is hidden

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

42 files changed

+1388
-163
lines changed

src/libcollections/btree/set.rs

+96
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,8 @@ impl<T: Ord> Default for BTreeSet<T> {
443443
}
444444

445445
#[unstable = "matches collection reform specification, waiting for dust to settle"]
446+
// NOTE(stage0): Remove impl after a snapshot
447+
#[cfg(stage0)]
446448
impl<T: Ord + Clone> Sub<BTreeSet<T>,BTreeSet<T>> for BTreeSet<T> {
447449
/// Returns the difference of `self` and `rhs` as a new `BTreeSet<T>`.
448450
///
@@ -464,6 +466,30 @@ impl<T: Ord + Clone> Sub<BTreeSet<T>,BTreeSet<T>> for BTreeSet<T> {
464466
}
465467

466468
#[unstable = "matches collection reform specification, waiting for dust to settle"]
469+
#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot
470+
impl<'a, 'b, T: Ord + Clone> Sub<&'b BTreeSet<T>, BTreeSet<T>> for &'a BTreeSet<T> {
471+
/// Returns the difference of `self` and `rhs` as a new `BTreeSet<T>`.
472+
///
473+
/// # Examples
474+
///
475+
/// ```
476+
/// use std::collections::BTreeSet;
477+
///
478+
/// let a: BTreeSet<int> = vec![1, 2, 3].into_iter().collect();
479+
/// let b: BTreeSet<int> = vec![3, 4, 5].into_iter().collect();
480+
///
481+
/// let result: BTreeSet<int> = &a - &b;
482+
/// let result_vec: Vec<int> = result.into_iter().collect();
483+
/// assert_eq!(result_vec, vec![1, 2]);
484+
/// ```
485+
fn sub(self, rhs: &BTreeSet<T>) -> BTreeSet<T> {
486+
self.difference(rhs).cloned().collect()
487+
}
488+
}
489+
490+
#[unstable = "matches collection reform specification, waiting for dust to settle"]
491+
// NOTE(stage0): Remove impl after a snapshot
492+
#[cfg(stage0)]
467493
impl<T: Ord + Clone> BitXor<BTreeSet<T>,BTreeSet<T>> for BTreeSet<T> {
468494
/// Returns the symmetric difference of `self` and `rhs` as a new `BTreeSet<T>`.
469495
///
@@ -485,6 +511,30 @@ impl<T: Ord + Clone> BitXor<BTreeSet<T>,BTreeSet<T>> for BTreeSet<T> {
485511
}
486512

487513
#[unstable = "matches collection reform specification, waiting for dust to settle"]
514+
#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot
515+
impl<'a, 'b, T: Ord + Clone> BitXor<&'b BTreeSet<T>, BTreeSet<T>> for &'a BTreeSet<T> {
516+
/// Returns the symmetric difference of `self` and `rhs` as a new `BTreeSet<T>`.
517+
///
518+
/// # Examples
519+
///
520+
/// ```
521+
/// use std::collections::BTreeSet;
522+
///
523+
/// let a: BTreeSet<int> = vec![1, 2, 3].into_iter().collect();
524+
/// let b: BTreeSet<int> = vec![2, 3, 4].into_iter().collect();
525+
///
526+
/// let result: BTreeSet<int> = &a ^ &b;
527+
/// let result_vec: Vec<int> = result.into_iter().collect();
528+
/// assert_eq!(result_vec, vec![1, 4]);
529+
/// ```
530+
fn bitxor(self, rhs: &BTreeSet<T>) -> BTreeSet<T> {
531+
self.symmetric_difference(rhs).cloned().collect()
532+
}
533+
}
534+
535+
#[unstable = "matches collection reform specification, waiting for dust to settle"]
536+
// NOTE(stage0): Remove impl after a snapshot
537+
#[cfg(stage0)]
488538
impl<T: Ord + Clone> BitAnd<BTreeSet<T>,BTreeSet<T>> for BTreeSet<T> {
489539
/// Returns the intersection of `self` and `rhs` as a new `BTreeSet<T>`.
490540
///
@@ -506,6 +556,30 @@ impl<T: Ord + Clone> BitAnd<BTreeSet<T>,BTreeSet<T>> for BTreeSet<T> {
506556
}
507557

508558
#[unstable = "matches collection reform specification, waiting for dust to settle"]
559+
#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot
560+
impl<'a, 'b, T: Ord + Clone> BitAnd<&'b BTreeSet<T>, BTreeSet<T>> for &'a BTreeSet<T> {
561+
/// Returns the intersection of `self` and `rhs` as a new `BTreeSet<T>`.
562+
///
563+
/// # Examples
564+
///
565+
/// ```
566+
/// use std::collections::BTreeSet;
567+
///
568+
/// let a: BTreeSet<int> = vec![1, 2, 3].into_iter().collect();
569+
/// let b: BTreeSet<int> = vec![2, 3, 4].into_iter().collect();
570+
///
571+
/// let result: BTreeSet<int> = &a & &b;
572+
/// let result_vec: Vec<int> = result.into_iter().collect();
573+
/// assert_eq!(result_vec, vec![2, 3]);
574+
/// ```
575+
fn bitand(self, rhs: &BTreeSet<T>) -> BTreeSet<T> {
576+
self.intersection(rhs).cloned().collect()
577+
}
578+
}
579+
580+
#[unstable = "matches collection reform specification, waiting for dust to settle"]
581+
// NOTE(stage0): Remove impl after a snapshot
582+
#[cfg(stage0)]
509583
impl<T: Ord + Clone> BitOr<BTreeSet<T>,BTreeSet<T>> for BTreeSet<T> {
510584
/// Returns the union of `self` and `rhs` as a new `BTreeSet<T>`.
511585
///
@@ -526,6 +600,28 @@ impl<T: Ord + Clone> BitOr<BTreeSet<T>,BTreeSet<T>> for BTreeSet<T> {
526600
}
527601
}
528602

603+
#[unstable = "matches collection reform specification, waiting for dust to settle"]
604+
#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot
605+
impl<'a, 'b, T: Ord + Clone> BitOr<&'b BTreeSet<T>, BTreeSet<T>> for &'a BTreeSet<T> {
606+
/// Returns the union of `self` and `rhs` as a new `BTreeSet<T>`.
607+
///
608+
/// # Examples
609+
///
610+
/// ```
611+
/// use std::collections::BTreeSet;
612+
///
613+
/// let a: BTreeSet<int> = vec![1, 2, 3].into_iter().collect();
614+
/// let b: BTreeSet<int> = vec![3, 4, 5].into_iter().collect();
615+
///
616+
/// let result: BTreeSet<int> = &a | &b;
617+
/// let result_vec: Vec<int> = result.into_iter().collect();
618+
/// assert_eq!(result_vec, vec![1, 2, 3, 4, 5]);
619+
/// ```
620+
fn bitor(self, rhs: &BTreeSet<T>) -> BTreeSet<T> {
621+
self.union(rhs).cloned().collect()
622+
}
623+
}
624+
529625
impl<T: Show> Show for BTreeSet<T> {
530626
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
531627
try!(write!(f, "{{"));

src/libcollections/enum_set.rs

+36
Original file line numberDiff line numberDiff line change
@@ -183,30 +183,66 @@ impl<E:CLike> EnumSet<E> {
183183
}
184184
}
185185

186+
// NOTE(stage0): Remove impl after a snapshot
187+
#[cfg(stage0)]
186188
impl<E:CLike> Sub<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
187189
fn sub(&self, e: &EnumSet<E>) -> EnumSet<E> {
188190
EnumSet {bits: self.bits & !e.bits}
189191
}
190192
}
191193

194+
#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot
195+
impl<E:CLike> Sub<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
196+
fn sub(self, e: EnumSet<E>) -> EnumSet<E> {
197+
EnumSet {bits: self.bits & !e.bits}
198+
}
199+
}
200+
201+
// NOTE(stage0): Remove impl after a snapshot
202+
#[cfg(stage0)]
192203
impl<E:CLike> BitOr<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
193204
fn bitor(&self, e: &EnumSet<E>) -> EnumSet<E> {
194205
EnumSet {bits: self.bits | e.bits}
195206
}
196207
}
197208

209+
#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot
210+
impl<E:CLike> BitOr<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
211+
fn bitor(self, e: EnumSet<E>) -> EnumSet<E> {
212+
EnumSet {bits: self.bits | e.bits}
213+
}
214+
}
215+
216+
// NOTE(stage0): Remove impl after a snapshot
217+
#[cfg(stage0)]
198218
impl<E:CLike> BitAnd<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
199219
fn bitand(&self, e: &EnumSet<E>) -> EnumSet<E> {
200220
EnumSet {bits: self.bits & e.bits}
201221
}
202222
}
203223

224+
#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot
225+
impl<E:CLike> BitAnd<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
226+
fn bitand(self, e: EnumSet<E>) -> EnumSet<E> {
227+
EnumSet {bits: self.bits & e.bits}
228+
}
229+
}
230+
231+
// NOTE(stage0): Remove impl after a snapshot
232+
#[cfg(stage0)]
204233
impl<E:CLike> BitXor<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
205234
fn bitxor(&self, e: &EnumSet<E>) -> EnumSet<E> {
206235
EnumSet {bits: self.bits ^ e.bits}
207236
}
208237
}
209238

239+
#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot
240+
impl<E:CLike> BitXor<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
241+
fn bitxor(self, e: EnumSet<E>) -> EnumSet<E> {
242+
EnumSet {bits: self.bits ^ e.bits}
243+
}
244+
}
245+
210246
/// An iterator over an EnumSet
211247
pub struct Items<E> {
212248
index: uint,

src/libcollections/string.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,8 @@ impl<'a, S: Str> Equiv<S> for String {
855855
}
856856
}
857857

858+
// NOTE(stage0): Remove impl after a snapshot
859+
#[cfg(stage0)]
858860
#[experimental = "waiting on Add stabilization"]
859861
impl<S: Str> Add<S, String> for String {
860862
fn add(&self, other: &S) -> String {
@@ -864,6 +866,22 @@ impl<S: Str> Add<S, String> for String {
864866
}
865867
}
866868

869+
#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot
870+
impl<'a> Add<&'a str, String> for String {
871+
fn add(mut self, other: &str) -> String {
872+
self.push_str(other);
873+
self
874+
}
875+
}
876+
877+
#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot
878+
impl<'a> Add<String, String> for &'a str {
879+
fn add(self, mut other: String) -> String {
880+
other.push_str(self);
881+
other
882+
}
883+
}
884+
867885
impl ops::Slice<uint, str> for String {
868886
#[inline]
869887
fn as_slice_<'a>(&'a self) -> &'a str {
@@ -1280,7 +1298,7 @@ mod tests {
12801298
fn test_str_add() {
12811299
let a = String::from_str("12345");
12821300
let b = a + "2";
1283-
let b = b + String::from_str("2");
1301+
let b = b + "2";
12841302
assert_eq!(b.len(), 7);
12851303
assert_eq!(b, "1234522");
12861304
}

0 commit comments

Comments
 (0)