Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get "does not implement any method" if module w/ trait use'd, but not when trait imported #21049

Closed
arienmalec opened this issue Jan 12, 2015 · 5 comments

Comments

@arienmalec
Copy link

The following code fails with " error: type objs::Obj does not implement any method in scope named foo"

mod traits {
    pub trait Foo {
        fn foo(&self) -> u32;
    }

}

mod objs {
    use traits;
    pub struct Obj {
        my_foo: u32,
    }

    impl Obj {
        pub fn with_foo(f: u32) -> Self {
            Obj {my_foo: f}
        }
    }
    impl traits::Foo for Obj {
        fn foo(&self) -> u32 {
            self.my_foo
        }
    }
}


fn main() {
    use traits;
    use objs;
    let o = objs::Obj::with_foo(42);
    println!("{}", o.foo());
}

but works when main is changed to specifically import the trait:

fn main() {
    use traits::{Foo};
    use objs;
    let o = objs::Obj::with_foo(42);
    println!("{}", o.foo());
}

Note that the only difference between these two versions is whether Foo is addressable as Foo or as traits::Foo; in either case the trait has been included in scope; that is, the only difference is changing:

use traits;
to
use traits::{Foo};

@Aatch
Copy link
Contributor

Aatch commented Jan 12, 2015

This is expected behaviour. The trait has to be in scope for it to be considered for method resolution. The error message could be more helpful, but that's a separate issue, specifically, #7643.

Closing in favor of that.

@Aatch Aatch closed this as completed Jan 12, 2015
@arienmalec
Copy link
Author

This is a different issue. In #7643, the module was not use'd. In this case, the modeling containing the trait has been use'd and is therefore in scope. See use traits; in the code that isn't working. The only difference between works and does not work is changing:

use traits;
to
use traits::{Foo}

@arienmalec
Copy link
Author

I'd also add that if this behavior is expected, it is inconsistent between library traits and user defined traits. For example, the statement use std::fmt; is sufficient to refer to std::fmt::String

@Aatch
Copy link
Contributor

Aatch commented Jan 13, 2015

@arienmalec there is not any inconsistency. use std::fmt will not bring std::fmt::String into scope. Merely use-ing a module is not enough to bring the trait into scope. Note that this only applies when resolving method calls, not any other time.

@arienmalec
Copy link
Author

I can call the fmt method implemented through implementing the std::fmt::String trait with a use std::fmt. I don't (or write! doesn't) get an error in that case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants