diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs
index cd01c008fe1bc..d4c05e4b7d39c 100644
--- a/src/libcollections/btree/set.rs
+++ b/src/libcollections/btree/set.rs
@@ -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>`.
     ///
@@ -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>`.
     ///
@@ -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>`.
     ///
@@ -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>`.
     ///
@@ -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, "{{"));
diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs
index d8dc1f36e056d..4df1be1bb355c 100644
--- a/src/libcollections/enum_set.rs
+++ b/src/libcollections/enum_set.rs
@@ -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,
diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs
index c4659f86680e4..f3a9e7b186758 100644
--- a/src/libcollections/string.rs
+++ b/src/libcollections/string.rs
@@ -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 {
@@ -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 {
@@ -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");
     }
diff --git a/src/libcollections/tree/set.rs b/src/libcollections/tree/set.rs
index bd8bf5c6cb67f..1d3ec2eb7f2f6 100644
--- a/src/libcollections/tree/set.rs
+++ b/src/libcollections/tree/set.rs
@@ -668,6 +668,8 @@ impl<'a, T: Ord> Iterator<&'a T> for UnionItems<'a, T> {
 }
 
 #[unstable = "matches collection reform specification, waiting for dust to settle"]
+// NOTE(stage0): Remove impl after a snapshot
+#[cfg(stage0)]
 impl<T: Ord + Clone> BitOr<TreeSet<T>, TreeSet<T>> for TreeSet<T> {
     /// Returns the union of `self` and `rhs` as a new `TreeSet<T>`.
     ///
@@ -689,6 +691,30 @@ impl<T: Ord + Clone> BitOr<TreeSet<T>, TreeSet<T>> for TreeSet<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 TreeSet<T>, TreeSet<T>> for &'a TreeSet<T> {
+    /// Returns the union of `self` and `rhs` as a new `TreeSet<T>`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::TreeSet;
+    ///
+    /// let a: TreeSet<int> = vec![1, 2, 3].into_iter().collect();
+    /// let b: TreeSet<int> = vec![3, 4, 5].into_iter().collect();
+    ///
+    /// let set: TreeSet<int> = &a | &b;
+    /// let v: Vec<int> = set.into_iter().collect();
+    /// assert_eq!(v, vec![1, 2, 3, 4, 5]);
+    /// ```
+    fn bitor(self, rhs: &TreeSet<T>) -> TreeSet<T> {
+        self.union(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<TreeSet<T>, TreeSet<T>> for TreeSet<T> {
     /// Returns the intersection of `self` and `rhs` as a new `TreeSet<T>`.
     ///
@@ -710,6 +736,30 @@ impl<T: Ord + Clone> BitAnd<TreeSet<T>, TreeSet<T>> for TreeSet<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 TreeSet<T>, TreeSet<T>> for &'a TreeSet<T> {
+    /// Returns the intersection of `self` and `rhs` as a new `TreeSet<T>`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::TreeSet;
+    ///
+    /// let a: TreeSet<int> = vec![1, 2, 3].into_iter().collect();
+    /// let b: TreeSet<int> = vec![2, 3, 4].into_iter().collect();
+    ///
+    /// let set: TreeSet<int> = &a & &b;
+    /// let v: Vec<int> = set.into_iter().collect();
+    /// assert_eq!(v, vec![2, 3]);
+    /// ```
+    fn bitand(self, rhs: &TreeSet<T>) -> TreeSet<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> BitXor<TreeSet<T>, TreeSet<T>> for TreeSet<T> {
     /// Returns the symmetric difference of `self` and `rhs` as a new `TreeSet<T>`.
     ///
@@ -731,6 +781,30 @@ impl<T: Ord + Clone> BitXor<TreeSet<T>, TreeSet<T>> for TreeSet<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 TreeSet<T>, TreeSet<T>> for &'a TreeSet<T> {
+    /// Returns the symmetric difference of `self` and `rhs` as a new `TreeSet<T>`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::TreeSet;
+    ///
+    /// let a: TreeSet<int> = vec![1, 2, 3].into_iter().collect();
+    /// let b: TreeSet<int> = vec![3, 4, 5].into_iter().collect();
+    ///
+    /// let set: TreeSet<int> = &a ^ &b;
+    /// let v: Vec<int> = set.into_iter().collect();
+    /// assert_eq!(v, vec![1, 2, 4, 5]);
+    /// ```
+    fn bitxor(self, rhs: &TreeSet<T>) -> TreeSet<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> Sub<TreeSet<T>, TreeSet<T>> for TreeSet<T> {
     /// Returns the difference of `self` and `rhs` as a new `TreeSet<T>`.
     ///
@@ -751,6 +825,28 @@ impl<T: Ord + Clone> Sub<TreeSet<T>, TreeSet<T>> for TreeSet<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 TreeSet<T>, TreeSet<T>> for &'a TreeSet<T> {
+    /// Returns the difference of `self` and `rhs` as a new `TreeSet<T>`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::TreeSet;
+    ///
+    /// let a: TreeSet<int> = vec![1, 2, 3].into_iter().collect();
+    /// let b: TreeSet<int> = vec![3, 4, 5].into_iter().collect();
+    ///
+    /// let set: TreeSet<int> = &a - &b;
+    /// let v: Vec<int> = set.into_iter().collect();
+    /// assert_eq!(v, vec![1, 2]);
+    /// ```
+    fn sub(self, rhs: &TreeSet<T>) -> TreeSet<T> {
+        self.difference(rhs).cloned().collect()
+    }
+}
+
 impl<T: Ord> FromIterator<T> for TreeSet<T> {
     fn from_iter<Iter: Iterator<T>>(iter: Iter) -> TreeSet<T> {
         let mut set = TreeSet::new();
@@ -1032,7 +1128,7 @@ mod test {
         let a: TreeSet<int> = vec![1, 3, 5, 9, 11, 16, 19, 24].into_iter().collect();
         let b: TreeSet<int> = vec![-2, 1, 5, 9, 13, 19].into_iter().collect();
 
-        let set: TreeSet<int> = a | b;
+        let set: TreeSet<int> = &a | &b;
         let v: Vec<int> = set.into_iter().collect();
         assert_eq!(v, vec![-2, 1, 3, 5, 9, 11, 13, 16, 19, 24]);
     }
@@ -1042,7 +1138,7 @@ mod test {
         let a: TreeSet<int> = vec![11, 1, 3, 77, 103, 5, -5].into_iter().collect();
         let b: TreeSet<int> = vec![2, 11, 77, -9, -42, 5, 3].into_iter().collect();
 
-        let set: TreeSet<int> = a & b;
+        let set: TreeSet<int> = &a & &b;
         let v: Vec<int> = set.into_iter().collect();
         assert_eq!(v, vec![3, 5, 11, 77]);
     }
@@ -1052,7 +1148,7 @@ mod test {
         let a: TreeSet<int> = vec![1, 3, 5, 9, 11].into_iter().collect();
         let b: TreeSet<int> = vec![-2, 3, 9, 14, 22].into_iter().collect();
 
-        let set: TreeSet<int> = a ^ b;
+        let set: TreeSet<int> = &a ^ &b;
         let v: Vec<int> = set.into_iter().collect();
         assert_eq!(v, vec![-2, 1, 5, 11, 14, 22]);
     }
@@ -1062,7 +1158,7 @@ mod test {
         let a: TreeSet<int> = vec![-5, 11, 22, 33, 40, 42].into_iter().collect();
         let b: TreeSet<int> = vec![-12, -5, 14, 23, 34, 38, 39, 50].into_iter().collect();
 
-        let set: TreeSet<int> = a - b;
+        let set: TreeSet<int> = &a - &b;
         let v: Vec<int> = set.into_iter().collect();
         assert_eq!(v, vec![11, 22, 33, 40, 42]);
     }
diff --git a/src/libcollections/trie/set.rs b/src/libcollections/trie/set.rs
index 5621726dc5682..7b7b4d8280b78 100644
--- a/src/libcollections/trie/set.rs
+++ b/src/libcollections/trie/set.rs
@@ -462,6 +462,8 @@ impl Extend<uint> for TrieSet {
     }
 }
 
+// NOTE(stage0): Remove impl after a snapshot
+#[cfg(stage0)]
 #[unstable = "matches collection reform specification, waiting for dust to settle"]
 impl BitOr<TrieSet, TrieSet> for TrieSet {
     /// Returns the union of `self` and `rhs` as a new `TrieSet`.
@@ -483,6 +485,30 @@ impl BitOr<TrieSet, TrieSet> for TrieSet {
     }
 }
 
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+#[unstable = "matches collection reform specification, waiting for dust to settle"]
+impl<'a, 'b> BitOr<&'b TrieSet, TrieSet> for &'a TrieSet {
+    /// Returns the union of `self` and `rhs` as a new `TrieSet`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TrieSet;
+    ///
+    /// let a: TrieSet = vec![1, 2, 3].into_iter().collect();
+    /// let b: TrieSet = vec![3, 4, 5].into_iter().collect();
+    ///
+    /// let set: TrieSet = &a | &b;
+    /// let v: Vec<uint> = set.iter().collect();
+    /// assert_eq!(v, vec![1u, 2, 3, 4, 5]);
+    /// ```
+    fn bitor(self, rhs: &TrieSet) -> TrieSet {
+        self.union(rhs).collect()
+    }
+}
+
+// NOTE(stage0): Remove impl after a snapshot
+#[cfg(stage0)]
 #[unstable = "matches collection reform specification, waiting for dust to settle"]
 impl BitAnd<TrieSet, TrieSet> for TrieSet {
     /// Returns the intersection of `self` and `rhs` as a new `TrieSet`.
@@ -504,6 +530,30 @@ impl BitAnd<TrieSet, TrieSet> for TrieSet {
     }
 }
 
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+#[unstable = "matches collection reform specification, waiting for dust to settle"]
+impl<'a, 'b> BitAnd<&'b TrieSet, TrieSet> for &'a TrieSet {
+    /// Returns the intersection of `self` and `rhs` as a new `TrieSet`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TrieSet;
+    ///
+    /// let a: TrieSet = vec![1, 2, 3].into_iter().collect();
+    /// let b: TrieSet = vec![2, 3, 4].into_iter().collect();
+    ///
+    /// let set: TrieSet = &a & &b;
+    /// let v: Vec<uint> = set.iter().collect();
+    /// assert_eq!(v, vec![2u, 3]);
+    /// ```
+    fn bitand(self, rhs: &TrieSet) -> TrieSet {
+        self.intersection(rhs).collect()
+    }
+}
+
+// NOTE(stage0): Remove impl after a snapshot
+#[cfg(stage0)]
 #[unstable = "matches collection reform specification, waiting for dust to settle"]
 impl BitXor<TrieSet, TrieSet> for TrieSet {
     /// Returns the symmetric difference of `self` and `rhs` as a new `TrieSet`.
@@ -525,6 +575,30 @@ impl BitXor<TrieSet, TrieSet> for TrieSet {
     }
 }
 
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+#[unstable = "matches collection reform specification, waiting for dust to settle"]
+impl<'a, 'b> BitXor<&'b TrieSet, TrieSet> for &'a TrieSet {
+    /// Returns the symmetric difference of `self` and `rhs` as a new `TrieSet`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TrieSet;
+    ///
+    /// let a: TrieSet = vec![1, 2, 3].into_iter().collect();
+    /// let b: TrieSet = vec![3, 4, 5].into_iter().collect();
+    ///
+    /// let set: TrieSet = &a ^ &b;
+    /// let v: Vec<uint> = set.iter().collect();
+    /// assert_eq!(v, vec![1u, 2, 4, 5]);
+    /// ```
+    fn bitxor(self, rhs: &TrieSet) -> TrieSet {
+        self.symmetric_difference(rhs).collect()
+    }
+}
+
+// NOTE(stage0): Remove impl after a snapshot
+#[cfg(stage0)]
 #[unstable = "matches collection reform specification, waiting for dust to settle"]
 impl Sub<TrieSet, TrieSet> for TrieSet {
     /// Returns the difference of `self` and `rhs` as a new `TrieSet`.
@@ -546,6 +620,28 @@ impl Sub<TrieSet, TrieSet> for TrieSet {
     }
 }
 
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+#[unstable = "matches collection reform specification, waiting for dust to settle"]
+impl<'a, 'b> Sub<&'b TrieSet, TrieSet> for &'a TrieSet {
+    /// Returns the difference of `self` and `rhs` as a new `TrieSet`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TrieSet;
+    ///
+    /// let a: TrieSet = vec![1, 2, 3].into_iter().collect();
+    /// let b: TrieSet = vec![3, 4, 5].into_iter().collect();
+    ///
+    /// let set: TrieSet = &a - &b;
+    /// let v: Vec<uint> = set.iter().collect();
+    /// assert_eq!(v, vec![1u, 2]);
+    /// ```
+    fn sub(self, rhs: &TrieSet) -> TrieSet {
+        self.difference(rhs).collect()
+    }
+}
+
 /// A forward iterator over a set.
 pub struct SetItems<'a> {
     iter: Entries<'a, ()>
@@ -837,7 +933,7 @@ mod test {
         let a: TrieSet = vec![1, 2, 3].into_iter().collect();
         let b: TrieSet = vec![3, 4, 5].into_iter().collect();
 
-        let set: TrieSet = a | b;
+        let set: TrieSet = &a | &b;
         let v: Vec<uint> = set.iter().collect();
         assert_eq!(v, vec![1u, 2, 3, 4, 5]);
     }
@@ -847,7 +943,7 @@ mod test {
         let a: TrieSet = vec![1, 2, 3].into_iter().collect();
         let b: TrieSet = vec![2, 3, 4].into_iter().collect();
 
-        let set: TrieSet = a & b;
+        let set: TrieSet = &a & &b;
         let v: Vec<uint> = set.iter().collect();
         assert_eq!(v, vec![2u, 3]);
     }
@@ -857,7 +953,7 @@ mod test {
         let a: TrieSet = vec![1, 2, 3].into_iter().collect();
         let b: TrieSet = vec![3, 4, 5].into_iter().collect();
 
-        let set: TrieSet = a ^ b;
+        let set: TrieSet = &a ^ &b;
         let v: Vec<uint> = set.iter().collect();
         assert_eq!(v, vec![1u, 2, 4, 5]);
     }
@@ -867,7 +963,7 @@ mod test {
         let a: TrieSet = vec![1, 2, 3].into_iter().collect();
         let b: TrieSet = vec![3, 4, 5].into_iter().collect();
 
-        let set: TrieSet = a - b;
+        let set: TrieSet = &a - &b;
         let v: Vec<uint> = set.iter().collect();
         assert_eq!(v, vec![1u, 2]);
     }
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index 2ed8686394c01..275825da3b55f 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -1273,6 +1273,8 @@ impl<T> AsSlice<T> for Vec<T> {
     }
 }
 
+// NOTE(stage0): Remove impl after a snapshot
+#[cfg(stage0)]
 impl<T: Clone, Sized? V: AsSlice<T>> Add<V, Vec<T>> for Vec<T> {
     #[inline]
     fn add(&self, rhs: &V) -> Vec<T> {
@@ -1283,6 +1285,25 @@ impl<T: Clone, Sized? V: AsSlice<T>> Add<V, Vec<T>> for Vec<T> {
     }
 }
 
+
+#[cfg(not(stage0))]  // NOTE(stage0): Remove impl after a snapshot
+impl<'a, T: Clone> Add<&'a [T], Vec<T>> for Vec<T> {
+    #[inline]
+    fn add(mut self, rhs: &[T]) -> Vec<T> {
+        self.push_all(rhs);
+        self
+    }
+}
+
+#[cfg(not(stage0))]  // NOTE(stage0): Remove impl after a snapshot
+impl<'a, T: Clone> Add<Vec<T>, Vec<T>> for &'a [T] {
+    #[inline]
+    fn add(self, mut rhs: Vec<T>) -> Vec<T> {
+        rhs.push_all(self);
+        rhs
+    }
+}
+
 #[unsafe_destructor]
 impl<T> Drop for Vec<T> {
     fn drop(&mut self) {
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index 8ee2a8874bb03..5405c7aa3b7dd 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -2166,7 +2166,7 @@ impl<A: Add<A, A> + Clone> Iterator<A> for Counter<A> {
     #[inline]
     fn next(&mut self) -> Option<A> {
         let result = self.state.clone();
-        self.state = self.state + self.step;
+        self.state = self.state.clone() + self.step.clone();
         Some(result)
     }
 
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 3c9b68b350b6b..2416cf5bcc7ae 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -37,8 +37,8 @@ use str::{FromStr, from_str, StrPrelude};
 /// Simultaneous division and remainder
 #[inline]
 #[deprecated = "use division and remainder directly"]
-pub fn div_rem<T: Div<T, T> + Rem<T, T>>(x: T, y: T) -> (T, T) {
-    (x / y, x % y)
+pub fn div_rem<T: Clone + Div<T, T> + Rem<T, T>>(x: T, y: T) -> (T, T) {
+    (x.clone() / y.clone(), x % y)
 }
 
 /// Raises a `base` to the power of `exp`, using exponentiation by squaring.
diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index ebe46af516957..7ff5026d0b9c8 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -32,13 +32,13 @@
 //! }
 //!
 //! impl Add<Point, Point> for Point {
-//!     fn add(&self, other: &Point) -> Point {
+//!     fn add(self, other: Point) -> Point {
 //!         Point {x: self.x + other.x, y: self.y + other.y}
 //!     }
 //! }
 //!
 //! impl Sub<Point, Point> for Point {
-//!     fn sub(&self, other: &Point) -> Point {
+//!     fn sub(self, other: Point) -> Point {
 //!         Point {x: self.x - other.x, y: self.y - other.y}
 //!     }
 //! }
@@ -103,12 +103,16 @@ pub trait Drop {
 ///   Foo + Foo;
 /// }
 /// ```
+// NOTE(stage0): Remove trait after a snapshot
+#[cfg(stage0)]
 #[lang="add"]
 pub trait Add<Sized? RHS,Result> for Sized? {
     /// The method for the `+` operator
     fn add(&self, rhs: &RHS) -> Result;
 }
 
+// NOTE(stage0): Remove macro after a snapshot
+#[cfg(stage0)]
 macro_rules! add_impl(
     ($($t:ty)*) => ($(
         impl Add<$t, $t> for $t {
@@ -118,6 +122,44 @@ macro_rules! add_impl(
     )*)
 )
 
+/// The `Add` trait is used to specify the functionality of `+`.
+///
+/// # Example
+///
+/// A trivial implementation of `Add`. When `Foo + Foo` happens, it ends up
+/// calling `add`, and therefore, `main` prints `Adding!`.
+///
+/// ```rust
+/// struct Foo;
+///
+/// impl Add<Foo, Foo> for Foo {
+///     fn add(self, _rhs: Foo) -> Foo {
+///       println!("Adding!");
+///       self
+///   }
+/// }
+///
+/// fn main() {
+///   Foo + Foo;
+/// }
+/// ```
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+#[lang="add"]
+pub trait Add<RHS, Result> {
+    /// The method for the `+` operator
+    fn add(self, rhs: RHS) -> Result;
+}
+
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+macro_rules! add_impl(
+    ($($t:ty)*) => ($(
+        impl Add<$t, $t> for $t {
+            #[inline]
+            fn add(self, other: $t) -> $t { self + other }
+        }
+    )*)
+)
+
 add_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)
 
 /// The `Sub` trait is used to specify the functionality of `-`.
@@ -143,12 +185,16 @@ add_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)
 ///     Foo - Foo;
 /// }
 /// ```
+// NOTE(stage0): Remove trait after a snapshot
+#[cfg(stage0)]
 #[lang="sub"]
 pub trait Sub<Sized? RHS, Result> for Sized? {
     /// The method for the `-` operator
     fn sub(&self, rhs: &RHS) -> Result;
 }
 
+// NOTE(stage0): Remove macro after a snapshot
+#[cfg(stage0)]
 macro_rules! sub_impl(
     ($($t:ty)*) => ($(
         impl Sub<$t, $t> for $t {
@@ -158,6 +204,44 @@ macro_rules! sub_impl(
     )*)
 )
 
+/// The `Sub` trait is used to specify the functionality of `-`.
+///
+/// # Example
+///
+/// A trivial implementation of `Sub`. When `Foo - Foo` happens, it ends up
+/// calling `sub`, and therefore, `main` prints `Subtracting!`.
+///
+/// ```rust
+/// struct Foo;
+///
+/// impl Sub<Foo, Foo> for Foo {
+///     fn sub(self, _rhs: Foo) -> Foo {
+///         println!("Subtracting!");
+///         self
+///     }
+/// }
+///
+/// fn main() {
+///     Foo - Foo;
+/// }
+/// ```
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+#[lang="sub"]
+pub trait Sub<RHS, Result> {
+    /// The method for the `-` operator
+    fn sub(self, rhs: RHS) -> Result;
+}
+
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+macro_rules! sub_impl(
+    ($($t:ty)*) => ($(
+        impl Sub<$t, $t> for $t {
+            #[inline]
+            fn sub(self, other: $t) -> $t { self - other }
+        }
+    )*)
+)
+
 sub_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)
 
 /// The `Mul` trait is used to specify the functionality of `*`.
@@ -183,12 +267,16 @@ sub_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)
 ///     Foo * Foo;
 /// }
 /// ```
+// NOTE(stage0): Remove trait after a snapshot
+#[cfg(stage0)]
 #[lang="mul"]
 pub trait Mul<Sized? RHS, Result>  for Sized? {
     /// The method for the `*` operator
     fn mul(&self, rhs: &RHS) -> Result;
 }
 
+// NOTE(stage0): Remove macro after a snapshot
+#[cfg(stage0)]
 macro_rules! mul_impl(
     ($($t:ty)*) => ($(
         impl Mul<$t, $t> for $t {
@@ -198,6 +286,44 @@ macro_rules! mul_impl(
     )*)
 )
 
+/// The `Mul` trait is used to specify the functionality of `*`.
+///
+/// # Example
+///
+/// A trivial implementation of `Mul`. When `Foo * Foo` happens, it ends up
+/// calling `mul`, and therefore, `main` prints `Multiplying!`.
+///
+/// ```rust
+/// struct Foo;
+///
+/// impl Mul<Foo, Foo> for Foo {
+///     fn mul(self, _rhs: Foo) -> Foo {
+///         println!("Multiplying!");
+///         self
+///     }
+/// }
+///
+/// fn main() {
+///     Foo * Foo;
+/// }
+/// ```
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+#[lang="mul"]
+pub trait Mul<RHS, Result> {
+    /// The method for the `*` operator
+    fn mul(self, rhs: RHS) -> Result;
+}
+
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+macro_rules! mul_impl(
+    ($($t:ty)*) => ($(
+        impl Mul<$t, $t> for $t {
+            #[inline]
+            fn mul(self, other: $t) -> $t { self * other }
+        }
+    )*)
+)
+
 mul_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)
 
 /// The `Div` trait is used to specify the functionality of `/`.
@@ -223,12 +349,16 @@ mul_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)
 ///     Foo / Foo;
 /// }
 /// ```
+// NOTE(stage0): Remove trait after a snapshot
+#[cfg(stage0)]
 #[lang="div"]
 pub trait Div<Sized? RHS, Result> for Sized? {
     /// The method for the `/` operator
     fn div(&self, rhs: &RHS) -> Result;
 }
 
+// NOTE(stage0): Remove macro after a snapshot
+#[cfg(stage0)]
 macro_rules! div_impl(
     ($($t:ty)*) => ($(
         impl Div<$t, $t> for $t {
@@ -238,6 +368,44 @@ macro_rules! div_impl(
     )*)
 )
 
+/// The `Div` trait is used to specify the functionality of `/`.
+///
+/// # Example
+///
+/// A trivial implementation of `Div`. When `Foo / Foo` happens, it ends up
+/// calling `div`, and therefore, `main` prints `Dividing!`.
+///
+/// ```
+/// struct Foo;
+///
+/// impl Div<Foo, Foo> for Foo {
+///     fn div(self, _rhs: Foo) -> Foo {
+///         println!("Dividing!");
+///         self
+///     }
+/// }
+///
+/// fn main() {
+///     Foo / Foo;
+/// }
+/// ```
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+#[lang="div"]
+pub trait Div<RHS, Result> {
+    /// The method for the `/` operator
+    fn div(self, rhs: RHS) -> Result;
+}
+
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+macro_rules! div_impl(
+    ($($t:ty)*) => ($(
+        impl Div<$t, $t> for $t {
+            #[inline]
+            fn div(self, other: $t) -> $t { self / other }
+        }
+    )*)
+)
+
 div_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)
 
 /// The `Rem` trait is used to specify the functionality of `%`.
@@ -263,12 +431,16 @@ div_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)
 ///     Foo % Foo;
 /// }
 /// ```
+// NOTE(stage0): Remove trait after a snapshot
+#[cfg(stage0)]
 #[lang="rem"]
 pub trait Rem<Sized? RHS, Result>  for Sized? {
     /// The method for the `%` operator
     fn rem(&self, rhs: &RHS) -> Result;
 }
 
+// NOTE(stage0): Remove macro after a snapshot
+#[cfg(stage0)]
 macro_rules! rem_impl(
     ($($t:ty)*) => ($(
         impl Rem<$t, $t> for $t {
@@ -278,6 +450,8 @@ macro_rules! rem_impl(
     )*)
 )
 
+// NOTE(stage0): Remove macro after a snapshot
+#[cfg(stage0)]
 macro_rules! rem_float_impl(
     ($t:ty, $fmod:ident) => {
         impl Rem<$t, $t> for $t {
@@ -290,6 +464,57 @@ macro_rules! rem_float_impl(
     }
 )
 
+/// The `Rem` trait is used to specify the functionality of `%`.
+///
+/// # Example
+///
+/// A trivial implementation of `Rem`. When `Foo % Foo` happens, it ends up
+/// calling `rem`, and therefore, `main` prints `Remainder-ing!`.
+///
+/// ```
+/// struct Foo;
+///
+/// impl Rem<Foo, Foo> for Foo {
+///     fn rem(self, _rhs: Foo) -> Foo {
+///         println!("Remainder-ing!");
+///         self
+///     }
+/// }
+///
+/// fn main() {
+///     Foo % Foo;
+/// }
+/// ```
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+#[lang="rem"]
+pub trait Rem<RHS, Result> {
+    /// The method for the `%` operator
+    fn rem(self, rhs: RHS) -> Result;
+}
+
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+macro_rules! rem_impl(
+    ($($t:ty)*) => ($(
+        impl Rem<$t, $t> for $t {
+            #[inline]
+            fn rem(self, other: $t) -> $t { self % other }
+        }
+    )*)
+)
+
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+macro_rules! rem_float_impl(
+    ($t:ty, $fmod:ident) => {
+        impl Rem<$t, $t> for $t {
+            #[inline]
+            fn rem(self, other: $t) -> $t {
+                extern { fn $fmod(a: $t, b: $t) -> $t; }
+                unsafe { $fmod(self, other) }
+            }
+        }
+    }
+)
+
 rem_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64)
 rem_float_impl!(f32, fmodf)
 rem_float_impl!(f64, fmod)
@@ -414,12 +639,16 @@ not_impl!(bool uint u8 u16 u32 u64 int i8 i16 i32 i64)
 ///     Foo & Foo;
 /// }
 /// ```
+// NOTE(stage0): Remove trait after a snapshot
+#[cfg(stage0)]
 #[lang="bitand"]
 pub trait BitAnd<Sized? RHS, Result> for Sized? {
     /// The method for the `&` operator
     fn bitand(&self, rhs: &RHS) -> Result;
 }
 
+// NOTE(stage0): Remove macro after a snapshot
+#[cfg(stage0)]
 macro_rules! bitand_impl(
     ($($t:ty)*) => ($(
         impl BitAnd<$t, $t> for $t {
@@ -429,6 +658,44 @@ macro_rules! bitand_impl(
     )*)
 )
 
+/// The `BitAnd` trait is used to specify the functionality of `&`.
+///
+/// # Example
+///
+/// A trivial implementation of `BitAnd`. When `Foo & Foo` happens, it ends up
+/// calling `bitand`, and therefore, `main` prints `Bitwise And-ing!`.
+///
+/// ```
+/// struct Foo;
+///
+/// impl BitAnd<Foo, Foo> for Foo {
+///     fn bitand(self, _rhs: Foo) -> Foo {
+///         println!("Bitwise And-ing!");
+///         self
+///     }
+/// }
+///
+/// fn main() {
+///     Foo & Foo;
+/// }
+/// ```
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+#[lang="bitand"]
+pub trait BitAnd<RHS, Result> {
+    /// The method for the `&` operator
+    fn bitand(self, rhs: RHS) -> Result;
+}
+
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+macro_rules! bitand_impl(
+    ($($t:ty)*) => ($(
+        impl BitAnd<$t, $t> for $t {
+            #[inline]
+            fn bitand(self, rhs: $t) -> $t { self & rhs }
+        }
+    )*)
+)
+
 bitand_impl!(bool uint u8 u16 u32 u64 int i8 i16 i32 i64)
 
 /// The `BitOr` trait is used to specify the functionality of `|`.
@@ -454,12 +721,16 @@ bitand_impl!(bool uint u8 u16 u32 u64 int i8 i16 i32 i64)
 ///     Foo | Foo;
 /// }
 /// ```
+// NOTE(stage0): Remove trait after a snapshot
+#[cfg(stage0)]
 #[lang="bitor"]
 pub trait BitOr<Sized? RHS, Result> for Sized? {
     /// The method for the `|` operator
     fn bitor(&self, rhs: &RHS) -> Result;
 }
 
+// NOTE(stage0): Remove macro after a snapshot
+#[cfg(stage0)]
 macro_rules! bitor_impl(
     ($($t:ty)*) => ($(
         impl BitOr<$t,$t> for $t {
@@ -469,6 +740,44 @@ macro_rules! bitor_impl(
     )*)
 )
 
+/// The `BitOr` trait is used to specify the functionality of `|`.
+///
+/// # Example
+///
+/// A trivial implementation of `BitOr`. When `Foo | Foo` happens, it ends up
+/// calling `bitor`, and therefore, `main` prints `Bitwise Or-ing!`.
+///
+/// ```
+/// struct Foo;
+///
+/// impl BitOr<Foo, Foo> for Foo {
+///     fn bitor(self, _rhs: Foo) -> Foo {
+///         println!("Bitwise Or-ing!");
+///         self
+///     }
+/// }
+///
+/// fn main() {
+///     Foo | Foo;
+/// }
+/// ```
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+#[lang="bitor"]
+pub trait BitOr<RHS, Result> {
+    /// The method for the `|` operator
+    fn bitor(self, rhs: RHS) -> Result;
+}
+
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+macro_rules! bitor_impl(
+    ($($t:ty)*) => ($(
+        impl BitOr<$t,$t> for $t {
+            #[inline]
+            fn bitor(self, rhs: $t) -> $t { self | rhs }
+        }
+    )*)
+)
+
 bitor_impl!(bool uint u8 u16 u32 u64 int i8 i16 i32 i64)
 
 /// The `BitXor` trait is used to specify the functionality of `^`.
@@ -494,12 +803,16 @@ bitor_impl!(bool uint u8 u16 u32 u64 int i8 i16 i32 i64)
 ///     Foo ^ Foo;
 /// }
 /// ```
+// NOTE(stage0): Remove trait after a snapshot
+#[cfg(stage0)]
 #[lang="bitxor"]
 pub trait BitXor<Sized? RHS, Result> for Sized? {
     /// The method for the `^` operator
     fn bitxor(&self, rhs: &RHS) -> Result;
 }
 
+// NOTE(stage0): Remove macro after a snapshot
+#[cfg(stage0)]
 macro_rules! bitxor_impl(
     ($($t:ty)*) => ($(
         impl BitXor<$t, $t> for $t {
@@ -509,6 +822,44 @@ macro_rules! bitxor_impl(
     )*)
 )
 
+/// The `BitXor` trait is used to specify the functionality of `^`.
+///
+/// # Example
+///
+/// A trivial implementation of `BitXor`. When `Foo ^ Foo` happens, it ends up
+/// calling `bitxor`, and therefore, `main` prints `Bitwise Xor-ing!`.
+///
+/// ```
+/// struct Foo;
+///
+/// impl BitXor<Foo, Foo> for Foo {
+///     fn bitxor(self, _rhs: Foo) -> Foo {
+///         println!("Bitwise Xor-ing!");
+///         self
+///     }
+/// }
+///
+/// fn main() {
+///     Foo ^ Foo;
+/// }
+/// ```
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+#[lang="bitxor"]
+pub trait BitXor<RHS, Result> {
+    /// The method for the `^` operator
+    fn bitxor(self, rhs: RHS) -> Result;
+}
+
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+macro_rules! bitxor_impl(
+    ($($t:ty)*) => ($(
+        impl BitXor<$t, $t> for $t {
+            #[inline]
+            fn bitxor(self, other: $t) -> $t { self ^ other }
+        }
+    )*)
+)
+
 bitxor_impl!(bool uint u8 u16 u32 u64 int i8 i16 i32 i64)
 
 /// The `Shl` trait is used to specify the functionality of `<<`.
@@ -534,12 +885,16 @@ bitxor_impl!(bool uint u8 u16 u32 u64 int i8 i16 i32 i64)
 ///     Foo << Foo;
 /// }
 /// ```
+// NOTE(stage0): Remove trait after a snapshot
+#[cfg(stage0)]
 #[lang="shl"]
 pub trait Shl<Sized? RHS, Result> for Sized? {
     /// The method for the `<<` operator
     fn shl(&self, rhs: &RHS) -> Result;
 }
 
+// NOTE(stage0): Remove macro after a snapshot
+#[cfg(stage0)]
 macro_rules! shl_impl(
     ($($t:ty)*) => ($(
         impl Shl<uint, $t> for $t {
@@ -551,6 +906,46 @@ macro_rules! shl_impl(
     )*)
 )
 
+/// The `Shl` trait is used to specify the functionality of `<<`.
+///
+/// # Example
+///
+/// A trivial implementation of `Shl`. When `Foo << Foo` happens, it ends up
+/// calling `shl`, and therefore, `main` prints `Shifting left!`.
+///
+/// ```
+/// struct Foo;
+///
+/// impl Shl<Foo, Foo> for Foo {
+///     fn shl(self, _rhs: Foo) -> Foo {
+///         println!("Shifting left!");
+///         self
+///     }
+/// }
+///
+/// fn main() {
+///     Foo << Foo;
+/// }
+/// ```
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+#[lang="shl"]
+pub trait Shl<RHS, Result> {
+    /// The method for the `<<` operator
+    fn shl(self, rhs: RHS) -> Result;
+}
+
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+macro_rules! shl_impl(
+    ($($t:ty)*) => ($(
+        impl Shl<uint, $t> for $t {
+            #[inline]
+            fn shl(self, other: uint) -> $t {
+                self << other
+            }
+        }
+    )*)
+)
+
 shl_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64)
 
 /// The `Shr` trait is used to specify the functionality of `>>`.
@@ -576,12 +971,16 @@ shl_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64)
 ///     Foo >> Foo;
 /// }
 /// ```
+// NOTE(stage0): Remove trait after a snapshot
+#[cfg(stage0)]
 #[lang="shr"]
 pub trait Shr<Sized? RHS, Result> for Sized? {
     /// The method for the `>>` operator
     fn shr(&self, rhs: &RHS) -> Result;
 }
 
+// NOTE(stage0): Remove macro after a snapshot
+#[cfg(stage0)]
 macro_rules! shr_impl(
     ($($t:ty)*) => ($(
         impl Shr<uint, $t> for $t {
@@ -591,6 +990,44 @@ macro_rules! shr_impl(
     )*)
 )
 
+/// The `Shr` trait is used to specify the functionality of `>>`.
+///
+/// # Example
+///
+/// A trivial implementation of `Shr`. When `Foo >> Foo` happens, it ends up
+/// calling `shr`, and therefore, `main` prints `Shifting right!`.
+///
+/// ```
+/// struct Foo;
+///
+/// impl Shr<Foo, Foo> for Foo {
+///     fn shr(self, _rhs: Foo) -> Foo {
+///         println!("Shifting right!");
+///         self
+///     }
+/// }
+///
+/// fn main() {
+///     Foo >> Foo;
+/// }
+/// ```
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+#[lang="shr"]
+pub trait Shr<RHS, Result> {
+    /// The method for the `>>` operator
+    fn shr(self, rhs: RHS) -> Result;
+}
+
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+macro_rules! shr_impl(
+    ($($t:ty)*) => ($(
+        impl Shr<uint, $t> for $t {
+            #[inline]
+            fn shr(self, other: uint) -> $t { self >> other }
+        }
+    )*)
+)
+
 shr_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64)
 
 /// The `Index` trait is used to specify the functionality of indexing operations
diff --git a/src/libcoretest/num/int_macros.rs b/src/libcoretest/num/int_macros.rs
index e25f10bd0dad5..87e2fe752995c 100644
--- a/src/libcoretest/num/int_macros.rs
+++ b/src/libcoretest/num/int_macros.rs
@@ -64,11 +64,11 @@ mod tests {
 
     #[test]
     fn test_bitwise_operators() {
-        assert!(0b1110 as $T == (0b1100 as $T).bitor(&(0b1010 as $T)));
-        assert!(0b1000 as $T == (0b1100 as $T).bitand(&(0b1010 as $T)));
-        assert!(0b0110 as $T == (0b1100 as $T).bitxor(&(0b1010 as $T)));
-        assert!(0b1110 as $T == (0b0111 as $T).shl(&1));
-        assert!(0b0111 as $T == (0b1110 as $T).shr(&1));
+        assert!(0b1110 as $T == (0b1100 as $T).bitor(0b1010 as $T));
+        assert!(0b1000 as $T == (0b1100 as $T).bitand(0b1010 as $T));
+        assert!(0b0110 as $T == (0b1100 as $T).bitxor(0b1010 as $T));
+        assert!(0b1110 as $T == (0b0111 as $T).shl(1));
+        assert!(0b0111 as $T == (0b1110 as $T).shr(1));
         assert!(-(0b11 as $T) - (1 as $T) == (0b11 as $T).not());
     }
 
diff --git a/src/libcoretest/num/mod.rs b/src/libcoretest/num/mod.rs
index 6ee3633d36c14..b7f8b81f996de 100644
--- a/src/libcoretest/num/mod.rs
+++ b/src/libcoretest/num/mod.rs
@@ -12,6 +12,7 @@ use core::cmp::PartialEq;
 use core::fmt::Show;
 use core::num::{NumCast, cast};
 use core::ops::{Add, Sub, Mul, Div, Rem};
+use core::kinds::Copy;
 
 mod int_macros;
 mod i8;
@@ -32,18 +33,19 @@ pub fn test_num<T>(ten: T, two: T) where
      + Add<T, T> + Sub<T, T>
      + Mul<T, T> + Div<T, T>
      + Rem<T, T> + Show
+     + Copy
 {
-    assert_eq!(ten.add(&two),  cast(12i).unwrap());
-    assert_eq!(ten.sub(&two),  cast(8i).unwrap());
-    assert_eq!(ten.mul(&two),  cast(20i).unwrap());
-    assert_eq!(ten.div(&two),  cast(5i).unwrap());
-    assert_eq!(ten.rem(&two),  cast(0i).unwrap());
+    assert_eq!(ten.add(two),  cast(12i).unwrap());
+    assert_eq!(ten.sub(two),  cast(8i).unwrap());
+    assert_eq!(ten.mul(two),  cast(20i).unwrap());
+    assert_eq!(ten.div(two),  cast(5i).unwrap());
+    assert_eq!(ten.rem(two),  cast(0i).unwrap());
 
-    assert_eq!(ten.add(&two),  ten + two);
-    assert_eq!(ten.sub(&two),  ten - two);
-    assert_eq!(ten.mul(&two),  ten * two);
-    assert_eq!(ten.div(&two),  ten / two);
-    assert_eq!(ten.rem(&two),  ten % two);
+    assert_eq!(ten.add(two),  ten + two);
+    assert_eq!(ten.sub(two),  ten - two);
+    assert_eq!(ten.mul(two),  ten * two);
+    assert_eq!(ten.div(two),  ten / two);
+    assert_eq!(ten.rem(two),  ten % two);
 }
 
 #[cfg(test)]
diff --git a/src/libcoretest/num/uint_macros.rs b/src/libcoretest/num/uint_macros.rs
index 01a88119b6470..5657a43de1922 100644
--- a/src/libcoretest/num/uint_macros.rs
+++ b/src/libcoretest/num/uint_macros.rs
@@ -31,11 +31,11 @@ mod tests {
 
     #[test]
     fn test_bitwise_operators() {
-        assert!(0b1110 as $T == (0b1100 as $T).bitor(&(0b1010 as $T)));
-        assert!(0b1000 as $T == (0b1100 as $T).bitand(&(0b1010 as $T)));
-        assert!(0b0110 as $T == (0b1100 as $T).bitxor(&(0b1010 as $T)));
-        assert!(0b1110 as $T == (0b0111 as $T).shl(&1u));
-        assert!(0b0111 as $T == (0b1110 as $T).shr(&1u));
+        assert!(0b1110 as $T == (0b1100 as $T).bitor(0b1010 as $T));
+        assert!(0b1000 as $T == (0b1100 as $T).bitand(0b1010 as $T));
+        assert!(0b0110 as $T == (0b1100 as $T).bitxor(0b1010 as $T));
+        assert!(0b1110 as $T == (0b0111 as $T).shl(1u));
+        assert!(0b0111 as $T == (0b1110 as $T).shr(1u));
         assert!(MAX - (0b1011 as $T) == (0b1011 as $T).not());
     }
 
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index 8e00c96535b1e..59344258833a6 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -30,7 +30,7 @@ use middle::ty::{MethodStatic, MethodStaticUnboxedClosure};
 use util::ppaux::Repr;
 
 use std::kinds;
-use syntax::ast;
+use syntax::{ast, ast_util};
 use syntax::ptr::P;
 use syntax::codemap::Span;
 
@@ -329,6 +329,12 @@ macro_rules! return_if_err(
     )
 )
 
+/// Whether the elements of an overloaded operation are passed by value or by reference
+enum PassArgs {
+    ByValue,
+    ByRef,
+}
+
 impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
     pub fn new(delegate: &'d mut Delegate<'tcx>,
                typer: &'t TYPER,
@@ -438,7 +444,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
             ast::ExprPath(..) => { }
 
             ast::ExprUnary(ast::UnDeref, ref base) => {      // *base
-                if !self.walk_overloaded_operator(expr, &**base, Vec::new()) {
+                if !self.walk_overloaded_operator(expr, &**base, Vec::new(), PassArgs::ByRef) {
                     self.select_from_expr(&**base);
                 }
             }
@@ -452,7 +458,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
             }
 
             ast::ExprIndex(ref lhs, ref rhs) => {       // lhs[rhs]
-                if !self.walk_overloaded_operator(expr, &**lhs, vec![&**rhs]) {
+                if !self.walk_overloaded_operator(expr, &**lhs, vec![&**rhs], PassArgs::ByRef) {
                     self.select_from_expr(&**lhs);
                     self.consume_expr(&**rhs);
                 }
@@ -465,7 +471,8 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
                     (&None, &Some(ref e)) => vec![&**e],
                     (&None, &None) => Vec::new()
                 };
-                let overloaded = self.walk_overloaded_operator(expr, &**base, args);
+                let overloaded =
+                    self.walk_overloaded_operator(expr, &**base, args, PassArgs::ByRef);
                 assert!(overloaded);
             }
 
@@ -570,13 +577,19 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
             }
 
             ast::ExprUnary(_, ref lhs) => {
-                if !self.walk_overloaded_operator(expr, &**lhs, Vec::new()) {
+                if !self.walk_overloaded_operator(expr, &**lhs, Vec::new(), PassArgs::ByRef) {
                     self.consume_expr(&**lhs);
                 }
             }
 
-            ast::ExprBinary(_, ref lhs, ref rhs) => {
-                if !self.walk_overloaded_operator(expr, &**lhs, vec![&**rhs]) {
+            ast::ExprBinary(op, ref lhs, ref rhs) => {
+                let pass_args = if ast_util::is_by_value_binop(op) {
+                    PassArgs::ByValue
+                } else {
+                    PassArgs::ByRef
+                };
+
+                if !self.walk_overloaded_operator(expr, &**lhs, vec![&**rhs], pass_args) {
                     self.consume_expr(&**lhs);
                     self.consume_expr(&**rhs);
                 }
@@ -911,13 +924,24 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
     fn walk_overloaded_operator(&mut self,
                                 expr: &ast::Expr,
                                 receiver: &ast::Expr,
-                                rhs: Vec<&ast::Expr>)
+                                rhs: Vec<&ast::Expr>,
+                                pass_args: PassArgs)
                                 -> bool
     {
         if !self.typer.is_method_call(expr.id) {
             return false;
         }
 
+        match pass_args {
+            PassArgs::ByValue => {
+                self.consume_expr(receiver);
+                self.consume_expr(rhs[0]);
+
+                return true;
+            },
+            PassArgs::ByRef => {},
+        }
+
         self.walk_expr(receiver);
 
         // Arguments (but not receivers) to overloaded operator
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 8e99045cffb58..2f694b382cc67 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -2859,24 +2859,51 @@ impl TypeContents {
     }
 }
 
+// NOTE(stage0): Remove impl after a snapshot
+#[cfg(stage0)]
 impl ops::BitOr<TypeContents,TypeContents> for TypeContents {
     fn bitor(&self, other: &TypeContents) -> TypeContents {
         TypeContents {bits: self.bits | other.bits}
     }
 }
 
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+impl ops::BitOr<TypeContents,TypeContents> for TypeContents {
+    fn bitor(self, other: TypeContents) -> TypeContents {
+        TypeContents {bits: self.bits | other.bits}
+    }
+}
+
+// NOTE(stage0): Remove impl after a snapshot
+#[cfg(stage0)]
 impl ops::BitAnd<TypeContents,TypeContents> for TypeContents {
     fn bitand(&self, other: &TypeContents) -> TypeContents {
         TypeContents {bits: self.bits & other.bits}
     }
 }
 
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+impl ops::BitAnd<TypeContents, TypeContents> for TypeContents {
+    fn bitand(self, other: TypeContents) -> TypeContents {
+        TypeContents {bits: self.bits & other.bits}
+    }
+}
+
+// NOTE(stage0): Remove impl after a snapshot
+#[cfg(stage0)]
 impl ops::Sub<TypeContents,TypeContents> for TypeContents {
     fn sub(&self, other: &TypeContents) -> TypeContents {
         TypeContents {bits: self.bits & !other.bits}
     }
 }
 
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+impl ops::Sub<TypeContents, TypeContents> for TypeContents {
+    fn sub(self, other: TypeContents) -> TypeContents {
+        TypeContents {bits: self.bits & !other.bits}
+    }
+}
+
 impl fmt::Show for TypeContents {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "TypeContents({:b})", self.bits)
diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs
index b8b2395dde172..bde68981ff493 100644
--- a/src/librustc_trans/trans/callee.rs
+++ b/src/librustc_trans/trans/callee.rs
@@ -996,10 +996,11 @@ pub enum CallArgs<'a, 'tcx> {
     // value.
     ArgVals(&'a [ValueRef]),
 
-    // For overloaded operators: `(lhs, Vec(rhs, rhs_id))`. `lhs`
+    // For overloaded operators: `(lhs, Vec(rhs, rhs_id), autoref)`. `lhs`
     // is the left-hand-side and `rhs/rhs_id` is the datum/expr-id of
-    // the right-hand-side arguments (if any).
-    ArgOverloadedOp(Datum<'tcx, Expr>, Vec<(Datum<'tcx, Expr>, ast::NodeId)>),
+    // the right-hand-side arguments (if any). `autoref` indicates whether the `rhs`
+    // arguments should be auto-referenced
+    ArgOverloadedOp(Datum<'tcx, Expr>, Vec<(Datum<'tcx, Expr>, ast::NodeId)>, bool),
 
     // Supply value of arguments as a list of expressions that must be
     // translated, for overloaded call operators.
@@ -1171,7 +1172,7 @@ pub fn trans_args<'a, 'blk, 'tcx>(cx: Block<'blk, 'tcx>,
                                               arg_cleanup_scope,
                                               ignore_self)
         }
-        ArgOverloadedOp(lhs, rhs) => {
+        ArgOverloadedOp(lhs, rhs, autoref) => {
             assert!(!variadic);
 
             llargs.push(unpack_result!(bcx, {
@@ -1185,7 +1186,7 @@ pub fn trans_args<'a, 'blk, 'tcx>(cx: Block<'blk, 'tcx>,
                 llargs.push(unpack_result!(bcx, {
                     trans_arg_datum(bcx, arg_tys[1], rhs,
                                     arg_cleanup_scope,
-                                    DoAutorefArg(rhs_id))
+                                    if autoref { DoAutorefArg(rhs_id) } else { DontAutorefArg })
                 }));
             }
         }
diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs
index e1769001942d5..55672004f1422 100644
--- a/src/librustc_trans/trans/expr.rs
+++ b/src/librustc_trans/trans/expr.rs
@@ -609,7 +609,8 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                                method_call,
                                                base_datum,
                                                args,
-                                               Some(SaveIn(scratch.val))));
+                                               Some(SaveIn(scratch.val)),
+                                               true));
             DatumBlock::new(bcx, scratch.to_expr_datum())
         }
         ast::ExprBox(_, ref contents) => {
@@ -762,7 +763,8 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                                method_call,
                                                base_datum,
                                                vec![(ix_datum, idx.id)],
-                                               Some(SaveIn(scratch.val))));
+                                               Some(SaveIn(scratch.val)),
+                                               true));
             let datum = scratch.to_expr_datum();
             if ty::type_is_sized(bcx.tcx(), elt_ty) {
                 Datum::new(datum.to_llscalarish(bcx), elt_ty, LvalueExpr)
@@ -1092,25 +1094,26 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                       callee::ArgExprs(args.as_slice()),
                                       dest)
         }
-        ast::ExprBinary(_, ref lhs, ref rhs) => {
+        ast::ExprBinary(op, ref lhs, ref rhs) => {
             // if not overloaded, would be RvalueDatumExpr
             let lhs = unpack_datum!(bcx, trans(bcx, &**lhs));
             let rhs_datum = unpack_datum!(bcx, trans(bcx, &**rhs));
             trans_overloaded_op(bcx, expr, MethodCall::expr(expr.id), lhs,
-                                vec![(rhs_datum, rhs.id)], Some(dest)).bcx
+                                vec![(rhs_datum, rhs.id)], Some(dest),
+                                !ast_util::is_by_value_binop(op)).bcx
         }
         ast::ExprUnary(_, ref subexpr) => {
             // if not overloaded, would be RvalueDatumExpr
             let arg = unpack_datum!(bcx, trans(bcx, &**subexpr));
             trans_overloaded_op(bcx, expr, MethodCall::expr(expr.id),
-                                arg, Vec::new(), Some(dest)).bcx
+                                arg, Vec::new(), Some(dest), true).bcx
         }
         ast::ExprIndex(ref base, ref idx) => {
             // if not overloaded, would be RvalueDatumExpr
             let base = unpack_datum!(bcx, trans(bcx, &**base));
             let idx_datum = unpack_datum!(bcx, trans(bcx, &**idx));
             trans_overloaded_op(bcx, expr, MethodCall::expr(expr.id), base,
-                                vec![(idx_datum, idx.id)], Some(dest)).bcx
+                                vec![(idx_datum, idx.id)], Some(dest), true).bcx
         }
         ast::ExprCast(ref val, _) => {
             // DPS output mode means this is a trait cast:
@@ -1803,7 +1806,8 @@ fn trans_overloaded_op<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                    method_call: MethodCall,
                                    lhs: Datum<'tcx, Expr>,
                                    rhs: Vec<(Datum<'tcx, Expr>, ast::NodeId)>,
-                                   dest: Option<Dest>)
+                                   dest: Option<Dest>,
+                                   autoref: bool)
                                    -> Result<'blk, 'tcx> {
     let method_ty = (*bcx.tcx().method_map.borrow())[method_call].ty;
     callee::trans_call_inner(bcx,
@@ -1815,7 +1819,7 @@ fn trans_overloaded_op<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                                           None,
                                                           arg_cleanup_scope)
                              },
-                             callee::ArgOverloadedOp(lhs, rhs),
+                             callee::ArgOverloadedOp(lhs, rhs, autoref),
                              dest)
 }
 
@@ -2122,7 +2126,8 @@ fn deref_once<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             let scratch = rvalue_scratch_datum(bcx, ref_ty, "overloaded_deref");
 
             unpack_result!(bcx, trans_overloaded_op(bcx, expr, method_call,
-                                                    datum, Vec::new(), Some(SaveIn(scratch.val))));
+                                                    datum, Vec::new(), Some(SaveIn(scratch.val)),
+                                                    false));
             scratch.to_expr_datum()
         }
         None => {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 18a773fb949fc..5f8991278b08c 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -77,7 +77,6 @@ type parameter).
 */
 
 pub use self::LvaluePreference::*;
-pub use self::DerefArgs::*;
 pub use self::Expectation::*;
 use self::IsBinopAssignment::*;
 use self::TupleArgumentsFlag::*;
@@ -2117,7 +2116,7 @@ fn try_overloaded_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                                       method_callee.ty,
                                                       call_expression,
                                                       args,
-                                                      DontDerefArgs,
+                                                      AutorefArgs::No,
                                                       TupleArguments);
         fcx.inh.method_map.borrow_mut().insert(method_call, method_callee);
         write_call(fcx, call_expression, output_type);
@@ -2274,7 +2273,7 @@ fn try_overloaded_slice<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                 method_ty_or_err,
                                 expr,
                                 args.as_slice(),
-                                DoDerefArgs,
+                                AutorefArgs::Yes,
                                 DontTupleArguments);
 
     opt_method_ty.map(|method_ty| {
@@ -2480,7 +2479,7 @@ fn lookup_method_for_for_loop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                                   method_type,
                                                   iterator_expr,
                                                   &[],
-                                                  DontDerefArgs,
+                                                  AutorefArgs::No,
                                                   DontTupleArguments);
 
     match method {
@@ -2522,7 +2521,7 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                          method_fn_ty: Ty<'tcx>,
                                          callee_expr: &ast::Expr,
                                          args_no_rcvr: &[&P<ast::Expr>],
-                                         deref_args: DerefArgs,
+                                         autoref_args: AutorefArgs,
                                          tuple_arguments: TupleArgumentsFlag)
                                          -> ty::FnOutput<'tcx> {
     if ty::type_is_error(method_fn_ty) {
@@ -2538,7 +2537,7 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                              err_inputs.as_slice(),
                              callee_expr,
                              args_no_rcvr,
-                             deref_args,
+                             autoref_args,
                              false,
                              tuple_arguments);
         ty::FnConverging(ty::mk_err())
@@ -2551,7 +2550,7 @@ fn check_method_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                      fty.sig.inputs.slice_from(1),
                                      callee_expr,
                                      args_no_rcvr,
-                                     deref_args,
+                                     autoref_args,
                                      fty.sig.variadic,
                                      tuple_arguments);
                 fty.sig.output
@@ -2571,7 +2570,7 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                   fn_inputs: &[Ty<'tcx>],
                                   _callee_expr: &ast::Expr,
                                   args: &[&P<ast::Expr>],
-                                  deref_args: DerefArgs,
+                                  autoref_args: AutorefArgs,
                                   variadic: bool,
                                   tuple_arguments: TupleArgumentsFlag) {
     let tcx = fcx.ccx.tcx;
@@ -2674,8 +2673,8 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                 debug!("checking the argument");
                 let mut formal_ty = formal_tys[i];
 
-                match deref_args {
-                    DoDerefArgs => {
+                match autoref_args {
+                    AutorefArgs::Yes => {
                         match formal_ty.sty {
                             ty::ty_rptr(_, mt) => formal_ty = mt.ty,
                             ty::ty_err => (),
@@ -2690,7 +2689,7 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                             }
                         }
                     }
-                    DontDerefArgs => {}
+                    AutorefArgs::No => {}
                 }
 
                 check_expr_coercable_to_type(fcx, &***arg, formal_ty);
@@ -2904,12 +2903,13 @@ pub fn lookup_tup_field_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
 
 // Controls whether the arguments are automatically referenced. This is useful
 // for overloaded binary and unary operators.
-pub enum DerefArgs {
-    DontDerefArgs,
-    DoDerefArgs
+#[deriving(PartialEq)]
+pub enum AutorefArgs {
+    Yes,
+    No,
 }
 
-impl Copy for DerefArgs {}
+impl Copy for AutorefArgs {}
 
 /// Controls whether the arguments are tupled. This is used for the call
 /// operator.
@@ -2997,7 +2997,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                              fn_sig.inputs.as_slice(),
                              f,
                              args,
-                             DontDerefArgs,
+                             AutorefArgs::No,
                              fn_sig.variadic,
                              DontTupleArguments);
 
@@ -3047,7 +3047,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                                                  fn_ty,
                                                  expr,
                                                  args.as_slice(),
-                                                 DontDerefArgs,
+                                                 AutorefArgs::No,
                                                  DontTupleArguments);
 
         write_call(fcx, expr, ret_ty);
@@ -3130,7 +3130,8 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                                      trait_did: Option<ast::DefId>,
                                      lhs: &'a ast::Expr,
                                      rhs: Option<&P<ast::Expr>>,
-                                     unbound_method: F) -> Ty<'tcx> where
+                                     unbound_method: F,
+                                     autoref_args: AutorefArgs) -> Ty<'tcx> where
         F: FnOnce(),
     {
         let method = match trait_did {
@@ -3183,7 +3184,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                                             method_ty,
                                             op_ex,
                                             args.as_slice(),
-                                            DoDerefArgs,
+                                            autoref_args,
                                             DontTupleArguments) {
                     ty::FnConverging(result_type) => result_type,
                     ty::FnDiverging => ty::mk_err()
@@ -3199,7 +3200,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                                             expected_ty,
                                             op_ex,
                                             args.as_slice(),
-                                            DoDerefArgs,
+                                            autoref_args,
                                             DontTupleArguments);
                 ty::mk_err()
             }
@@ -3347,7 +3348,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                         ast_util::binop_to_string(op),
                         actual)
             }, lhs_resolved_t, None)
-        })
+        }, if ast_util::is_by_value_binop(op) { AutorefArgs::No } else { AutorefArgs::Yes })
     }
 
     fn check_user_unop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
@@ -3363,7 +3364,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                 format!("cannot apply unary operator `{}` to type `{}`",
                         op_str, actual)
             }, rhs_t, None);
-        })
+        }, AutorefArgs::Yes)
     }
 
     // Check field access expressions
diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index cadcee43b4402..3e7992b3cba17 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -131,7 +131,7 @@ use middle::pat_util;
 use util::nodemap::{DefIdMap, NodeMap, FnvHashMap};
 use util::ppaux::{ty_to_string, Repr};
 
-use syntax::ast;
+use syntax::{ast, ast_util};
 use syntax::codemap::Span;
 use syntax::visit;
 use syntax::visit::Visitor;
@@ -637,14 +637,22 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
             visit::walk_expr(rcx, expr);
         }
 
-        ast::ExprIndex(ref lhs, ref rhs) |
-        ast::ExprBinary(_, ref lhs, ref rhs) if has_method_map => {
+        ast::ExprIndex(ref lhs, ref rhs) if has_method_map => {
+            constrain_call(rcx, expr, Some(&**lhs),
+                           Some(&**rhs).into_iter(), true);
+
+            visit::walk_expr(rcx, expr);
+        },
+
+        ast::ExprBinary(op, ref lhs, ref rhs) if has_method_map => {
+            let implicitly_ref_args = !ast_util::is_by_value_binop(op);
+
             // As `expr_method_call`, but the call is via an
             // overloaded op.  Note that we (sadly) currently use an
             // implicit "by ref" sort of passing style here.  This
             // should be converted to an adjustment!
             constrain_call(rcx, expr, Some(&**lhs),
-                           Some(&**rhs).into_iter(), true);
+                           Some(&**rhs).into_iter(), implicitly_ref_args);
 
             visit::walk_expr(rcx, expr);
         }
diff --git a/src/librustdoc/stability_summary.rs b/src/librustdoc/stability_summary.rs
index 881270afe140c..f92cdaf46b6b4 100644
--- a/src/librustdoc/stability_summary.rs
+++ b/src/librustdoc/stability_summary.rs
@@ -42,7 +42,7 @@ pub struct Counts {
 impl Copy for Counts {}
 
 impl Add<Counts, Counts> for Counts {
-    fn add(&self, other: &Counts) -> Counts {
+    fn add(self, other: Counts) -> Counts {
         Counts {
             deprecated:   self.deprecated   + other.deprecated,
             experimental: self.experimental + other.experimental,
diff --git a/src/libstd/bitflags.rs b/src/libstd/bitflags.rs
index ffcd6505dadd1..38bb32ea775ab 100644
--- a/src/libstd/bitflags.rs
+++ b/src/libstd/bitflags.rs
@@ -209,6 +209,8 @@ macro_rules! bitflags {
             }
         }
 
+        // NOTE(stage0): Remove impl after a snapshot
+        #[cfg(stage0)]
         impl BitOr<$BitFlags, $BitFlags> for $BitFlags {
             /// Returns the union of the two sets of flags.
             #[inline]
@@ -217,6 +219,17 @@ macro_rules! bitflags {
             }
         }
 
+        #[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+        impl BitOr<$BitFlags, $BitFlags> for $BitFlags {
+            /// Returns the union of the two sets of flags.
+            #[inline]
+            fn bitor(self, other: $BitFlags) -> $BitFlags {
+                $BitFlags { bits: self.bits | other.bits }
+            }
+        }
+
+        // NOTE(stage0): Remove impl after a snapshot
+        #[cfg(stage0)]
         impl BitXor<$BitFlags, $BitFlags> for $BitFlags {
             /// Returns the left flags, but with all the right flags toggled.
             #[inline]
@@ -225,6 +238,17 @@ macro_rules! bitflags {
             }
         }
 
+        #[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+        impl BitXor<$BitFlags, $BitFlags> for $BitFlags {
+            /// Returns the left flags, but with all the right flags toggled.
+            #[inline]
+            fn bitxor(self, other: $BitFlags) -> $BitFlags {
+                $BitFlags { bits: self.bits ^ other.bits }
+            }
+        }
+
+        // NOTE(stage0): Remove impl after a snapshot
+        #[cfg(stage0)]
         impl BitAnd<$BitFlags, $BitFlags> for $BitFlags {
             /// Returns the intersection between the two sets of flags.
             #[inline]
@@ -233,6 +257,17 @@ macro_rules! bitflags {
             }
         }
 
+        #[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+        impl BitAnd<$BitFlags, $BitFlags> for $BitFlags {
+            /// Returns the intersection between the two sets of flags.
+            #[inline]
+            fn bitand(self, other: $BitFlags) -> $BitFlags {
+                $BitFlags { bits: self.bits & other.bits }
+            }
+        }
+
+        // NOTE(stage0): Remove impl after a snapshot
+        #[cfg(stage0)]
         impl Sub<$BitFlags, $BitFlags> for $BitFlags {
             /// Returns the set difference of the two sets of flags.
             #[inline]
@@ -241,6 +276,15 @@ macro_rules! bitflags {
             }
         }
 
+        #[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+        impl Sub<$BitFlags, $BitFlags> for $BitFlags {
+            /// Returns the set difference of the two sets of flags.
+            #[inline]
+            fn sub(self, other: $BitFlags) -> $BitFlags {
+                $BitFlags { bits: self.bits & !other.bits }
+            }
+        }
+
         impl Not<$BitFlags> for $BitFlags {
             /// Returns the complement of this set of flags.
             #[inline]
diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs
index a15e71b4a2a88..9aaaceb87e6d3 100644
--- a/src/libstd/num/mod.rs
+++ b/src/libstd/num/mod.rs
@@ -19,6 +19,7 @@
 #[cfg(test)] use cmp::PartialEq;
 #[cfg(test)] use fmt::Show;
 #[cfg(test)] use ops::{Add, Sub, Mul, Div, Rem};
+#[cfg(test)] use kinds::Copy;
 
 pub use core::num::{Num, div_rem, Zero, zero, One, one};
 pub use core::num::{Unsigned, pow, Bounded};
@@ -130,18 +131,19 @@ pub fn test_num<T>(ten: T, two: T) where
      + Add<T, T> + Sub<T, T>
      + Mul<T, T> + Div<T, T>
      + Rem<T, T> + Show
+     + Copy
 {
-    assert_eq!(ten.add(&two),  cast(12i).unwrap());
-    assert_eq!(ten.sub(&two),  cast(8i).unwrap());
-    assert_eq!(ten.mul(&two),  cast(20i).unwrap());
-    assert_eq!(ten.div(&two),  cast(5i).unwrap());
-    assert_eq!(ten.rem(&two),  cast(0i).unwrap());
-
-    assert_eq!(ten.add(&two),  ten + two);
-    assert_eq!(ten.sub(&two),  ten - two);
-    assert_eq!(ten.mul(&two),  ten * two);
-    assert_eq!(ten.div(&two),  ten / two);
-    assert_eq!(ten.rem(&two),  ten % two);
+    assert_eq!(ten.add(two),  cast(12i).unwrap());
+    assert_eq!(ten.sub(two),  cast(8i).unwrap());
+    assert_eq!(ten.mul(two),  cast(20i).unwrap());
+    assert_eq!(ten.div(two),  cast(5i).unwrap());
+    assert_eq!(ten.rem(two),  cast(0i).unwrap());
+
+    assert_eq!(ten.add(two),  ten + two);
+    assert_eq!(ten.sub(two),  ten - two);
+    assert_eq!(ten.mul(two),  ten * two);
+    assert_eq!(ten.div(two),  ten / two);
+    assert_eq!(ten.rem(two),  ten % two);
 }
 
 #[cfg(test)]
diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs
index 34a3d6aa27536..f98cebd967596 100644
--- a/src/libstd/time/duration.rs
+++ b/src/libstd/time/duration.rs
@@ -276,6 +276,8 @@ impl Neg<Duration> for Duration {
     }
 }
 
+// NOTE(stage0): Remove impl after a snapshot
+#[cfg(stage0)]
 impl Add<Duration,Duration> for Duration {
     fn add(&self, rhs: &Duration) -> Duration {
         let mut secs = self.secs + rhs.secs;
@@ -288,6 +290,21 @@ impl Add<Duration,Duration> for Duration {
     }
 }
 
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+impl Add<Duration, Duration> for Duration {
+    fn add(self, rhs: Duration) -> Duration {
+        let mut secs = self.secs + rhs.secs;
+        let mut nanos = self.nanos + rhs.nanos;
+        if nanos >= NANOS_PER_SEC {
+            nanos -= NANOS_PER_SEC;
+            secs += 1;
+        }
+        Duration { secs: secs, nanos: nanos }
+    }
+}
+
+// NOTE(stage0): Remove impl after a snapshot
+#[cfg(stage0)]
 impl Sub<Duration,Duration> for Duration {
     fn sub(&self, rhs: &Duration) -> Duration {
         let mut secs = self.secs - rhs.secs;
@@ -300,6 +317,21 @@ impl Sub<Duration,Duration> for Duration {
     }
 }
 
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+impl Sub<Duration, Duration> for Duration {
+    fn sub(self, rhs: Duration) -> Duration {
+        let mut secs = self.secs - rhs.secs;
+        let mut nanos = self.nanos - rhs.nanos;
+        if nanos < 0 {
+            nanos += NANOS_PER_SEC;
+            secs -= 1;
+        }
+        Duration { secs: secs, nanos: nanos }
+    }
+}
+
+// NOTE(stage0): Remove impl after a snapshot
+#[cfg(stage0)]
 impl Mul<i32,Duration> for Duration {
     fn mul(&self, rhs: &i32) -> Duration {
         // Multiply nanoseconds as i64, because it cannot overflow that way.
@@ -310,6 +342,19 @@ impl Mul<i32,Duration> for Duration {
     }
 }
 
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+impl Mul<i32, Duration> for Duration {
+    fn mul(self, rhs: i32) -> Duration {
+        // Multiply nanoseconds as i64, because it cannot overflow that way.
+        let total_nanos = self.nanos as i64 * rhs as i64;
+        let (extra_secs, nanos) = div_mod_floor_64(total_nanos, NANOS_PER_SEC as i64);
+        let secs = self.secs * rhs as i64 + extra_secs;
+        Duration { secs: secs, nanos: nanos as i32 }
+    }
+}
+
+// NOTE(stage0): Remove impl after a snapshot
+#[cfg(stage0)]
 impl Div<i32,Duration> for Duration {
     fn div(&self, rhs: &i32) -> Duration {
         let mut secs = self.secs / *rhs as i64;
@@ -328,6 +373,25 @@ impl Div<i32,Duration> for Duration {
     }
 }
 
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+impl Div<i32, Duration> for Duration {
+    fn div(self, rhs: i32) -> Duration {
+        let mut secs = self.secs / rhs as i64;
+        let carry = self.secs - secs * rhs as i64;
+        let extra_nanos = carry * NANOS_PER_SEC as i64 / rhs as i64;
+        let mut nanos = self.nanos / rhs + extra_nanos as i32;
+        if nanos >= NANOS_PER_SEC {
+            nanos -= NANOS_PER_SEC;
+            secs += 1;
+        }
+        if nanos < 0 {
+            nanos += NANOS_PER_SEC;
+            secs -= 1;
+        }
+        Duration { secs: secs, nanos: nanos }
+    }
+}
+
 impl fmt::Show for Duration {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         // technically speaking, negative duration is not valid ISO 8601,
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 7579972c6d843..71ce4847922d3 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -85,6 +85,16 @@ pub fn is_shift_binop(b: BinOp) -> bool {
     }
 }
 
+/// Returns `true` is the binary operator takes its arguments by value
+pub fn is_by_value_binop(b: BinOp) -> bool {
+    match b {
+        BiAdd | BiSub | BiMul | BiDiv | BiRem | BiBitXor | BiBitAnd | BiBitOr | BiShl | BiShr => {
+            true
+        }
+        _ => false
+    }
+}
+
 pub fn unop_to_string(op: UnOp) -> &'static str {
     match op {
       UnUniq => "box() ",
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index d2fe667339c84..592fdd7207c7b 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -52,35 +52,71 @@ impl Pos for BytePos {
     fn to_uint(&self) -> uint { let BytePos(n) = *self; n as uint }
 }
 
+// NOTE(stage0): Remove impl after a snapshot
+#[cfg(stage0)]
 impl Add<BytePos, BytePos> for BytePos {
     fn add(&self, rhs: &BytePos) -> BytePos {
         BytePos((self.to_uint() + rhs.to_uint()) as u32)
     }
 }
 
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+impl Add<BytePos, BytePos> for BytePos {
+    fn add(self, rhs: BytePos) -> BytePos {
+        BytePos((self.to_uint() + rhs.to_uint()) as u32)
+    }
+}
+
+// NOTE(stage0): Remove impl after a snapshot
+#[cfg(stage0)]
 impl Sub<BytePos, BytePos> for BytePos {
     fn sub(&self, rhs: &BytePos) -> BytePos {
         BytePos((self.to_uint() - rhs.to_uint()) as u32)
     }
 }
 
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+impl Sub<BytePos, BytePos> for BytePos {
+    fn sub(self, rhs: BytePos) -> BytePos {
+        BytePos((self.to_uint() - rhs.to_uint()) as u32)
+    }
+}
+
 impl Pos for CharPos {
     fn from_uint(n: uint) -> CharPos { CharPos(n) }
     fn to_uint(&self) -> uint { let CharPos(n) = *self; n }
 }
 
+// NOTE(stage0): Remove impl after a snapshot
+#[cfg(stage0)]
 impl Add<CharPos,CharPos> for CharPos {
     fn add(&self, rhs: &CharPos) -> CharPos {
         CharPos(self.to_uint() + rhs.to_uint())
     }
 }
 
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+impl Add<CharPos, CharPos> for CharPos {
+    fn add(self, rhs: CharPos) -> CharPos {
+        CharPos(self.to_uint() + rhs.to_uint())
+    }
+}
+
+// NOTE(stage0): Remove impl after a snapshot
+#[cfg(stage0)]
 impl Sub<CharPos,CharPos> for CharPos {
     fn sub(&self, rhs: &CharPos) -> CharPos {
         CharPos(self.to_uint() - rhs.to_uint())
     }
 }
 
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+impl Sub<CharPos, CharPos> for CharPos {
+    fn sub(self, rhs: CharPos) -> CharPos {
+        CharPos(self.to_uint() - rhs.to_uint())
+    }
+}
+
 /// Spans represent a region of code, used for error reporting. Positions in spans
 /// are *absolute* positions from the beginning of the codemap, not positions
 /// relative to FileMaps. Methods on the CodeMap can be used to relate spans back
diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs
index 99799fecb7882..e2439bad178fe 100644
--- a/src/libsyntax/ext/tt/transcribe.rs
+++ b/src/libsyntax/ext/tt/transcribe.rs
@@ -106,6 +106,8 @@ enum LockstepIterSize {
     LisContradiction(String),
 }
 
+// NOTE(stage0): Remove impl after a snapshot
+#[cfg(stage0)]
 impl Add<LockstepIterSize, LockstepIterSize> for LockstepIterSize {
     fn add(&self, other: &LockstepIterSize) -> LockstepIterSize {
         match *self {
@@ -127,6 +129,28 @@ impl Add<LockstepIterSize, LockstepIterSize> for LockstepIterSize {
     }
 }
 
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+impl Add<LockstepIterSize, LockstepIterSize> for LockstepIterSize {
+    fn add(self, other: LockstepIterSize) -> LockstepIterSize {
+        match self {
+            LisUnconstrained => other,
+            LisContradiction(_) => self,
+            LisConstraint(l_len, ref l_id) => match other {
+                LisUnconstrained => self.clone(),
+                LisContradiction(_) => other,
+                LisConstraint(r_len, _) if l_len == r_len => self.clone(),
+                LisConstraint(r_len, r_id) => {
+                    let l_n = token::get_ident(l_id.clone());
+                    let r_n = token::get_ident(r_id);
+                    LisContradiction(format!("inconsistent lockstep iteration: \
+                                              '{}' has {} items, but '{}' has {}",
+                                              l_n, l_len, r_n, r_len).to_string())
+                }
+            },
+        }
+    }
+}
+
 fn lockstep_iter_size(t: &TokenTree, r: &TtReader) -> LockstepIterSize {
     match *t {
         TtDelimited(_, ref delimed) => {
diff --git a/src/libtime/lib.rs b/src/libtime/lib.rs
index e293c547944d5..4129086e9ec97 100644
--- a/src/libtime/lib.rs
+++ b/src/libtime/lib.rs
@@ -99,6 +99,8 @@ impl Timespec {
     }
 }
 
+// NOTE(stage0): Remove impl after a snapshot
+#[cfg(stage0)]
 impl Add<Duration, Timespec> for Timespec {
     fn add(&self, other: &Duration) -> Timespec {
         let d_sec = other.num_seconds();
@@ -119,6 +121,29 @@ impl Add<Duration, Timespec> for Timespec {
     }
 }
 
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+impl Add<Duration, Timespec> for Timespec {
+    fn add(self, other: Duration) -> Timespec {
+        let d_sec = other.num_seconds();
+        // It is safe to unwrap the nanoseconds, because there cannot be
+        // more than one second left, which fits in i64 and in i32.
+        let d_nsec = (other - Duration::seconds(d_sec))
+                     .num_nanoseconds().unwrap() as i32;
+        let mut sec = self.sec + d_sec;
+        let mut nsec = self.nsec + d_nsec;
+        if nsec >= NSEC_PER_SEC {
+            nsec -= NSEC_PER_SEC;
+            sec += 1;
+        } else if nsec < 0 {
+            nsec += NSEC_PER_SEC;
+            sec -= 1;
+        }
+        Timespec::new(sec, nsec)
+    }
+}
+
+// NOTE(stage0): Remove impl after a snapshot
+#[cfg(stage0)]
 impl Sub<Timespec, Duration> for Timespec {
     fn sub(&self, other: &Timespec) -> Duration {
         let sec = self.sec - other.sec;
@@ -127,6 +152,15 @@ impl Sub<Timespec, Duration> for Timespec {
     }
 }
 
+#[cfg(not(stage0))]  // NOTE(stage0): Remove cfg after a snapshot
+impl Sub<Timespec, Duration> for Timespec {
+    fn sub(self, other: Timespec) -> Duration {
+        let sec = self.sec - other.sec;
+        let nsec = self.nsec - other.nsec;
+        Duration::seconds(sec) + Duration::nanoseconds(nsec as i64)
+    }
+}
+
 /// Returns the current time as a `timespec` containing the seconds and
 /// nanoseconds since 1970-01-01T00:00:00Z.
 pub fn get_time() -> Timespec {
diff --git a/src/test/auxiliary/trait_inheritance_overloading_xc.rs b/src/test/auxiliary/trait_inheritance_overloading_xc.rs
index 95bdecd77605f..61854aba2790d 100644
--- a/src/test/auxiliary/trait_inheritance_overloading_xc.rs
+++ b/src/test/auxiliary/trait_inheritance_overloading_xc.rs
@@ -10,24 +10,24 @@
 
 use std::cmp::PartialEq;
 
-pub trait MyNum : Add<Self,Self> + Sub<Self,Self> + Mul<Self,Self> + PartialEq {
+pub trait MyNum : Add<Self,Self> + Sub<Self,Self> + Mul<Self,Self> + PartialEq + Clone {
 }
 
-#[deriving(Show)]
+#[deriving(Clone, Show)]
 pub struct MyInt {
     pub val: int
 }
 
 impl Add<MyInt, MyInt> for MyInt {
-    fn add(&self, other: &MyInt) -> MyInt { mi(self.val + other.val) }
+    fn add(self, other: MyInt) -> MyInt { mi(self.val + other.val) }
 }
 
 impl Sub<MyInt, MyInt> for MyInt {
-    fn sub(&self, other: &MyInt) -> MyInt { mi(self.val - other.val) }
+    fn sub(self, other: MyInt) -> MyInt { mi(self.val - other.val) }
 }
 
 impl Mul<MyInt, MyInt> for MyInt {
-    fn mul(&self, other: &MyInt) -> MyInt { mi(self.val * other.val) }
+    fn mul(self, other: MyInt) -> MyInt { mi(self.val * other.val) }
 }
 
 impl PartialEq for MyInt {
diff --git a/src/test/compile-fail/binop-consume-args.rs b/src/test/compile-fail/binop-consume-args.rs
new file mode 100644
index 0000000000000..2bdd148b99bd0
--- /dev/null
+++ b/src/test/compile-fail/binop-consume-args.rs
@@ -0,0 +1,73 @@
+// 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.
+
+// Test that binary operators consume their arguments
+
+fn add<A: Add<B, ()>, B>(lhs: A, rhs: B) {
+    lhs + rhs;
+    drop(lhs);  //~ ERROR use of moved value: `lhs`
+    drop(rhs);  //~ ERROR use of moved value: `rhs`
+}
+
+fn sub<A: Sub<B, ()>, B>(lhs: A, rhs: B) {
+    lhs - rhs;
+    drop(lhs);  //~ ERROR use of moved value: `lhs`
+    drop(rhs);  //~ ERROR use of moved value: `rhs`
+}
+
+fn mul<A: Mul<B, ()>, B>(lhs: A, rhs: B) {
+    lhs * rhs;
+    drop(lhs);  //~ ERROR use of moved value: `lhs`
+    drop(rhs);  //~ ERROR use of moved value: `rhs`
+}
+
+fn div<A: Div<B, ()>, B>(lhs: A, rhs: B) {
+    lhs / rhs;
+    drop(lhs);  //~ ERROR use of moved value: `lhs`
+    drop(rhs);  //~ ERROR use of moved value: `rhs`
+}
+
+fn rem<A: Rem<B, ()>, B>(lhs: A, rhs: B) {
+    lhs % rhs;
+    drop(lhs);  //~ ERROR use of moved value: `lhs`
+    drop(rhs);  //~ ERROR use of moved value: `rhs`
+}
+
+fn bitand<A: BitAnd<B, ()>, B>(lhs: A, rhs: B) {
+    lhs & rhs;
+    drop(lhs);  //~ ERROR use of moved value: `lhs`
+    drop(rhs);  //~ ERROR use of moved value: `rhs`
+}
+
+fn bitor<A: BitOr<B, ()>, B>(lhs: A, rhs: B) {
+    lhs | rhs;
+    drop(lhs);  //~ ERROR use of moved value: `lhs`
+    drop(rhs);  //~ ERROR use of moved value: `rhs`
+}
+
+fn bitxor<A: BitXor<B, ()>, B>(lhs: A, rhs: B) {
+    lhs ^ rhs;
+    drop(lhs);  //~ ERROR use of moved value: `lhs`
+    drop(rhs);  //~ ERROR use of moved value: `rhs`
+}
+
+fn shl<A: Shl<B, ()>, B>(lhs: A, rhs: B) {
+    lhs << rhs;
+    drop(lhs);  //~ ERROR use of moved value: `lhs`
+    drop(rhs);  //~ ERROR use of moved value: `rhs`
+}
+
+fn shr<A: Shr<B, ()>, B>(lhs: A, rhs: B) {
+    lhs >> rhs;
+    drop(lhs);  //~ ERROR use of moved value: `lhs`
+    drop(rhs);  //~ ERROR use of moved value: `rhs`
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/binop-move-semantics.rs b/src/test/compile-fail/binop-move-semantics.rs
new file mode 100644
index 0000000000000..d9440e1837572
--- /dev/null
+++ b/src/test/compile-fail/binop-move-semantics.rs
@@ -0,0 +1,69 @@
+// 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.
+
+// Test that move restrictions are enforced on overloaded binary operations
+
+fn double_move<T: Add<T, ()>>(x: T) {
+    x
+    +
+    x;  //~ ERROR: use of moved value
+}
+
+fn move_then_borrow<T: Add<T, ()> + Clone>(x: T) {
+    x
+    +
+    x.clone();  //~ ERROR: use of moved value
+}
+
+fn move_borrowed<T: Add<T, ()>>(x: T, mut y: T) {
+    let m = &x;
+    let n = &mut y;
+
+    x  //~ ERROR: cannot move out of `x` because it is borrowed
+    +
+    y;  //~ ERROR: cannot move out of `y` because it is borrowed
+}
+
+fn illegal_dereference<T: Add<T, ()>>(mut x: T, y: T) {
+    let m = &mut x;
+    let n = &y;
+
+    *m  //~ ERROR: cannot move out of dereference of `&mut`-pointer
+    +
+    *n;  //~ ERROR: cannot move out of dereference of `&`-pointer
+}
+
+struct Foo;
+
+impl<'a, 'b> Add<&'b Foo, ()> for &'a mut Foo {
+    fn add(self, _: &Foo) {}
+}
+
+impl<'a, 'b> Add<&'b mut Foo, ()> for &'a Foo {
+    fn add(self, _: &mut Foo) {}
+}
+
+fn mut_plus_immut() {
+    let mut f = Foo;
+
+    &mut f
+    +
+    &f;  //~ ERROR: cannot borrow `f` as immutable because it is also borrowed as mutable
+}
+
+fn immut_plus_mut() {
+    let mut f = Foo;
+
+    &f
+    +
+    &mut f;  //~ ERROR: cannot borrow `f` as mutable because it is also borrowed as immutable
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/borrowck-loan-in-overloaded-op.rs b/src/test/compile-fail/borrowck-loan-in-overloaded-op.rs
index 4a6c20079c17e..692303fc1e481 100644
--- a/src/test/compile-fail/borrowck-loan-in-overloaded-op.rs
+++ b/src/test/compile-fail/borrowck-loan-in-overloaded-op.rs
@@ -9,18 +9,19 @@
 // except according to those terms.
 
 
+#[deriving(Clone)]
 struct foo(Box<uint>);
 
 impl Add<foo, foo> for foo {
-    fn add(&self, f: &foo) -> foo {
-        let foo(box i) = *self;
-        let foo(box j) = *f;
+    fn add(self, f: foo) -> foo {
+        let foo(box i) = self;
+        let foo(box j) = f;
         foo(box() (i + j))
     }
 }
 
 fn main() {
     let x = foo(box 3);
-    let _y = x + {x}; // the `{x}` forces a move to occur
-    //~^ ERROR cannot move out of `x`
+    let _y = {x} + x.clone(); // the `{x}` forces a move to occur
+    //~^ ERROR use of moved value: `x`
 }
diff --git a/src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs b/src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs
index c5d7b6fa4518f..b83e1544c96d3 100644
--- a/src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs
+++ b/src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs
@@ -8,15 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
+#[deriving(Copy)]
 struct Point {
     x: int,
     y: int,
 }
 
-impl Add<int,int> for Point {
-    fn add(&self, z: &int) -> int {
-        self.x + self.y + (*z)
+impl Add<int, int> for Point {
+    fn add(self, z: int) -> int {
+        self.x + self.y + z
     }
 }
 
@@ -41,7 +41,7 @@ fn b() {
 
     let q = &mut p;
 
-    p + 3;  //~ ERROR cannot borrow `p`
+    p + 3;  //~ ERROR cannot use `p`
     p.times(3); //~ ERROR cannot borrow `p`
 
     *q + 3; // OK to use the new alias `q`
diff --git a/src/test/compile-fail/wrong-mul-method-signature.rs b/src/test/compile-fail/wrong-mul-method-signature.rs
index aead739d3e01a..b5e4cac75550f 100644
--- a/src/test/compile-fail/wrong-mul-method-signature.rs
+++ b/src/test/compile-fail/wrong-mul-method-signature.rs
@@ -17,12 +17,12 @@ struct Vec1 {
     x: f64
 }
 
-// Expecting ref in input signature
+// Expecting value in input signature
 impl Mul<f64, Vec1> for Vec1 {
-    fn mul(&self, s: f64) -> Vec1 {
-    //~^ ERROR: method `mul` has an incompatible type for trait: expected &-ptr, found f64
+    fn mul(self, s: &f64) -> Vec1 {
+    //~^ ERROR: method `mul` has an incompatible type for trait: expected f64, found &-ptr
         Vec1 {
-            x: self.x * s
+            x: self.x * *s
         }
     }
 }
@@ -34,8 +34,8 @@ struct Vec2 {
 
 // Wrong type parameter ordering
 impl Mul<Vec2, f64> for Vec2 {
-    fn mul(&self, s: f64) -> Vec2 {
-    //~^ ERROR: method `mul` has an incompatible type for trait: expected &-ptr, found f64
+    fn mul(self, s: f64) -> Vec2 {
+    //~^ ERROR: method `mul` has an incompatible type for trait: expected struct Vec2, found f64
         Vec2 {
             x: self.x * s,
             y: self.y * s
@@ -51,9 +51,9 @@ struct Vec3 {
 
 // Unexpected return type
 impl Mul<f64, i32> for Vec3 {
-    fn mul(&self, s: &f64) -> f64 {
+    fn mul(self, s: f64) -> f64 {
     //~^ ERROR: method `mul` has an incompatible type for trait: expected i32, found f64
-        *s
+        s
     }
 }
 
diff --git a/src/test/run-pass/bool.rs b/src/test/run-pass/bool.rs
index 91075633ab8d8..238d0ecdca7f8 100644
--- a/src/test/run-pass/bool.rs
+++ b/src/test/run-pass/bool.rs
@@ -16,30 +16,30 @@ fn main() {
     assert_eq!(false != true, true);
     assert_eq!(false.ne(&false), false);
 
-    assert_eq!(false.bitand(&false), false);
-    assert_eq!(true.bitand(&false), false);
-    assert_eq!(false.bitand(&true), false);
-    assert_eq!(true.bitand(&true), true);
+    assert_eq!(false.bitand(false), false);
+    assert_eq!(true.bitand(false), false);
+    assert_eq!(false.bitand(true), false);
+    assert_eq!(true.bitand(true), true);
 
     assert_eq!(false & false, false);
     assert_eq!(true & false, false);
     assert_eq!(false & true, false);
     assert_eq!(true & true, true);
 
-    assert_eq!(false.bitor(&false), false);
-    assert_eq!(true.bitor(&false), true);
-    assert_eq!(false.bitor(&true), true);
-    assert_eq!(true.bitor(&true), true);
+    assert_eq!(false.bitor(false), false);
+    assert_eq!(true.bitor(false), true);
+    assert_eq!(false.bitor(true), true);
+    assert_eq!(true.bitor(true), true);
 
     assert_eq!(false | false, false);
     assert_eq!(true | false, true);
     assert_eq!(false | true, true);
     assert_eq!(true | true, true);
 
-    assert_eq!(false.bitxor(&false), false);
-    assert_eq!(true.bitxor(&false), true);
-    assert_eq!(false.bitxor(&true), true);
-    assert_eq!(true.bitxor(&true), false);
+    assert_eq!(false.bitxor(false), false);
+    assert_eq!(true.bitxor(false), true);
+    assert_eq!(false.bitxor(true), true);
+    assert_eq!(true.bitxor(true), false);
 
     assert_eq!(false ^ false, false);
     assert_eq!(true ^ false, true);
diff --git a/src/test/run-pass/deriving-zero.rs b/src/test/run-pass/deriving-zero.rs
index 690d82a4ed25a..88f3e5775b78b 100644
--- a/src/test/run-pass/deriving-zero.rs
+++ b/src/test/run-pass/deriving-zero.rs
@@ -15,10 +15,10 @@ use std::num::Zero;
 struct Vector2<T>(T, T);
 
 impl<T: Add<T, T>> Add<Vector2<T>, Vector2<T>> for Vector2<T> {
-    fn add(&self, other: &Vector2<T>) -> Vector2<T> {
+    fn add(self, other: Vector2<T>) -> Vector2<T> {
         match (self, other) {
-            (&Vector2(ref x0, ref y0), &Vector2(ref x1, ref y1)) => {
-                Vector2(*x0 + *x1, *y0 + *y1)
+            (Vector2(x0, y0), Vector2(x1, y1)) => {
+                Vector2(x0 + x1, y0 + y1)
             }
         }
     }
@@ -30,7 +30,7 @@ struct Vector3<T> {
 }
 
 impl<T: Add<T, T>> Add<Vector3<T>, Vector3<T>> for Vector3<T> {
-    fn add(&self, other: &Vector3<T>) -> Vector3<T> {
+    fn add(self, other: Vector3<T>) -> Vector3<T> {
         Vector3 {
             x: self.x + other.x,
             y: self.y + other.y,
@@ -47,7 +47,7 @@ struct Matrix3x2<T> {
 }
 
 impl<T: Add<T, T>> Add<Matrix3x2<T>, Matrix3x2<T>> for Matrix3x2<T> {
-    fn add(&self, other: &Matrix3x2<T>) -> Matrix3x2<T> {
+    fn add(self, other: Matrix3x2<T>) -> Matrix3x2<T> {
         Matrix3x2 {
             x: self.x + other.x,
             y: self.y + other.y,
diff --git a/src/test/run-pass/issue-3743.rs b/src/test/run-pass/issue-3743.rs
index ada3e37c092a7..80d3d29bc004d 100644
--- a/src/test/run-pass/issue-3743.rs
+++ b/src/test/run-pass/issue-3743.rs
@@ -28,7 +28,7 @@ trait RhsOfVec2Mul<Result> { fn mul_vec2_by(&self, lhs: &Vec2) -> Result; }
 
 // Vec2's implementation of Mul "from the other side" using the above trait
 impl<Res, Rhs: RhsOfVec2Mul<Res>> Mul<Rhs,Res> for Vec2 {
-    fn mul(&self, rhs: &Rhs) -> Res { rhs.mul_vec2_by(self) }
+    fn mul(self, rhs: Rhs) -> Res { rhs.mul_vec2_by(&self) }
 }
 
 // Implementation of 'f64 as right-hand-side of Vec2::Mul'
diff --git a/src/test/run-pass/numeric-method-autoexport.rs b/src/test/run-pass/numeric-method-autoexport.rs
index 585ade71fc603..f8184d248ff01 100644
--- a/src/test/run-pass/numeric-method-autoexport.rs
+++ b/src/test/run-pass/numeric-method-autoexport.rs
@@ -18,19 +18,19 @@
 pub fn main() {
 // ints
     // num
-    assert_eq!(15i.add(&6), 21);
-    assert_eq!(15i8.add(&6i8), 21i8);
-    assert_eq!(15i16.add(&6i16), 21i16);
-    assert_eq!(15i32.add(&6i32), 21i32);
-    assert_eq!(15i64.add(&6i64), 21i64);
+    assert_eq!(15i.add(6), 21);
+    assert_eq!(15i8.add(6i8), 21i8);
+    assert_eq!(15i16.add(6i16), 21i16);
+    assert_eq!(15i32.add(6i32), 21i32);
+    assert_eq!(15i64.add(6i64), 21i64);
 
 // uints
     // num
-    assert_eq!(15u.add(&6u), 21u);
-    assert_eq!(15u8.add(&6u8), 21u8);
-    assert_eq!(15u16.add(&6u16), 21u16);
-    assert_eq!(15u32.add(&6u32), 21u32);
-    assert_eq!(15u64.add(&6u64), 21u64);
+    assert_eq!(15u.add(6u), 21u);
+    assert_eq!(15u8.add(6u8), 21u8);
+    assert_eq!(15u16.add(6u16), 21u16);
+    assert_eq!(15u32.add(6u32), 21u32);
+    assert_eq!(15u64.add(6u64), 21u64);
 
 // floats
     // num
diff --git a/src/test/run-pass/operator-multidispatch.rs b/src/test/run-pass/operator-multidispatch.rs
index fc79e4f0edb36..cb3397c00bc57 100644
--- a/src/test/run-pass/operator-multidispatch.rs
+++ b/src/test/run-pass/operator-multidispatch.rs
@@ -20,13 +20,13 @@ struct Point {
 }
 
 impl ops::Add<Point,Point> for Point {
-    fn add(&self, other: &Point) -> Point {
-        Point {x: self.x + (*other).x, y: self.y + (*other).y}
+    fn add(self, other: Point) -> Point {
+        Point {x: self.x + other.x, y: self.y + other.y}
     }
 }
 
 impl ops::Add<int,Point> for Point {
-    fn add(&self, &other: &int) -> Point {
+    fn add(self, other: int) -> Point {
         Point {x: self.x + other,
                y: self.y + other}
     }
diff --git a/src/test/run-pass/operator-overloading.rs b/src/test/run-pass/operator-overloading.rs
index a896d2b06f7bd..0f3da6836cb34 100644
--- a/src/test/run-pass/operator-overloading.rs
+++ b/src/test/run-pass/operator-overloading.rs
@@ -12,21 +12,21 @@
 use std::cmp;
 use std::ops;
 
-#[deriving(Show)]
+#[deriving(Copy, Show)]
 struct Point {
     x: int,
     y: int
 }
 
 impl ops::Add<Point,Point> for Point {
-    fn add(&self, other: &Point) -> Point {
-        Point {x: self.x + (*other).x, y: self.y + (*other).y}
+    fn add(self, other: Point) -> Point {
+        Point {x: self.x + other.x, y: self.y + other.y}
     }
 }
 
 impl ops::Sub<Point,Point> for Point {
-    fn sub(&self, other: &Point) -> Point {
-        Point {x: self.x - (*other).x, y: self.y - (*other).y}
+    fn sub(self, other: Point) -> Point {
+        Point {x: self.x - other.x, y: self.y - other.y}
     }
 }
 
diff --git a/src/test/run-pass/overloaded-calls-param-vtables.rs b/src/test/run-pass/overloaded-calls-param-vtables.rs
index d0dbee39ae095..2e8ec3916bd89 100644
--- a/src/test/run-pass/overloaded-calls-param-vtables.rs
+++ b/src/test/run-pass/overloaded-calls-param-vtables.rs
@@ -18,7 +18,7 @@ struct G;
 
 impl<'a, A: Add<int, int>> Fn<(A,), int> for G {
     extern "rust-call" fn call(&self, (arg,): (A,)) -> int {
-        arg.add(&1)
+        arg.add(1)
     }
 }
 
diff --git a/src/test/run-pass/simd-generics.rs b/src/test/run-pass/simd-generics.rs
index 31c29b615fc09..42f93a97142d2 100644
--- a/src/test/run-pass/simd-generics.rs
+++ b/src/test/run-pass/simd-generics.rs
@@ -22,8 +22,8 @@ fn add<T: ops::Add<T, T>>(lhs: T, rhs: T) -> T {
 }
 
 impl ops::Add<f32x4, f32x4> for f32x4 {
-    fn add(&self, rhs: &f32x4) -> f32x4 {
-        *self + *rhs
+    fn add(self, rhs: f32x4) -> f32x4 {
+        self + rhs
     }
 }
 
diff --git a/src/test/run-pass/trait-inheritance-overloading-xc-exe.rs b/src/test/run-pass/trait-inheritance-overloading-xc-exe.rs
index 7760395bf1c95..2a087e5e425ad 100644
--- a/src/test/run-pass/trait-inheritance-overloading-xc-exe.rs
+++ b/src/test/run-pass/trait-inheritance-overloading-xc-exe.rs
@@ -14,7 +14,7 @@ extern crate trait_inheritance_overloading_xc;
 use trait_inheritance_overloading_xc::{MyNum, MyInt};
 
 fn f<T:MyNum>(x: T, y: T) -> (T, T, T) {
-    return (x + y, x - y, x * y);
+    return (x.clone() + y.clone(), x.clone() - y.clone(), x * y);
 }
 
 fn mi(v: int) -> MyInt { MyInt { val: v } }
diff --git a/src/test/run-pass/trait-inheritance-overloading.rs b/src/test/run-pass/trait-inheritance-overloading.rs
index b13ea7ae0baef..5f8e945cce860 100644
--- a/src/test/run-pass/trait-inheritance-overloading.rs
+++ b/src/test/run-pass/trait-inheritance-overloading.rs
@@ -10,21 +10,21 @@
 
 use std::cmp::PartialEq;
 
-trait MyNum : Add<Self,Self> + Sub<Self,Self> + Mul<Self,Self> + PartialEq { }
+trait MyNum : Add<Self,Self> + Sub<Self,Self> + Mul<Self,Self> + PartialEq + Clone { }
 
-#[deriving(Show)]
+#[deriving(Clone, Show)]
 struct MyInt { val: int }
 
 impl Add<MyInt, MyInt> for MyInt {
-    fn add(&self, other: &MyInt) -> MyInt { mi(self.val + other.val) }
+    fn add(self, other: MyInt) -> MyInt { mi(self.val + other.val) }
 }
 
 impl Sub<MyInt, MyInt> for MyInt {
-    fn sub(&self, other: &MyInt) -> MyInt { mi(self.val - other.val) }
+    fn sub(self, other: MyInt) -> MyInt { mi(self.val - other.val) }
 }
 
 impl Mul<MyInt, MyInt> for MyInt {
-    fn mul(&self, other: &MyInt) -> MyInt { mi(self.val * other.val) }
+    fn mul(self, other: MyInt) -> MyInt { mi(self.val * other.val) }
 }
 
 impl PartialEq for MyInt {
@@ -35,7 +35,7 @@ impl PartialEq for MyInt {
 impl MyNum for MyInt {}
 
 fn f<T:MyNum>(x: T, y: T) -> (T, T, T) {
-    return (x + y, x - y, x * y);
+    return (x.clone() + y.clone(), x.clone() - y.clone(), x * y);
 }
 
 fn mi(v: int) -> MyInt { MyInt { val: v } }