Closed
Description
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
forCow
when I'm comparing matching againstFoo
? - 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