What happened when using functions and traits which have same names

This works (play)

mod a {
    pub fn foo(x: i32) {
        println!("{}", x);
    }
    
    pub trait foo {
        fn foo(self);
    }
    
    impl foo for i32 {
        fn foo(self) {
            println!("{}", self);
        }
    }
}

use a::foo;

fn main() {
    let x = 1;
    x.foo();
    
    foo(x);
}

If I want to use different names for function and trait when using, is there anything I can do?

Values, types/traits, and macros have different namespaces, so they can reuse names like you noticed. (And a function is a sort of constant value.) This is important to several Rust features you've probably used without noticing:

  • When you write struct Foo; you get a type named Foo and a constant named Foo.
  • When you write struct Foo(String); you get a type named Foo and a function named Foo.
  • Derive macros are separate items from the traits they derive, but usually have the same name.

I'm not aware of any way to prohibit such overlap, but if there were going to be, it'd be put in Clippy.

2 Likes

If you follow Rust naming conventions, it won't happen... given a language with capital letters anyway.

I don't think there's a way to not import both the trait and the function at the same time. But note that you never used the trait name (you used the method name). You can rename things on import:

But as the last lines show, it renames the trait too. You can import them both renamed and not renamed, but only self discipline will keep the use distinct.

1 Like

So.. use exports names instead of items, right? Or use exports items have the same names.

There are some quirks around macros if nothing else, but "use imports names" is pretty close.

2 Likes