Skip to content

structural_match bug: deep refs like & &B leak use of PartialEq #62307

Closed
@pnkfelix

Description

@pnkfelix

(Spawned off of investigation of #61188)

rust-lang/rfcs#1445 says that we're supposed to reject uses of consts with ADT's that don't implement #[structural_match] (i.e. ADT's that do not do #[derive(PartialEq, Eq)].

Unfortunately, we did not quite finish the job. Consider the following code (play):

#[derive(Debug)]
struct B(i32);

// Overriding PartialEq to use this strange notion of equality exposes
// whether `match` is using structural-equality or method-dispatch
// under the hood, which is the antithesis of rust-lang/rfcs#1445
impl PartialEq for B {
    fn eq(&self, other: &B) -> bool { std::cmp::min(self.0, other.0) == 0 }
}

const ZER_B: & & B = & & B(0);
const ONE_B: & & B = & & B(1);

fn main() {
    if let ONE_B = ZER_B {
        println!("CLAIM Z: {:?} matches {:?}", ONE_B, ZER_B);
    }

    if let ONE_B = ONE_B {
        println!("CLAIM O: {:?} matches {:?}", ONE_B, ONE_B);
    }
}

This prints:

CLAIM Z: B(1) matches B(0)

but I would expect to see something like the error you get if you use constants of type &B instead of & &B:

error: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq, Eq)]`
  --> src/main.rs:15:12
   |
15 |     if let ONE_B = ZER_B {
   |            ^^^^^

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.T-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