Spurious confusing errors on trait impl on type name collision
type Type = ();
#[derive(Debug)]
struct Type;
impl Iterator for Type {}
Gives:
Compiling playground v0.0.1 (file:///playground)
error[E0428]: the name `Type` is defined multiple times
--> src/main.rs:4:1
|
1 | type Type = ();
| --------------- previous definition of the type `Type` here
...
4 | struct Type;
| ^^^^^^^^^^^^ `Type` redefined here
|
= note: `Type` must be defined only once in the type namespace of this module
error[E0119]: conflicting implementations of trait `std::fmt::Debug` for type `()`:
--> src/main.rs:3:10
|
3 | #[derive(Debug)]
| ^^^^^
|
= note: conflicting implementation in crate `core`
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> src/main.rs:6:1
|
6 | impl Iterator for Type {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ impl doesn't use types inside crate
|
= note: the impl does not reference any types defined in this crate
= note: define and implement a trait or new type instead
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> src/main.rs:3:10
|
3 | #[derive(Debug)]
| ^^^^^ impl doesn't use types inside crate
|
= note: the impl does not reference any types defined in this crate
= note: define and implement a trait or new type instead
error: aborting due to 4 previous errors
error: Could not compile `playground`.
To learn more, run the command again with --verbose.
The first error is true. The rest are spurious. There are probably other spurious errors that can be generated via name collision.
For
#[derive]specifically a chunk of this would get resolved if#[derive]produced hygienic references to the annotated type. Not sure if that’s possible or reasonable thing to do though. Alternatively,impl Iterator for NotDefinedAtAll {}manages to not produce an error here somehow, so maybe a similar strategy could be applied for names with conflicting resolution too…?
I also encountered this just now and I imagine today this issue is probably much more relevant than it was in 2017 – today many people will be using rust-analyzer or somesuch, and seeing something like
#[derive(Debug)] ■■■ only traits defined in the current crate can be... enum Banana { ... }is comparatively more confusing when you don’t necessarily have the accompanying
the name Banana is defined multiple times...on the same page.Simonas Kazlauskas at 2022-09-08 12:47:33