Skip to content

Const equality disagrees when using in match and ifΒ #108207

Open
@Pzixel

Description

@Pzixel

Consider following code:

#[derive(Debug, PartialEq, Eq)]
struct Foo([u32; 4]);

const fn bar() {
    const ONE: Foo = Foo([1, 0, 0, 0]);
    match Foo([0, 0, 0, 0]) {
        ONE => unreachable!(),
        _ => {},
    }

    if ONE == Foo([0, 0, 0, 0]) {
        unreachable!()
    }
}

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=f2b2c2421583fbb47472f8e8746b394f
It fails with "the trait PartialEq<_> is implemented for Foo, but that implementation is not const".

But if we do add a const implementation:

#![feature(const_trait_impl)]

#[derive(Debug, Eq)]
struct Foo([u32; 4]);

impl const PartialEq for Foo {
    fn eq(&self, other: &Self) -> bool {
        self.0[0] == other.0[0]
        && self.0[1] == other.0[1]
        && self.0[2] == other.0[2]
        && self.0[3] == other.0[3]
    }
}


const fn bar() {
    const ONE: Foo = Foo([1, 0, 0, 0]);
    match Foo([0, 0, 0, 0]) {
        ONE => unreachable!(),
        _ => {},
    }

    if ONE == Foo([0, 0, 0, 0]) {
        unreachable!()
    }
}

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=a980e3ab7d72b9545886de5547cf4963
then it fails with "to use a constant of type Foo in a pattern, Foo must be annotated with `#[derive]"

So we found ourselves between rock and hard place where we have to choose between using pattern matching and equality.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)A-patternsRelating to patterns and pattern matching

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions