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

'duplicate definition' error with static functions in different trait scopes #3427

Closed
brendanzab opened this issue Sep 8, 2012 · 4 comments

Comments

@brendanzab
Copy link
Member

Are static functions meant to be in trait scope, or module scope? Here's an example:

trait Vector2<T:Num Ord FuzzyEq> {
    pure fn x() -> T;
    pure fn y() -> T;

    static pure fn make(&&x:float, &&y:float) -> self;
}

trait Vector3<T:Num Ord FuzzyEq> {
    pure fn x() -> T;
    pure fn y() -> T;
    pure fn z() -> T;

    static pure fn make(&&x:float, &&y:float, &&z:float) -> self;

    fn cross(&&other:self) -> self;
}

trait Vector4<T:Num Ord FuzzyEq> {
    pure fn x() -> T;
    pure fn y() -> T;
    pure fn z() -> T;
    pure fn w() -> T;

    static pure fn make(&&x:float, &&y:float, &&z:float, &&w:float) -> self;
}

This is the error I get when I try to compile:

rustc src/om3d.rc --lib --out-dir=lib
src/vec.rs:61:4: 61:64 error: Duplicate definition of value make
src/vec.rs:61     static pure fn make(&&x:float, &&y:float, &&z:float) -> self;
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/vec.rs:53:4: 53:53 note: First definition of value make here:
src/vec.rs:53     static pure fn make(&&x:float, &&y:float) -> self;
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/vec.rs:72:4: 72:75 error: Duplicate definition of value make
src/vec.rs:72     static pure fn make(&&x:float, &&y:float, &&z:float, &&w:float) -> self;
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/vec.rs:61:4: 61:64 note: First definition of value make here:
src/vec.rs:61     static pure fn make(&&x:float, &&y:float, &&z:float) -> self;
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to 2 previous errors
@catamorphism
Copy link
Contributor

This is expected behavior, as static functions live in the enclosing scope. Sorry, you'll have to name your three make functions different things, at least for now.

@brendanzab
Copy link
Member Author

Ok, at least I know now.

I've been running into trouble because I've been doing the constructor along the lines of pcwalton's geom::Matrix4 struct, but then I get a conflict when I try to access static functions from another trait.

eg:

struct vec3 { data:[float * 3] }

// constructor
pure fn vec3<T>(x:T, y:T, z:T) -> vec3<T> {
    vec3<T> { data: [ x, y, z ] }
}

// 3-dimensional functions
trait Vector3<T> {

    ...
}

// N-dimensional functions
impl vec3: Vector<T> {

    // returns the number of components in the vector (conflicts with constructor)
    #[inline(always)] static pure fn dim() -> uint { 3 }

    ...
}
let i = vec3::dim();    // produces an error

I mean, I could always do make_vec3, but it just seems a little ugly as opposed to vec3::make. I also don't get the the advantages of trait polymorphism.

@pcwalton
Copy link
Contributor

Call dim with the module that contains the Vector4 trait; e.g. matrix::dim(), not matrix::vec3::dim().

That said, we've been discussing having traits/types offer a namespace of their own to make this more intuitive: https://mail.mozilla.org/pipermail/rust-dev/2012-August/002255.html

@brendanzab
Copy link
Member Author

Ohhhh. I see now. Yeah I think I'm used to the classic OO style of doing things and assumed it was the same (ala Java/C++). The difficulty is I have vec2, vec3 and vec4 all in the same module. So calling vec::dim isn't really an option. It would mean having to split everything up into separate files.

Good to see that there's some discussion going on, as it would be really nice to take more advantages of traits with static functions.

bors pushed a commit to rust-lang-ci/rust that referenced this issue May 15, 2021
RalfJung pushed a commit to RalfJung/rust that referenced this issue Mar 31, 2024
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

3 participants