On 14/11/13 16:00, Tommi wrote:
On 2013-11-14, at 6:20, Tommi <[email protected]> wrote:
On 2013-11-14, at 5:54, Huon Wilson <[email protected]> wrote:
On 14/11/13 14:50, Tommi wrote:
let mut n = 11;
let p: &int = &123;
p + n; // OK
n + p; // error: mismatched types: expected `int` but found `&int`
Shouldn't this error be considered a compiler-bug? The Add trait says '&' for
rhs after all:
fn add(&self, rhs: &RHS) -> Result;
-Tommi
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev
This is https://github.com/mozilla/rust/issues/8895 . I believe it is caused by the
implementation details of the overloaded-operator desugaring (a + b is equivalent to
`a.add(&b)`, so auto-deref allows for `a: &T` with `b: T`), I personally think
the more sensible resolution would be for `p + n` to be disallowed as well as `n + p`.
Huon
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev
Thanks, I tried to search for a bug report for this but didn't manage to find that one. To me
it makes perfect sense that p + n would work because if a + b is specified to be
"just" syntactic sugar for a.add(b), then a + b should behave exactly like
a.add(b), with implicit pointer dereferencing and all that good stuff. But, I don't
understand why is it a.add(&b) like you said, though.
By the way, I would hate all of this behavior if Rust had pointer arithmetic,
but luckily it doesn't seem to have it.
-Tommi
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev
You're right in that it's not a bug in built-in types, but affects user-defined
types also. But n.add(p) works just fine, while n.add(&p) doesn't:
struct Num { n: int }
impl Add<Num, Num> for Num {
fn add(&self, other: &Num) -> Num { Num { n: self.n + other.n } }
}
fn main() {
let n = 11i;
let p = &22i;
p + n; // OK
n + p; // error: mismatched types: expected `int` but found `&int`
n.add(p); // OK
n.add(&p); // error: mismatched types: expected `&int` but found `&&int`
let n = Num { n: 11 };
let p = &Num { n: 22 };
p + n; // OK
n + p; // error: mismatched types: expected `Num` but found `&Num`
n.add(p); // OK
n.add(&p); // error: mismatched types: expected `&Num` but found `&&Num`
}
-Tommi
p has type &Num, which matches the type signature of add for Num, so it
is expected that it compiles. And, &p has type & &Num, which doesn't
match the signature of add for Num and so correspondingly doesn't
compile. Similarly, for the + sugar, `n + p` and `n.add(&p)` (with the
extra &) are the same (despite the error messages having one fewer
layers of &).
The operator traits all take references because they (in the common
case) don't want ownership of their arguments. If they didn't take
references (i.e. `fn add(self, other: Num) -> Num`) then something like
bigint_1.add(&bigint_2) // bigint_1 + bigint_2
would likely require
bigint_1.clone().add(bigint_2.clone()) // bigint_1.clone() +
bigint_2.clone()
if one wanted to reuse the values in bigint_1 and bigint_2 later.
The current definitions of the traits means that the operator desugaring
needs to implicitly add the references (that is a + b -> a.add(&b),
rather than a.add(b)`) to match the type signature, or else we'd be
forced to write `x + &1` everywhere.
(Just to be clear the auto-deref only happens on the "self" value, i.e.
the value on which you are calling the method, not any arguments.)
Huon
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev