Spurious confusing errors on trait impl on type name collision

8fc16d8
Opened by Ryan Scheel at 2022-09-08 12:48:09
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.

  1. 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