Is there any reason to import traits into a module namespace for statically dispatches instead of just apply the traits?

I’m studying Rust and I have a question about necessity to import traits into a module namespace for statically dispatches.

I think it’s generally possible to separate functions of use mod::Trait into the following two statements:

  • a statement which imports mod::Trait into a module namespace in order to use Trait without mod::
  • a statement which enables methods of mod::Trait for statically dispatches

Probably, there are historical and/or technical reasons, but I couldn’t find out such topics on this site. Could you tell me the reason or some documents described about it?

My guess is that the rule was “the trait must be in scope”, and use was for bringing things into scope, and everything else just followed from that.

It prevents ambiguities. If you have a type that implements two traits, and those traits have methods with the same name, which one do you choose? By importing the trait, the users specifies which one to use. If you need to use both traits in the same scope, there is a way to disambiguate, but it isn’t very ergonomic.

Now imagine you have code that works using one trait, and at a later time you implement another trait with the same method names. If the import wasn’t required, it would silently introduce the ambiguity to the whole crate and break code that was working before and is potentially totally unrelated.

@kornel, thank you for your comment.

Yes. That’s a very simple rule. And simplicity is important.

In the meantime, there are some inconveniences which seems to be caused by this simple rule.

For example, we need to use as when we use traits having the same name, even when the traits are used only for statically dispatches. We can find the following topic related to this on this site:

I think that nobody mentioned such topics if Rust provides a statement to enable methods of a trait for statically dispatches without importing the trait name into scope.

Another example is about uniqueness of trait names. In my understanding, it’s recommended to use unique names for types in Rust (I know this is rather a general programming manner which is also applicable to other programing languages).

I agree with this, and this is more important in Rust than other languages. Because Rust requires to import traits into scope for statically dispatches. In the meantime, this recommendation decreases efficiency of module names as namespaces.

I know that there is no perfect programming language. And I just want to know fundamental philosophy in Rust for writing better code.

@ryan, thank you for your comment.

I think that it’s generally possible to distinguish traits having the same name without importing the name into scope, technically. Because each trait have its own fully qualified name like mod1::Trait and mod2::Trait.

My concern was why Rust decided not to separate the following functions of use mod::Trait into two statements:

  • importing the trait name Trait into scope
  • enabling methods of Trait for statically dispatches

My image is like below:

// imports the name `Trait` into scope, but doesn't enable method of Trait for statically dispatches
import mod::Trait;

// enables methods of Trait for statically dispatches without import the name `Trait` into scope
apply mod::Trait;

I agree with you. And we can see descriptions about that in Rules for implementing traits.