[rust-dev] Traits & "mod"

2013-06-01 Thread Tom Lee
Hey folks,

A work colleague is trying to pick up some Rust & we were both
surprised by the following:

// some_mod.rs

pub trait SomeTrait {
pub fn foo(&self) -> ~str;
}

pub struct SomeStruct {
name: ~str
}

impl SomeTrait for SomeStruct {
pub fn foo(&self) -> ~str {
self.name.clone()
}
}

impl SomeStruct {
pub fn new(name: &str) -> SomeStruct {
SomeStruct { name: name.to_owned() }
}
}

// some_use.rs

mod some_mod;

fn main() {

  let inst = some_mod::SomeStruct::new("test");

  println(inst.foo());

}


This fails with a compile error because the compiler can't "see"
some_mod::SomeTrait in the scope of some_use.rs:

some_use.rs:5:4: 6:1 error: type `some_mod::SomeStruct` does not
implement any method in scope named `foo`
some_use.rs:5 inst.foo()
some_use.rs:6 }

This is fixed by adding "use some_mod::SomeTrait" at the start of
some_use.rs. It's as though traits need to be in the same scope as
code that expects to make use of their behaviour (where I'd expect the
behaviour would be associated with the implementation for the "self"
type).

My question is: is this intended behaviour? If not, what's the
expected behaviour & is there an outstanding issue for this?

Appreciate any clarification!

Cheers,
Tom

--
Tom Lee / http://tomlee.co / @tglee
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Traits & "mod"

2013-06-02 Thread Sanghyeon Seo
> This is fixed by adding "use some_mod::SomeTrait" at the start of
> some_use.rs. It's as though traits need to be in the same scope as
> code that expects to make use of their behaviour (where I'd expect the
> behaviour would be associated with the implementation for the "self"
> type).
>
> My question is: is this intended behaviour? If not, what's the
> expected behaviour & is there an outstanding issue for this?

Yes, I believe this is fully intended behaviour.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Traits & "mod"

2013-06-03 Thread Graydon Hoare

On 01/06/2013 2:21 PM, Tom Lee wrote:


This is fixed by adding "use some_mod::SomeTrait" at the start of
some_use.rs. It's as though traits need to be in the same scope as
code that expects to make use of their behaviour (where I'd expect the
behaviour would be associated with the implementation for the "self"
type).


No, the methods in this case are scoped to the trait. See all the traits 
we 'pub use' in std::prelude so that they are available as methods 
ubiquitously.



My question is: is this intended behaviour? If not, what's the
expected behaviour & is there an outstanding issue for this?


This is intended behavior. Note that there _is_ a single 
inherent-to-the-type impl (set of methods) which you can use to 
associated methods with a type:


   struct Foo { ... }
   impl Foo {
   .. inherent methods
   }

Such that anyone who can see Foo can see these methods. But that impl 
has to be defined in the same crate[1] as the struct itself, such that 
we can check that there's only one of them. For implementations of a 
named trait, you must have the trait in-scope in order to see the 
methods[2].


If you think about this in terms of colliding names and separate 
compilation, it makes more sense. We want to make it possible to always 
link together two crates A and B both compiled independently. Suppose A 
and B both defined different traits P and Q on some type Foo with some 
methods P::bar() and Q::bar(). Then someone calling (Foo::new()).bar() 
would be producing a link-time error due to the ambiguity between 
P::bar() and Q::bar().


We want such things to be caught during compilation of the client code 
-- where it can be resolved by making a module that does not 
simultaneously 'use' P and Q -- rather than at link time.


-Graydon

[1] Possibly the inherent impl has to be in the same module as the 
struct, not just the same crate. I don't remember where we drew that 
line. I think it's mostly equivalent either way.


[2] You must also implement any trait T for a struct S in either the 
crate defining T or the crate defining S. This is a different but 
related restriction, to ensure we never have two different impls of T for S.

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev