Open
Description
Today item import take precedence over glob imports which take precedence over prelude imports. This works for traits:
mod a {
pub trait X {
fn x(&self) { println!("a"); }
}
impl X for () {}
}
mod b {
pub trait X {
fn x(&self) { println!("b"); }
}
impl X for () {}
}
use a::X;
use b::*;
fn main() {
().x(); // Works and prints "a", b/c b is shadowed
}
However, this logic does not work for trait methods. If we rename b::X
to b::Y
, the code fails to compile:
mod a {
pub trait X {
fn x(&self) { println!("a"); }
}
impl X for () {}
}
mod b {
pub trait Y {
fn x(&self) { println!("b"); }
}
impl Y for () {}
}
use a::X;
use b::*;
fn main() {
().x(); // error: multiple `x` found
}
I think this problematic for two reasons:
- it seems inconsistent with how other names work
- it makes adding a trait to prelude in std and other crates a breaking change (see Tracking issue for the 2018 edition’s prelude #51418)
Could we perhaps fix it?
r? @rust-lang/lang