Discussion:
[rust-dev] trait implementations for references
Eugene Zemtsov
2014-09-22 08:32:25 UTC
Permalink
Hi All,

I have just recently discovered that it is possible to provide a trait
implementation for a reference type.
This feature by itself seems to me very controversial. But it also leads
to surprising dispatches when combined with argument matching for
references.
Consider following program:

trait A {
fn f(self);
fn g(&self);
}

impl A for int {
fn f(self) {
println!("f() for int");
}
fn g(&self) {
println!("g() for int");
}
}

impl<'a> A for &'a int {
fn f(self) {
println!("f() for reference");
}
fn g(&self) {
println!("g() for reference");
}
}

fn main() {
let one = 1i;
let one_ref = &one;
one_ref.f();
one_ref.g();
}


The output of this program is

f() for reference

g() for int


When I am analyzing this output, I can kinda understand how compiler finds
"the most suitable" implementation.
But this is still an example of a very tricky behavior we have so much of
in C++.

Is this a product of a conscious design decision or just a intermediate
state of the language which is under construction?
If it is by design, is there a place (RFC, github issue, mailing thread)
where I can read a discussion about pros and cons of allowing separate
trait implementations for references?

P.S.
If it matters my rust version is 0.12.0-pre-nightly (79a5448f4 2014-09-13
20:36:02 +0000)

Thanks,
Eugene Zemtsov.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140922/721dadc1/attachment.html>
François-Xavier Bourlet
2014-09-22 20:23:50 UTC
Permalink
Hi,

My little understanding is that the compiler has some sort of priority on
type inference depending of the kind of modification applied to the type in
order to match anything.

Rust can auto-deref on the "." operator and auto-borrow when passing to
reference parameters, and I suspect that an auto-deref is of higher
priority than an auto-borrow. But I might be very wrong!
Post by Eugene Zemtsov
Hi All,
I have just recently discovered that it is possible to provide a trait
implementation for a reference type.
This feature by itself seems to me very controversial. But it also leads
to surprising dispatches when combined with argument matching for
references.
trait A {
fn f(self);
fn g(&self);
}
impl A for int {
fn f(self) {
println!("f() for int");
}
fn g(&self) {
println!("g() for int");
}
}
impl<'a> A for &'a int {
fn f(self) {
println!("f() for reference");
}
fn g(&self) {
println!("g() for reference");
}
}
fn main() {
let one = 1i;
let one_ref = &one;
one_ref.f();
one_ref.g();
}
The output of this program is
f() for reference
g() for int
When I am analyzing this output, I can kinda understand how compiler finds
"the most suitable" implementation.
But this is still an example of a very tricky behavior we have so much of
in C++.
Is this a product of a conscious design decision or just a intermediate
state of the language which is under construction?
If it is by design, is there a place (RFC, github issue, mailing thread)
where I can read a discussion about pros and cons of allowing separate
trait implementations for references?
P.S.
If it matters my rust version is 0.12.0-pre-nightly (79a5448f4 2014-09-13
20:36:02 +0000)
Thanks,
Eugene Zemtsov.
_______________________________________________
Rust-dev mailing list
Rust-dev at mozilla.org
https://mail.mozilla.org/listinfo/rust-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140922/cbdf6f51/attachment.html>
Loading...