-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Proposal: Implement assignment operator overloads #5992
Comments
Maybe related: #4329 |
nominating for backwards compat |
(I'm pretty sure I don't want to permit overloading |
@graydon sure. |
accepted for backward compatibility |
I'm working on this at present, though I'm not tackling Index yet. |
The work that I have done thus far on this is on my If someone who actually knows what they are doing could look at it and figure out what I've still got wrong, I would be very grateful. My code should certainly not be accepted without careful review; this is my first work on the compiler itself. (@nikomatsakis, I believe you have owned a lot of this code?) Note that at present Sample code: #[deriving(Eq)]
struct Vector1 {
x: int,
}
impl Add<Vector1, Vector1> for Vector1 {
fn add(&self, rhs: &Vector1) -> Vector1 {
Vector1 {
x: self.x + rhs.x,
}
}
}
impl AddAssign<Vector1> for Vector1 {
fn add_assign(&mut self, rhs: &Vector1) {
self.x = self.x + rhs.x;
}
}
fn main() {
let v1 = Vector1 { x: 1 };
let v2 = Vector1 { x: 4 };
let _v3 = v1.add(&v2);
let v3 = v1 + v2;
if v3.x != 5 {
println("+ :-(");
}
let mut v1 = Vector1 { x: 1 };
let v2 = Vector1 { x: 4 };
v1.add_assign(&v2);
v1 += v2;
if v1.x != 9 {
println("+= :-(");
}
} Compiling this leads to an abort with
Selected parts of the output with GDB:
To get decent log information, rustc needs to be built with the configure flag Going through the log there, the
while the
Observe the extra |
I don't think this is a backwards compatibility issue anymore since @pcwalton removed the old system of rewriting |
accepted for feature-complete |
…ichton So far the following code ``` struct Foo; fn main() { let mut t = Foo; let ref b = Foo; a += *b; } ``` errors with ``` test.rs:15:3: 13:11 error: binary operation + cannot be applied to type `Foo` test.rs:15 *a += *b; ``` Since assignment-operators are no longer expanded to ```left = left OP right``` but are independents operators it should be ``` test.rs:15:3: 13:11 error: binary operation += cannot be applied to type `Foo` test.rs:15 *a += *b; ``` to make it clear that implementing Add for Foo is not gonna work. (cf issues #11143, #11344) Besides that, we also need to typecheck the rhs expression even if the operator has no implementation, or we end up with unknown types for the nodes of the rhs and an ICE later on while resolving types. (once again cf #11143 and #11344). This probably would get fixed with #5992, but in the meantime it's a confusing error to stumble upon. @pcwalton, you wrote the original code, what do you think? (closes #11143 and #11344)
I've salvaged the traits and implementations part of my |
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).
Assigning P-low, since it would be something we can add backwards compatibly post 1.0. |
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).
I have updated my There is one new situation which I have not taken care of: |
This issue should be moved to the rust-lang/rfcs repo, because it requires adding lang items, which (I think) needs an RFC. cc @nick29581 |
This issue has been moved to the RFCs repo: rust-lang/rfcs#393 |
…apsible_if, r=yaahc Fix the wrong suggestion when using macro in `collapsible_if` Fix rust-lang#5962 changelog: Fix the wrong suggestion when using macro in `collapsible_if`
This would be very useful for
core::num
(see #4819), and also mathematics libraries.It would also be useful to be able to assign to values accessed via the index operator. This would return a mutable reference to the element. =, +=, -=, *=, /=, and %= would then be based off the overloads defined for that element type.
Edit: Removed
Assign
trait for=
operator.The text was updated successfully, but these errors were encountered: