I think you're running into issue #8075<https://github.com/mozilla/rust/issues/8075>which has to do with generic impls conflicting with all the other impls present. The typechecker tries to ensure that impls are coherent, i.e. that impls do not overlap (otherwise the compiler wouldn't know which one to use). Unfortunately, the coherence check isn't very smart right now and if there's a generic impl around then it assumes it could conflict with everything (and consequently forbids any other impls).
The specific problem here is that the coherence checker doesn't realize that SomeData does not impl Float. Without knowing that, the checker sees two possible impls for SomeData and rejects the code. If you replace "impl<T: Float> SomeDataRhs for T" with "impl SomeDataRhs for f64", then it'll work fine. You can add an impl for f32 as well (FYI "float" is already removed in HEAD). Unfortunately, I don't know of a good general solution that will support all types implementing Float (i.e. what the generic impl is doing). On Tue, Dec 3, 2013 at 1:09 AM, Rémi Fontan <[email protected]> wrote: > Hi, > > I think I already asked this question in the past and I'm not very sure > what was the answer and whether it is still applicable wirh rust 0.8. > > I'm implementing the double dispatch method overloading such that I can > add 2 struct together and a float to a struct. > > let data = SomeData{a:1.0} + 2.0; > let data2 = SomeData{a:100.0} + data; > > I would like to implement the add for every type of float. I asked whether > I could write something like this: > > impl<T:Float> SomeDataRhs for T { > fn add_to(&self, lhs:&SomeData) -> SomeData { > SomeData{a:lhs.a + cast(*self)} > } > } > > it does not compile right now with rust 0.8 > I get error messages as follow > > test2.rs:39:0: 43:1 error: conflicting implementations for trait > `SomeDataRhs` > > test2.rs:39 impl SomeDataRhs for SomeData { > > test2.rs:40 fn add_to(&self, lhs:&SomeData) -> SomeData { > > test2.rs:41 SomeData{a:lhs.a + self.a} > > test2.rs:42 } > > test2.rs:43 } > > test2.rs:33:0: 37:1 note: note conflicting implementation here > > test2.rs:33 impl<T:Float> SomeDataRhs for T { > > test2.rs:34 fn add_to(&self, lhs:&SomeData) -> SomeData { > > test2.rs:35 SomeData{a:lhs.a + cast(*self)} > > test2.rs:36 } > > Would you know whether what I try to do is possible. I was recommended to > use macro for that, I don't mind to eventually go this way but I would > rather do it the proper way if there is one. > > here's the full code of my test: > extern mod std; > use std::num::cast; > > > struct SomeData { a:float } > > trait SomeDataRhs { > fn add_to(&self, lhs:&SomeData) -> SomeData; > } > > impl<T:SomeDataRhs> Add<T, SomeData> for SomeData { > > fn add(&self, rhs:&T) -> SomeData { > rhs.add_to(self) > } > } > > // --------------- > // implementations > > // impl SomeDataRhs for float { > // fn add_to(&self, lhs:&SomeData) -> SomeData { > // SomeData{a:lhs.a + *self} > // } > // } > > // impl SomeDataRhs for f64 { > // fn add_to(&self, lhs:&SomeData) -> SomeData { > // SomeData{a:lhs.a + cast(*self)} > // } > // } > > impl<T:Float> SomeDataRhs for T { > fn add_to(&self, lhs:&SomeData) -> SomeData { > SomeData{a:lhs.a + cast(*self)} > } > } > > impl SomeDataRhs for SomeData { > fn add_to(&self, lhs:&SomeData) -> SomeData { > SomeData{a:lhs.a + self.a} > } > } > > > #[test] > fn test_sandbox() { > > let mut data = SomeData{a:1.0} + 2.0; > println!("result: {}", data.a); > > let mut data2 = SomeData{a:100.0} + data; > data = data + data2; > println!("result: {}", data.a); > > } > > > > cheers, > > Rémi > > > -- > Rémi Fontan : [email protected] > mobile: +64 21 855 351 > 93 Otaki Street, Miramar 6022 > Wellington, New Zealand > > _______________________________________________ > Rust-dev mailing list > [email protected] > https://mail.mozilla.org/listinfo/rust-dev > >
_______________________________________________ Rust-dev mailing list [email protected] https://mail.mozilla.org/listinfo/rust-dev
