If T is a trait, its trait objects ~T, @T and &T do not implement T. There is an implementation of Writer for @Writer, but not for ~Writer or &Writer which is why you're seeing that error.
Steven Fackler On Fri, Oct 18, 2013 at 11:27 PM, Oren Ben-Kiki <o...@ben-kiki.org> wrote: > Ugh, I was too optimistic. Yes, I can write my code using `MyWriter`, but > I can't cast any @Writer (such as `io::stdout()`) to it. I guess I should > just use `@Writer` everywhere for now :-( > > This raises the question of how come the compiler is smart enough to > figure out a `@Writer` has the trait `WriterUtil`, but isn't smart enough > to figure out a `&Writer` has the trait... > > > On Sat, Oct 19, 2013 at 9:08 AM, Oren Ben-Kiki <o...@ben-kiki.org> wrote: > >> I run into the following problem (the code below is a toy example). >> >> ``` >> use std::io::Writer; // Makes no difference if added/removed. >> >> trait PrintWithSpice { >> fn print(&self, writer: &Writer, spice: bool); >> } >> >> struct Bar { >> bar: ~PrintWithSpice, >> } >> >> impl Bar { >> pub fn print(&self, writer: &Writer) { >> self.bar.print(writer, false); >> Bar::print_via_borrowed(writer, &self.bar); >> } >> >> fn print_via_borrowed(writer: &Writer, data: &PrintWithSpice) { >> // Invoking the `print` function via the borrowed pointer to the >> `PrintWithSpice` trait: >> // Works fine, as expected.. >> data.print(writer, true); >> } >> } >> >> struct Foo { >> foo: bool >> } >> >> impl PrintWithSpice for Foo { >> fn print(&self, writer: &Writer, spice: bool) { >> // Invoking the `write_str` function via the borrowed pointer to >> the `Writer` trait: >> // error: failed to find an implementation of trait >> std::io::Writer for &std::io::Writer<no-bounds> >> // What is going on? >> writer.write_str(format!("foo: {:b} spice: {:b}", self.foo, >> spice)); >> } >> } >> ``` >> >> I didn't understand what the compiler is complaining about. "failed to >> find an implementation of Foo for &Foo<no-bounds>"? A Foo is a Foo, no? >> Calling a function via a borrowed pointer to a trait should just work (it >> does a few lines above). >> >> After digging I discovered what the compiler really meant (I think). The >> `write_str` method is defined for `WriterUtils` rather than for `Writer`. >> So, if I replace `Writer` by `WriterUtil` in the above code, it compiles >> fine. >> >> So, I ended up defining `trait MyWriter: Writer + WriterUtil` and I am >> using that instead of `Writer` all over my code. I can see doing that as a >> workaround, but it doesn't smell right to me. >> >> So: >> >> * Why is the compiler complaining about not finding an implementation for >> `Writer` when the method I invoke is from `WriterUtil`? >> >> * Since there is an `impl<T: Writer> for WriterUtil`, shouldn't the >> compiler be "sufficiently smart" to deduce that the code is valid in the >> 1st place? >> >> * Until the compiler is "sufficiently smart" (or, if there is a good >> reason why it would never be), shouldn't we rename `Writer` to >> `BasicWriter` and define `trait Writer: BasicWriter, WriterUtil {}` so >> `&Writer` would become more usable? >> > > > _______________________________________________ > Rust-dev mailing list > Rust-dev@mozilla.org > https://mail.mozilla.org/listinfo/rust-dev > >
_______________________________________________ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev