-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
overloaded assignment operations a += b
#953
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
- Feature Name: op_assign | ||
- Start Date: 2015-03-08 | ||
- RFC PR: (leave this empty) | ||
- Rust Issue: (leave this empty) | ||
|
||
# Summary | ||
|
||
Add the family of `[Op]Assign` traits to allow overloading assignment | ||
operations like `a += b`. | ||
|
||
# Motivation | ||
|
||
We already let users overload the binary operations, letting them overload the | ||
assignment version is the next logical step. Plus, this sugar is important to | ||
make mathematical libraries more palatable. | ||
|
||
# Detailed design | ||
|
||
Add the following **unstable** traits to libcore and reexported them in stdlib: | ||
|
||
``` | ||
// `+=` | ||
#[lang = "add_assign"] | ||
trait AddAssign<Rhs=Self> { | ||
fn add_assign(&mut self, &Rhs); | ||
} | ||
|
||
// the remaining traits have the same signature | ||
// (lang items have been omitted for brevity) | ||
trait BitAndAssign { .. } // `&=` | ||
trait BitOrAssign { .. } // `|=` | ||
trait BitXorAssign { .. } // `^=` | ||
trait DivAssign { .. } // `/=` | ||
trait MulAssign { .. } // `*=` | ||
trait RemAssign { .. } // `%=` | ||
trait ShlAssign { .. } // `<<=` | ||
trait ShrAssign { .. } // `>>=` | ||
trait SubAssign { .. } // `-=` | ||
``` | ||
|
||
Implement these traits for the primitive numeric types *without* overloading, | ||
i.e. only `impl AddAssign<i32> for i32 { .. }`. | ||
|
||
Add an `op_assign` feature gate. When the feature gate is enabled, the compiler | ||
will consider these traits when typecheking `a += b`. Without the feature gate | ||
the compiler will enforce that `a` and `b` must be primitives of the same | ||
type/category as it does today. | ||
|
||
Once we feel comfortable with the implementation we'll remove the feature gate | ||
and mark the traits as stable. This can be done after 1.0 as this change is | ||
backwards compatible. | ||
|
||
# Drawbacks | ||
|
||
None that I can think of. | ||
|
||
# Alternatives | ||
|
||
Alternatively, we could change the traits to take the RHS by value. This makes | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would like to see discussion of why the proposed design differs from the plain There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added a section on by-ref vs by-value. |
||
them more "flexible" as the user can pick by value or by reference, but makes | ||
the use slightly unergonomic in the by ref case as the borrow must be explicit | ||
e.g. `x += &big_float;` vs `x += big_float;`. | ||
|
||
# Unresolved questions | ||
|
||
Are there any use cases of assignment operations where the RHS has to be taken | ||
by value for the operation to be performant (e.g. to avoid internal cloning)? | ||
|
||
Should we overload `ShlAssign` and `ShrAssign`, e.g. | ||
`impl ShlAssign<u8> for i32`, since we have already overloaded the `Shl` and | ||
`Shr` traits? | ||
|
||
Should we overload all the traits for references, e.g. | ||
`impl<'a> AddAssign<&'a i32> for i32` to allow `x += &0;`? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: "typecheking"