Skip to content

Commit 9a4ed61

Browse files
chris-morganflaper87
authored andcommitted
Add augmented assignment (rust-lang#5992), sans wiring.
This is the first part of rust-lang#5992, covering the traits and their implementations and documentation of it all, but not including the wiring to make the actual operators (such as `+=`) desugar to the appropriate method call. This comes from my old augmented-assignment branch which had the wiring also but wasn't quite right. Things have changed enough that that wiring is utterly defunct and unworthy of any attempt at resurrection. The traits, however, were not, so I have restored that part of the work. All places in the present code base where any of the arithmetic traits (`Add`, `Sub`, `Mul`, `Div`, `Rem`, `BitAnd`, `BitOr`, `BitXor`, `Shl` and `Shr`) were implemented has an `*Assign` trait implementation added, with the exception (as before and as noted in the code) of `&str` and `&[T]` where the assignment operators cannot be implemented. Note that there is necessarily no default implementation of the `*Assign` traits, as that would preclude more efficient implementations of the augmented assignment operators and render the whole thing utterly pointless (c.f. rust-lang#7059 on function specialisation).
1 parent be3cbcb commit 9a4ed61

File tree

21 files changed

+424
-12
lines changed

21 files changed

+424
-12
lines changed

src/doc/rust.md

+20
Original file line numberDiff line numberDiff line change
@@ -1852,28 +1852,48 @@ A complete list of the built-in language items follows:
18521852
: Have finalizers.
18531853
`add`
18541854
: Elements can be added (for example, integers and floats).
1855+
`add_assign`
1856+
: Elements can be added with augmented assignment.
18551857
`sub`
18561858
: Elements can be subtracted.
1859+
`sub_assign`
1860+
: Elements can be subtracted with augmented assignment.
18571861
`mul`
18581862
: Elements can be multiplied.
1863+
`mul_assign`
1864+
: Elements can be multiplied with augmented assignment.
18591865
`div`
18601866
: Elements have a division operation.
1867+
`div_assign`
1868+
: Elements have a division operation with augmented assignment.
18611869
`rem`
18621870
: Elements have a remainder operation.
1871+
`rem_assign`
1872+
: Elements have a remainder operation with augmented assignment.
18631873
`neg`
18641874
: Elements can be negated arithmetically.
18651875
`not`
18661876
: Elements can be negated logically.
18671877
`bitxor`
18681878
: Elements have an exclusive-or operation.
1879+
`bitxor_assign`
1880+
: Elements have an exclusive-or operation with augmented assignment.
18691881
`bitand`
18701882
: Elements have a bitwise `and` operation.
1883+
`bitand_assign`
1884+
: Elements have a bitwise `and` operation with augmented assignment.
18711885
`bitor`
18721886
: Elements have a bitwise `or` operation.
1887+
`bitor_assign`
1888+
: Elements have a bitwise `or` operation with augmented assignment.
18731889
`shl`
18741890
: Elements have a left shift operation.
1891+
`shl_assign`
1892+
: Elements have a left shift operation with augmented assignment.
18751893
`shr`
18761894
: Elements have a right shift operation.
1895+
`shr_assign`
1896+
: Elements have a right shift operation with augmented assignment.
18771897
`index`
18781898
: Elements can be indexed.
18791899
`eq`

src/etc/kate/rust.xml

+11-1
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,26 @@
5656
<item> Ptr </item>
5757
<item> Drop </item>
5858
<item> Add </item>
59+
<item> AddAssign </item>
5960
<item> Sub </item>
61+
<item> SubAssign </item>
6062
<item> Mul </item>
61-
<item> Quot </item>
63+
<item> MulAssign </item>
64+
<item> Div </item>
65+
<item> DivAssign </item>
6266
<item> Rem </item>
67+
<item> RemAssign </item>
6368
<item> Neg </item>
6469
<item> BitAnd </item>
70+
<item> BitAndAssign </item>
6571
<item> BitOr </item>
72+
<item> BitOrAssign </item>
6673
<item> BitXor </item>
74+
<item> BitXorAssign </item>
6775
<item> Shl </item>
76+
<item> ShlAssign </item>
6877
<item> Shr </item>
78+
<item> ShrAssign </item>
6979
<item> Index </item>
7080
<item> Not </item>
7181
</list>

src/etc/vim/syntax/rust.vim

+3
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,12 @@ syn keyword rustType f64 i8 i16 i32 i64 str Self
4949
syn keyword rustTrait Sized
5050
syn keyword rustTrait Freeze Send
5151
syn keyword rustTrait Add Sub Mul Div Rem Neg Not
52+
syn keyword rustTrait AddAssign SubAssign MulAssign DivAssign RemAssign
5253
syn keyword rustTrait BitAnd BitOr BitXor
54+
syn keyword rustTrait BitAndAssign BitOrAssign BitXorAssign
5355
syn keyword rustTrait Drop
5456
syn keyword rustTrait Shl Shr Index
57+
syn keyword rustTrait ShlAssign ShrAssign
5558
syn keyword rustEnum Option
5659
syn keyword rustEnumVariant Some None
5760
syn keyword rustEnum Result

src/libextra/enum_set.rs

+18
Original file line numberDiff line numberDiff line change
@@ -88,18 +88,36 @@ impl<E:CLike> Sub<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
8888
}
8989
}
9090

91+
impl<E:CLike> SubAssign<EnumSet<E>> for EnumSet<E> {
92+
fn sub_assign(&mut self, e: &EnumSet<E>) {
93+
self.bits &= !e.bits;
94+
}
95+
}
96+
9197
impl<E:CLike> BitOr<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
9298
fn bitor(&self, e: &EnumSet<E>) -> EnumSet<E> {
9399
EnumSet {bits: self.bits | e.bits}
94100
}
95101
}
96102

103+
impl<E:CLike> BitOrAssign<EnumSet<E>> for EnumSet<E> {
104+
fn bitor_assign(&mut self, e: &EnumSet<E>) {
105+
self.bits |= e.bits;
106+
}
107+
}
108+
97109
impl<E:CLike> BitAnd<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
98110
fn bitand(&self, e: &EnumSet<E>) -> EnumSet<E> {
99111
EnumSet {bits: self.bits & e.bits}
100112
}
101113
}
102114

115+
impl<E:CLike> BitAndAssign<EnumSet<E>> for EnumSet<E> {
116+
fn bitand_assign(&mut self, e: &EnumSet<E>) {
117+
self.bits &= e.bits;
118+
}
119+
}
120+
103121
/// An iterator over an EnumSet
104122
pub struct Items<E> {
105123
priv index: uint,

src/libnum/bigint.rs

+34
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ impl BitAnd<BigUint, BigUint> for BigUint {
164164
}
165165
}
166166

167+
impl BitAndAssign<BigUint> for BigUint {}
168+
167169
impl BitOr<BigUint, BigUint> for BigUint {
168170
fn bitor(&self, other: &BigUint) -> BigUint {
169171
let new_len = num::max(self.data.len(), other.data.len());
@@ -176,6 +178,8 @@ impl BitOr<BigUint, BigUint> for BigUint {
176178
}
177179
}
178180

181+
impl BitOrAssign<BigUint> for BigUint {}
182+
179183
impl BitXor<BigUint, BigUint> for BigUint {
180184
fn bitxor(&self, other: &BigUint) -> BigUint {
181185
let new_len = num::max(self.data.len(), other.data.len());
@@ -188,6 +192,8 @@ impl BitXor<BigUint, BigUint> for BigUint {
188192
}
189193
}
190194

195+
impl BitXorAssign<BigUint> for BigUint {}
196+
191197
impl Shl<uint, BigUint> for BigUint {
192198
#[inline]
193199
fn shl(&self, rhs: &uint) -> BigUint {
@@ -197,6 +203,8 @@ impl Shl<uint, BigUint> for BigUint {
197203
}
198204
}
199205

206+
impl ShlAssign<uint> for BigUint {}
207+
200208
impl Shr<uint, BigUint> for BigUint {
201209
#[inline]
202210
fn shr(&self, rhs: &uint) -> BigUint {
@@ -206,6 +214,8 @@ impl Shr<uint, BigUint> for BigUint {
206214
}
207215
}
208216

217+
impl ShrAssign<uint> for BigUint {}
218+
209219
impl Zero for BigUint {
210220
#[inline]
211221
fn zero() -> BigUint { BigUint::new(~[]) }
@@ -240,6 +250,8 @@ impl Add<BigUint, BigUint> for BigUint {
240250
}
241251
}
242252

253+
impl AddAssign<BigUint> for BigUint {}
254+
243255
impl Sub<BigUint, BigUint> for BigUint {
244256
fn sub(&self, other: &BigUint) -> BigUint {
245257
let new_len = num::max(self.data.len(), other.data.len());
@@ -265,6 +277,8 @@ impl Sub<BigUint, BigUint> for BigUint {
265277
}
266278
}
267279

280+
impl SubAssign<BigUint> for BigUint {}
281+
268282
impl Mul<BigUint, BigUint> for BigUint {
269283
fn mul(&self, other: &BigUint) -> BigUint {
270284
if self.is_zero() || other.is_zero() { return Zero::zero(); }
@@ -331,6 +345,8 @@ impl Mul<BigUint, BigUint> for BigUint {
331345
}
332346
}
333347

348+
impl MulAssign<BigUint> for BigUint {}
349+
334350
impl Div<BigUint, BigUint> for BigUint {
335351
#[inline]
336352
fn div(&self, other: &BigUint) -> BigUint {
@@ -339,6 +355,8 @@ impl Div<BigUint, BigUint> for BigUint {
339355
}
340356
}
341357

358+
impl DivAssign<BigUint> for BigUint {}
359+
342360
impl Rem<BigUint, BigUint> for BigUint {
343361
#[inline]
344362
fn rem(&self, other: &BigUint) -> BigUint {
@@ -347,6 +365,8 @@ impl Rem<BigUint, BigUint> for BigUint {
347365
}
348366
}
349367

368+
impl RemAssign<BigUint> for BigUint {}
369+
350370
impl Neg<BigUint> for BigUint {
351371
#[inline]
352372
fn neg(&self) -> BigUint { fail!() }
@@ -965,13 +985,17 @@ impl Shl<uint, BigInt> for BigInt {
965985
}
966986
}
967987

988+
impl ShlAssign<uint> for BigInt {}
989+
968990
impl Shr<uint, BigInt> for BigInt {
969991
#[inline]
970992
fn shr(&self, rhs: &uint) -> BigInt {
971993
BigInt::from_biguint(self.sign, self.data >> *rhs)
972994
}
973995
}
974996

997+
impl ShrAssign<uint> for BigInt {}
998+
975999
impl Zero for BigInt {
9761000
#[inline]
9771001
fn zero() -> BigInt {
@@ -1034,6 +1058,8 @@ impl Add<BigInt, BigInt> for BigInt {
10341058
}
10351059
}
10361060

1061+
impl AddAssign<BigInt> for BigInt {}
1062+
10371063
impl Sub<BigInt, BigInt> for BigInt {
10381064
#[inline]
10391065
fn sub(&self, other: &BigInt) -> BigInt {
@@ -1052,6 +1078,8 @@ impl Sub<BigInt, BigInt> for BigInt {
10521078
}
10531079
}
10541080

1081+
impl SubAssign<BigInt> for BigInt {}
1082+
10551083
impl Mul<BigInt, BigInt> for BigInt {
10561084
#[inline]
10571085
fn mul(&self, other: &BigInt) -> BigInt {
@@ -1067,6 +1095,8 @@ impl Mul<BigInt, BigInt> for BigInt {
10671095
}
10681096
}
10691097

1098+
impl MulAssign<BigInt> for BigInt {}
1099+
10701100
impl Div<BigInt, BigInt> for BigInt {
10711101
#[inline]
10721102
fn div(&self, other: &BigInt) -> BigInt {
@@ -1075,6 +1105,8 @@ impl Div<BigInt, BigInt> for BigInt {
10751105
}
10761106
}
10771107

1108+
impl DivAssign<BigInt> for BigInt {}
1109+
10781110
impl Rem<BigInt, BigInt> for BigInt {
10791111
#[inline]
10801112
fn rem(&self, other: &BigInt) -> BigInt {
@@ -1083,6 +1115,8 @@ impl Rem<BigInt, BigInt> for BigInt {
10831115
}
10841116
}
10851117

1118+
impl RemAssign<BigInt> for BigInt {}
1119+
10861120
impl Neg<BigInt> for BigInt {
10871121
#[inline]
10881122
fn neg(&self) -> BigInt {

src/libnum/complex.rs

+6
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,17 @@ impl<T: Clone + Num> Add<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
112112
Cmplx::new(self.re + other.re, self.im + other.im)
113113
}
114114
}
115+
impl<T: Clone + Num> AddAssign<Cmplx<T>> for Cmplx<T> {}
116+
115117
// (a + i b) - (c + i d) == (a - c) + i (b - d)
116118
impl<T: Clone + Num> Sub<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
117119
#[inline]
118120
fn sub(&self, other: &Cmplx<T>) -> Cmplx<T> {
119121
Cmplx::new(self.re - other.re, self.im - other.im)
120122
}
121123
}
124+
impl<T: Clone + Num> SubAssign<Cmplx<T>> for Cmplx<T> {}
125+
122126
// (a + i b) * (c + i d) == (a*c - b*d) + i (a*d + b*c)
123127
impl<T: Clone + Num> Mul<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
124128
#[inline]
@@ -127,6 +131,7 @@ impl<T: Clone + Num> Mul<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
127131
self.re*other.im + self.im*other.re)
128132
}
129133
}
134+
impl<T: Clone + Num> MulAssign<Cmplx<T>> for Cmplx<T> {}
130135

131136
// (a + i b) / (c + i d) == [(a + i b) * (c - i d)] / (c*c + d*d)
132137
// == [(a*c + b*d) / (c*c + d*d)] + i [(b*c - a*d) / (c*c + d*d)]
@@ -138,6 +143,7 @@ impl<T: Clone + Num> Div<Cmplx<T>, Cmplx<T>> for Cmplx<T> {
138143
(self.im*other.re - self.re*other.im) / norm_sqr)
139144
}
140145
}
146+
impl<T: Clone + Num> DivAssign<Cmplx<T>> for Cmplx<T> {}
141147

142148
impl<T: Clone + Num> Neg<Cmplx<T>> for Cmplx<T> {
143149
#[inline]

src/libnum/rational.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,8 @@ impl<T: Clone + Integer + Ord>
189189
}
190190
}
191191

192+
impl<T: Clone + Integer + Ord> MulAssign<Ratio<T>> for Ratio<T> {}
193+
192194
// (a/b) / (c/d) = (a*d)/(b*c)
193195
impl<T: Clone + Integer + Ord>
194196
Div<Ratio<T>,Ratio<T>> for Ratio<T> {
@@ -198,9 +200,11 @@ impl<T: Clone + Integer + Ord>
198200
}
199201
}
200202

203+
impl<T: Clone + Integer + Ord> DivAssign<Ratio<T>> for Ratio<T> {}
204+
201205
// Abstracts the a/b `op` c/d = (a*d `op` b*d) / (b*d) pattern
202206
macro_rules! arith_impl {
203-
(impl $imp:ident, $method:ident) => {
207+
(impl $imp:ident/$imp_assign:ident, $method:ident) => {
204208
impl<T: Clone + Integer + Ord>
205209
$imp<Ratio<T>,Ratio<T>> for Ratio<T> {
206210
#[inline]
@@ -209,17 +213,19 @@ macro_rules! arith_impl {
209213
self.denom * rhs.denom)
210214
}
211215
}
216+
impl<T: Clone + Integer + Ord>
217+
$imp_assign<Ratio<T>> for Ratio<T> {}
212218
}
213219
}
214220

215221
// a/b + c/d = (a*d + b*c)/(b*d
216-
arith_impl!(impl Add, add)
222+
arith_impl!(impl Add/AddAssign, add)
217223

218224
// a/b - c/d = (a*d - b*c)/(b*d)
219-
arith_impl!(impl Sub, sub)
225+
arith_impl!(impl Sub/SubAssign, sub)
220226

221227
// a/b % c/d = (a*d % b*c)/(b*d)
222-
arith_impl!(impl Rem, rem)
228+
arith_impl!(impl Rem/RemAssign, rem)
223229

224230
impl<T: Clone + Integer + Ord>
225231
Neg<Ratio<T>> for Ratio<T> {

src/librustc/middle/borrowck/mod.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use util::ppaux::{note_and_explain_region, Repr, UserString};
2121

2222
use std::cell::{Cell, RefCell};
2323
use std::hashmap::HashMap;
24-
use std::ops::{BitOr, BitAnd};
24+
use std::ops::{BitOr, BitOrAssign, BitAnd, BitAndAssign};
2525
use std::result::{Result};
2626
use syntax::ast;
2727
use syntax::ast_map;
@@ -352,12 +352,24 @@ impl BitOr<RestrictionSet,RestrictionSet> for RestrictionSet {
352352
}
353353
}
354354

355+
impl BitOrAssign<RestrictionSet> for RestrictionSet {
356+
fn bitor_assign(&mut self, rhs: &RestrictionSet) {
357+
self.bits |= rhs.bits;
358+
}
359+
}
360+
355361
impl BitAnd<RestrictionSet,RestrictionSet> for RestrictionSet {
356362
fn bitand(&self, rhs: &RestrictionSet) -> RestrictionSet {
357363
RestrictionSet {bits: self.bits & rhs.bits}
358364
}
359365
}
360366

367+
impl BitAndAssign<RestrictionSet> for RestrictionSet {
368+
fn bitand_assign(&mut self, rhs: &RestrictionSet) {
369+
self.bits &= rhs.bits;
370+
}
371+
}
372+
361373
///////////////////////////////////////////////////////////////////////////
362374
// Rooting of managed boxes
363375
//

0 commit comments

Comments
 (0)