Re: [rust-dev] Strange behavior about Writer trait
I'm not sure I follow. Assuming that the trait `T` has no method that uses `Self`, then any `impl` requiring `T` should happily accept an `T` / `@T`. Why penalize non-self-referential traits (like `Writer`), just because some traits (like `AdderIncr`) are self-referential? On Sun, Oct 20, 2013 at 1:10 AM, Steven Blenkinsop steven...@gmail.comwrote: Consider this program: trait AdderIncr { fn add(self, x: Self) - Self; fn incr(mut self); } impl AdderIncr for int { fn add(self, x: int) - int { *self + x } fn incr(mut self) { *self += 1; } } fn incrAdd(x: mut AdderIncr, y: mut AdderIncr) { x.incr(); x.add(y); } fn main() {} It fails to compile: Documents/test.rs:13:1: 13:10 error: cannot call a method whose type contains a self-type through an object Documents/test.rs:13x.add(y); ^ The Self type is meaningless in object methods, since I have no way to ensure that y has the same underlying type as x. Thus, only a subset of the methods of a trait are available on the corresponding object, which means that objects can't automatically implement their corresponding trait. That means any impls that implement a trait for all types that implement AdderIncr, for example, won't implement that trait for AdderIncr, since AdderIncr doesn't implement AdderIncr. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
[rust-dev] Strange behavior about Writer trait
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::Writerno-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 Foono-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 `implT: 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
Re: [rust-dev] Strange behavior about Writer trait
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::Writerno-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 Foono-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 `implT: 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
Re: [rust-dev] Strange behavior about Writer trait
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::Writerno-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 Foono-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 `implT: 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
Re: [rust-dev] Strange behavior about Writer trait
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::Writerno-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 Foono-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 `implT: 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
Re: [rust-dev] Strange behavior about Writer trait
Consider this program: trait AdderIncr { fn add(self, x: Self) - Self; fn incr(mut self); } impl AdderIncr for int { fn add(self, x: int) - int { *self + x } fn incr(mut self) { *self += 1; } } fn incrAdd(x: mut AdderIncr, y: mut AdderIncr) { x.incr(); x.add(y); } fn main() {} It fails to compile: Documents/test.rs:13:1: 13:10 error: cannot call a method whose type contains a self-type through an object Documents/test.rs:13x.add(y); ^ The Self type is meaningless in object methods, since I have no way to ensure that y has the same underlying type as x. Thus, only a subset of the methods of a trait are available on the corresponding object, which means that objects can't automatically implement their corresponding trait. That means any impls that implement a trait for all types that implement AdderIncr, for example, won't implement that trait for AdderIncr, since AdderIncr doesn't implement AdderIncr. On Sat, Oct 19, 2013 at 2:47 AM, Oren Ben-Kiki o...@ben-kiki.org wrote: 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.comwrote: 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.orgwrote: 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.orgwrote: 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::Writerno-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 Foono-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 `implT: 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 ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev