That’s exactly the case in my Rust example presented here: Principles for Implicits in Scala 3 - #16 by tarsa
I provided an example where all definitions are placed in one file which can be misleading. Consider instead a multi-file project with following files:
struct_here.rs:
pub struct MyStruct;
impl MyStruct {}
traits/mod.rs:
pub mod trait_here;
traits/trait_here.rs:
use struct_here::MyStruct;
pub trait MyTrait {
fn print_hello(&self);
}
impl MyTrait for MyStruct {
fn print_hello(&self) {
println!("Hello, World!")
}
}
and finally the main file (library entry point) lib.rs:
pub mod struct_here;
pub mod traits;
use struct_here::MyStruct;
fn entry_point() {
let instance = MyStruct {};
instance.<caret is here>
}
At the specified place IntelliJ suggests me that I can use print_hello()
method on instance
of type struct_here::MyStruct
. Note that traits::trait_here::MyTrait
is not yet imported (with use
keyword). Also struct_here/MyStruct.rs
doesn’t have any reference to traits::trait_here::MyTrait
so IntelliJ really need to scan everything to provide relevant suggestion.
When I choose the suggestion final code looks like this (lib.rs):
pub mod struct_here;
pub mod traits;
use struct_here::MyStruct;
use traits::trait_here::MyTrait; // automatically added line by IntelliJ
fn entry_point() {
let instance = MyStruct {};
instance.print_hello(); // print_hello from autocomplete
}
Rust compiler does similar job to IntelliJ, but in non-interactive way. Rust compiler doesn’t provide auto-complete, but it does suggest relevant import (use
) clause when compilation fails.
There’s also a question why we must import the traits in Rust to make them useable. Answer is simple - with all traits implicitly imported there would be name clashes. Consider this: IeObsi - Online IDE & Debugging Tool - Ideone.com
mod my_struct {
pub struct MyStruct {}
}
mod traits_1 {
pub trait Trait1 {
fn print(&self);
}
impl Trait1 for ::my_struct::MyStruct {
fn print(&self) {
println!("Good morning!");
}
}
}
mod traits_2 {
pub trait Trait2 {
fn print(&self);
}
impl Trait2 for ::my_struct::MyStruct {
fn print(&self) {
println!("Goodbye!");
}
}
}
fn main() {
use traits_1::Trait1;
use traits_2::Trait2;
let instance = my_struct::MyStruct {};
println!("{}", instance.print());
}
Result:
error[E0034]: multiple applicable items in scope
--> src/main.rs:35:29
|
35 | println!("{}", instance.print());
| ^^^^^ multiple `print` found
|
note: candidate #1 is defined in an impl of the trait `traits_1::Trait1` for the type `my_struct::MyStruct`
--> src/main.rs:12:9
|
12 | fn print(&self) {
| ^^^^^^^^^^^^^^^
note: candidate #2 is defined in an impl of the trait `traits_2::Trait2` for the type `my_struct::MyStruct`
--> src/main.rs:24:9
|
24 | fn print(&self) {
| ^^^^^^^^^^^^^^^