Hmmm.... That sounds strange. Shouldn't `obj: &T` allow me to invoke `obj.method_of_T()`?
For example, how did I manage to invoke the `data.print(...)` method via the borrowed `data: &PrintWithSpice` pointer? Automatic dereference? And if so, why didn't it work for `Writer` as well? On Sat, Oct 19, 2013 at 9:29 AM, Steven Fackler <sfack...@gmail.com> wrote: > 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