Skip to content

Surprising diagnostics about using const value in match pattern #92454

Closed
@djc

Description

@djc

Given the following code (playground:

use std::borrow::Cow;

fn main() {
    let foo = Foo { inner: "foo".into() };
    println!("{}", match foo {
        FOO => "match",
        _ => "no"
    });
}

#[derive(PartialEq, Eq)]
struct Foo {
    inner: Cow<'static, str>,
}

const FOO: Foo = Foo { inner: Cow::Borrowed("foo") };

The current output is:

error: to use a constant of type `Cow` in a pattern, `Cow` must be annotated with `#[derive(PartialEq, Eq)]`
 --> src/main.rs:6:9
  |
6 |         FOO => "match",
  |         ^^^

Surprisingly to me at least, using a custom PartialEq implementation still results in the same issue (playground):

struct Foo {
    inner: Cow<'static, str>,
}

impl PartialEq for Foo {
    fn eq(&self, other: &Self) -> bool {
        self.inner.as_ref() == other.inner.as_ref()
    }
}

impl Eq for Foo {}

This seems pretty unclear:

  • Why is the compiler telling me I should derive PartialEq for Cow when I'm comparing matching against Foo?
  • Why is the compiler telling me to derive PartialEq instead of having a custom impl?

I don't know exactly what kind of contract match depends on, but I would have thought any kind of PartialEq impl (that is, even non-const) would be enough here.

Original issue here: open-telemetry/opentelemetry-rust#685. This also links to a potential fix in sfackler/rust-postgres@05a0643 (involving adding another layer of indirection), but I'd really like to understand why that is even necessary.

(To be clear: the diagnostic is unclear here, but maybe there's an actual compiler problem here, too?)

cc @estebank

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions