Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make binary operators take their arguments by value #19448

Merged
merged 30 commits into from
Dec 16, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
14c0a70
syntax/ast_util: add `is_by_value_binop()`
Dec 1, 2014
c3a6d28
Tell typeck which binops are by value
Dec 1, 2014
f64e52a
Tell trans which binops are by value
Dec 1, 2014
5038f5a
Tell expr_use_visitor which binops are by value
Dec 1, 2014
227435a
Tell regionck which binops are by value
Dec 1, 2014
c73259a
libcore: convert binop traits to by value
Dec 1, 2014
65d3a40
libcore: fix move semantics fallout
Dec 1, 2014
dbc7e17
libcollections: Vec<T> + &[T]
Dec 1, 2014
076e932
libcollections: String + &str
Dec 1, 2014
baf79d4
libcollections: make `EnumSet` binops by value
Dec 1, 2014
32168fa
libstd: convert `BitFlags` binops to by value
Dec 1, 2014
9126a24
libstd: convert `Duration` binops to by value
Dec 1, 2014
b5537fa
libtime: convert `Timespec` binops to by value
Dec 1, 2014
265b89a
libsyntax: convert `BytePos`/`CharPos` binops to by value
Dec 1, 2014
c4fa2a3
libsyntax: convert `LockstepIterSize` binops to by value
Dec 1, 2014
eb71976
librustc: convert `TypeContents` binops to by value
Dec 1, 2014
fb1d4f1
librustdoc: convert `Counts` binops to by value
Dec 1, 2014
2b17083
Test that binops consume their arguments
Dec 1, 2014
971add8
Fix run-pass tests
Dec 1, 2014
f0b6567
Fix compile-fail tests
Dec 1, 2014
a672b27
libcollections: fix unit tests
Dec 1, 2014
1ec5650
libcoretest: fix unit tests
Dec 1, 2014
bc23b8e
libstd: fix unit tests
Dec 1, 2014
d193bf3
libcore: fix doctests
Dec 2, 2014
f4abb12
Address Niko's comments
Dec 3, 2014
949b55e
libcollections: add commutative version of `Vec`/`String` addition
Dec 3, 2014
dff2b39
Test binops move semantics
Dec 3, 2014
3084604
libcollections: convert `TrieSet` binops to by value
Dec 6, 2014
e00e461
libcollections: convert `TreeSet` binops to by value
Dec 13, 2014
89d2061
libcollections: convert `BTreeSet` binops to by value
Dec 13, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions src/libcollections/btree/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,8 @@ impl<T: Ord> Default for BTreeSet<T> {
}

#[unstable = "matches collection reform specification, waiting for dust to settle"]
// NOTE(stage0): Remove impl after a snapshot
#[cfg(stage0)]
impl<T: Ord + Clone> Sub<BTreeSet<T>,BTreeSet<T>> for BTreeSet<T> {
/// Returns the difference of `self` and `rhs` as a new `BTreeSet<T>`.
///
Expand All @@ -430,6 +432,30 @@ impl<T: Ord + Clone> Sub<BTreeSet<T>,BTreeSet<T>> for BTreeSet<T> {
}

#[unstable = "matches collection reform specification, waiting for dust to settle"]
#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot
impl<'a, 'b, T: Ord + Clone> Sub<&'b BTreeSet<T>, BTreeSet<T>> for &'a BTreeSet<T> {
/// Returns the difference of `self` and `rhs` as a new `BTreeSet<T>`.
///
/// # Examples
///
/// ```
/// use std::collections::BTreeSet;
///
/// let a: BTreeSet<int> = vec![1, 2, 3].into_iter().collect();
/// let b: BTreeSet<int> = vec![3, 4, 5].into_iter().collect();
///
/// let result: BTreeSet<int> = &a - &b;
/// let result_vec: Vec<int> = result.into_iter().collect();
/// assert_eq!(result_vec, vec![1, 2]);
/// ```
fn sub(self, rhs: &BTreeSet<T>) -> BTreeSet<T> {
self.difference(rhs).cloned().collect()
}
}

#[unstable = "matches collection reform specification, waiting for dust to settle"]
// NOTE(stage0): Remove impl after a snapshot
#[cfg(stage0)]
impl<T: Ord + Clone> BitXor<BTreeSet<T>,BTreeSet<T>> for BTreeSet<T> {
/// Returns the symmetric difference of `self` and `rhs` as a new `BTreeSet<T>`.
///
Expand All @@ -451,6 +477,30 @@ impl<T: Ord + Clone> BitXor<BTreeSet<T>,BTreeSet<T>> for BTreeSet<T> {
}

#[unstable = "matches collection reform specification, waiting for dust to settle"]
#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot
impl<'a, 'b, T: Ord + Clone> BitXor<&'b BTreeSet<T>, BTreeSet<T>> for &'a BTreeSet<T> {
/// Returns the symmetric difference of `self` and `rhs` as a new `BTreeSet<T>`.
///
/// # Examples
///
/// ```
/// use std::collections::BTreeSet;
///
/// let a: BTreeSet<int> = vec![1, 2, 3].into_iter().collect();
/// let b: BTreeSet<int> = vec![2, 3, 4].into_iter().collect();
///
/// let result: BTreeSet<int> = &a ^ &b;
/// let result_vec: Vec<int> = result.into_iter().collect();
/// assert_eq!(result_vec, vec![1, 4]);
/// ```
fn bitxor(self, rhs: &BTreeSet<T>) -> BTreeSet<T> {
self.symmetric_difference(rhs).cloned().collect()
}
}

#[unstable = "matches collection reform specification, waiting for dust to settle"]
// NOTE(stage0): Remove impl after a snapshot
#[cfg(stage0)]
impl<T: Ord + Clone> BitAnd<BTreeSet<T>,BTreeSet<T>> for BTreeSet<T> {
/// Returns the intersection of `self` and `rhs` as a new `BTreeSet<T>`.
///
Expand All @@ -472,6 +522,30 @@ impl<T: Ord + Clone> BitAnd<BTreeSet<T>,BTreeSet<T>> for BTreeSet<T> {
}

#[unstable = "matches collection reform specification, waiting for dust to settle"]
#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot
impl<'a, 'b, T: Ord + Clone> BitAnd<&'b BTreeSet<T>, BTreeSet<T>> for &'a BTreeSet<T> {
/// Returns the intersection of `self` and `rhs` as a new `BTreeSet<T>`.
///
/// # Examples
///
/// ```
/// use std::collections::BTreeSet;
///
/// let a: BTreeSet<int> = vec![1, 2, 3].into_iter().collect();
/// let b: BTreeSet<int> = vec![2, 3, 4].into_iter().collect();
///
/// let result: BTreeSet<int> = &a & &b;
/// let result_vec: Vec<int> = result.into_iter().collect();
/// assert_eq!(result_vec, vec![2, 3]);
/// ```
fn bitand(self, rhs: &BTreeSet<T>) -> BTreeSet<T> {
self.intersection(rhs).cloned().collect()
}
}

#[unstable = "matches collection reform specification, waiting for dust to settle"]
// NOTE(stage0): Remove impl after a snapshot
#[cfg(stage0)]
impl<T: Ord + Clone> BitOr<BTreeSet<T>,BTreeSet<T>> for BTreeSet<T> {
/// Returns the union of `self` and `rhs` as a new `BTreeSet<T>`.
///
Expand All @@ -492,6 +566,28 @@ impl<T: Ord + Clone> BitOr<BTreeSet<T>,BTreeSet<T>> for BTreeSet<T> {
}
}

#[unstable = "matches collection reform specification, waiting for dust to settle"]
#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot
impl<'a, 'b, T: Ord + Clone> BitOr<&'b BTreeSet<T>, BTreeSet<T>> for &'a BTreeSet<T> {
/// Returns the union of `self` and `rhs` as a new `BTreeSet<T>`.
///
/// # Examples
///
/// ```
/// use std::collections::BTreeSet;
///
/// let a: BTreeSet<int> = vec![1, 2, 3].into_iter().collect();
/// let b: BTreeSet<int> = vec![3, 4, 5].into_iter().collect();
///
/// let result: BTreeSet<int> = &a | &b;
/// let result_vec: Vec<int> = result.into_iter().collect();
/// assert_eq!(result_vec, vec![1, 2, 3, 4, 5]);
/// ```
fn bitor(self, rhs: &BTreeSet<T>) -> BTreeSet<T> {
self.union(rhs).cloned().collect()
}
}

impl<T: Show> Show for BTreeSet<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(write!(f, "{{"));
Expand Down
36 changes: 36 additions & 0 deletions src/libcollections/enum_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,30 +183,66 @@ impl<E:CLike> EnumSet<E> {
}
}

// NOTE(stage0): Remove impl after a snapshot
#[cfg(stage0)]
impl<E:CLike> Sub<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
fn sub(&self, e: &EnumSet<E>) -> EnumSet<E> {
EnumSet {bits: self.bits & !e.bits}
}
}

#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot
impl<E:CLike> Sub<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
fn sub(self, e: EnumSet<E>) -> EnumSet<E> {
EnumSet {bits: self.bits & !e.bits}
}
}

// NOTE(stage0): Remove impl after a snapshot
#[cfg(stage0)]
impl<E:CLike> BitOr<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
fn bitor(&self, e: &EnumSet<E>) -> EnumSet<E> {
EnumSet {bits: self.bits | e.bits}
}
}

#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot
impl<E:CLike> BitOr<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
fn bitor(self, e: EnumSet<E>) -> EnumSet<E> {
EnumSet {bits: self.bits | e.bits}
}
}

// NOTE(stage0): Remove impl after a snapshot
#[cfg(stage0)]
impl<E:CLike> BitAnd<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
fn bitand(&self, e: &EnumSet<E>) -> EnumSet<E> {
EnumSet {bits: self.bits & e.bits}
}
}

#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot
impl<E:CLike> BitAnd<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
fn bitand(self, e: EnumSet<E>) -> EnumSet<E> {
EnumSet {bits: self.bits & e.bits}
}
}

// NOTE(stage0): Remove impl after a snapshot
#[cfg(stage0)]
impl<E:CLike> BitXor<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
fn bitxor(&self, e: &EnumSet<E>) -> EnumSet<E> {
EnumSet {bits: self.bits ^ e.bits}
}
}

#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot
impl<E:CLike> BitXor<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
fn bitxor(self, e: EnumSet<E>) -> EnumSet<E> {
EnumSet {bits: self.bits ^ e.bits}
}
}

/// An iterator over an EnumSet
pub struct Items<E> {
index: uint,
Expand Down
20 changes: 19 additions & 1 deletion src/libcollections/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,8 @@ impl<'a, S: Str> Equiv<S> for String {
}
}

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

#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot
impl<'a> Add<&'a str, String> for String {
fn add(mut self, other: &str) -> String {
self.push_str(other);
self
}
}

#[cfg(not(stage0))] // NOTE(stage0): Remove cfg after a snapshot
impl<'a> Add<String, String> for &'a str {
fn add(self, mut other: String) -> String {
other.push_str(self);
other
}
}

impl ops::Slice<uint, str> for String {
#[inline]
fn as_slice_<'a>(&'a self) -> &'a str {
Expand Down Expand Up @@ -1280,7 +1298,7 @@ mod tests {
fn test_str_add() {
let a = String::from_str("12345");
let b = a + "2";
let b = b + String::from_str("2");
let b = b + "2";
assert_eq!(b.len(), 7);
assert_eq!(b, "1234522");
}
Expand Down
Loading