Skip to content

Misleading diagnostic when implementing const Trait method #103040

Open
@jhpratt

Description

@jhpratt

(playground)

#![feature(const_trait_impl, const_cmp)]

pub struct MyInstant(pub std::time::Instant);

impl const PartialEq<MyInstant> for std::time::Instant {
    fn eq(&self, rhs: &MyInstant) -> bool {
        self.eq(&rhs.0)
    }
}
error[E0308]: mismatched types
 --> src/lib.rs:7:17
  |
7 |         self.eq(&rhs.0)
  |              -- ^^^^^^ expected struct `MyInstant`, found struct `Instant`
  |              |
  |              arguments to this function are incorrect
  |
  = note: expected reference `&MyInstant`
             found reference `&Instant`
note: associated function defined here

This error is technically correct, as the only const eq method on std::time::Instant is the one being written. However, it is quite misleading. &Instant is the type that we want to accept as a parameter, with one caveat. Instant has to implement const PartialEq. It doesn't so the code shouldn't compile, but with a significantly different error message — ideally one pointing to that fact.

I have deliberately chosen Instant for this example because it is unlikely to ever implement const PartialEq. As such it can be used in tests without much concern.

For reference, the diagnostic is pretty much as expected (although still a bit suboptimal in my opinion) when not writing a trait method with the same name. (playground)

#![feature(const_trait_impl, const_cmp)]

pub struct MyInstant(pub std::time::Instant);

pub const fn check_equality(mine: MyInstant, theirs: std::time::Instant) -> bool {
    theirs.eq(&mine.0)
}
error[E0277]: can't compare `Instant` with `_` in const contexts
 --> src/lib.rs:6:15
  |
6 |     theirs.eq(&mine.0)
  |            -- ^^^^^^^ no implementation for `Instant == _`
  |            |
  |            required by a bound introduced by this call
  |
  = help: the trait `~const PartialEq<_>` is not implemented for `Instant`
note: the trait `PartialEq<_>` is implemented for `Instant`, but that implementation is not `const`
 --> src/lib.rs:6:15
  |
6 |     theirs.eq(&mine.0)
  |               ^^^^^^^

@rustbot label +A-const-fn +A-diagnostics +D-confusing +F-const-trait-impl +T-compiler +requires-nightly

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)A-diagnosticsArea: Messages for errors, warnings, and lintsD-confusingDiagnostics: Confusing error or lint that should be reworked.F-const_trait_impl`#![feature(const_trait_impl)]`T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions