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
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to