redundant E0210 (coherence) after E0120 (blanket Drop impl)

4f70ff6
Opened by Alex Burka at 2022-07-07 19:27:43
$ cargo script -e 'trait Trait {}      impl<T: Trait> Drop for T { fn drop(&mut self) { } }'
   Compiling expr v0.1.0 (file:///Users/alex/.multirust/toolchains/beta/cargo/.cargo/script-cache/expr-223e68b0943558e6)
error[E0120]: the Drop trait may only be implemented on structures
 --> /Users/alex/.multirust/toolchains/beta/cargo/.cargo/script-cache/expr-223e68b0943558e6/expr.rs:5:41
  |
5 | {trait Trait {} impl<T: Trait> Drop for T { fn drop(&mut self) { } }}
  |                                         ^ implementing Drop requires a struct

error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g. `MyStruct<T>`); only traits defined in the current crate can be implemented for a type parameter
 --> /Users/alex/.multirust/toolchains/beta/cargo/.cargo/script-cache/expr-223e68b0943558e6/expr.rs:5:17
  |
5 | {trait Trait {} impl<T: Trait> Drop for T { fn drop(&mut self) { } }}
  |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors

error: Could not compile `expr`.
  1. Current output:

    error[E0119]: conflicting implementations of trait `std::ops::Drop` for type `std::boxed::Box<_>`:
     --> src/lib.rs:2:1
      |
    2 | impl<T: Trait> Drop for T {
      | ^^^^^^^^^^^^^^^^^^^^^^^^^
      |
      = note: conflicting implementation in crate `alloc`:
              - impl<T> std::ops::Drop for std::boxed::Box<T>
                where T: ?Sized;
      = note: downstream crates may implement trait `Trait` for type `std::boxed::Box<_>`
    
    error[E0120]: the Drop trait may only be implemented on structures
     --> src/lib.rs:2:25
      |
    2 | impl<T: Trait> Drop for T {
      |                         ^ implementing Drop requires a struct
    
    error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
     --> src/lib.rs:2:1
      |
    2 | impl<T: Trait> Drop for T {
      | ^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type
      |
      = note: only traits defined in the current crate can be implemented for a type parameter
    
    error: aborting due to 3 previous errors
    

    Esteban Kuber at 2019-05-15 17:36:43

  2. Current output:

    error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
     --> src/lib.rs:2:6
      |
    2 | impl<T: Trait> Drop for T {
      |      ^ type parameter `T` must be used as the type parameter for some local type
      |
      = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
      = note: only traits defined in the current crate can be implemented for a type parameter
    
    error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions
     --> src/lib.rs:2:25
      |
    2 | impl<T: Trait> Drop for T {
      |                         ^ must be a struct, enum, or union
    

    I personally think E0210 should be the emitted error here.

    Crystal Durham at 2022-07-07 03:07:41

  3. I personally feel like having both E0210 and E0120 here is fine (but wouldn't be against fixing), although maybe we should modify E0120 to point at the type param def span. Other than that, the verbosity caused by this specific case isn't terrible, I think. We should also tweak the wording for the E0120 entry because it only accounts for trying to do this on a trait directly, whereas the error triggers for anything that isn't an ADT.

    Maybe what we should do is have a new error code for this specific case 🤷

    Esteban Kuber at 2022-07-07 19:24:20

  4. wording for the --explain entry

    See https://github.com/rust-lang/rust/issues/98996

    Crystal Durham at 2022-07-07 19:27:43