Skip to content

StructuralPartialEq diagnostic inconsistent with code #150298

Closed

Description

@cedtwo

Code

use std::marker::PhantomData;

#[derive(Debug, Clone, Copy, PartialEq)]
pub struct StructuralType<T: PartialEq> {
    ty: PhantomData<T>,
    var: u32,
}

impl<T: PartialEq> StructuralType<T> {
    const A: Self = StructuralType {
        ty: PhantomData,
        var: 0,
    };

    const B: Self = StructuralType {
        ty: PhantomData,
        var: 0,
    };

    fn broken(self) {
        match self {
            Self::A => {}
            Self::B => {}
            _ => {}
        }
    }
}

Current output

error: constant of non-structural type `StructuralType<T>` in a pattern
  --> src/lib.rs:22:13
   |
 4 | pub struct StructuralType<T: PartialEq> {
   | --------------------------------------- `StructuralType<T>` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
 9 | impl<T: PartialEq> StructuralType<T> {
   | ------------------------------------
10 |     const A: Self = StructuralType {
   |     ------------- constant defined here
...
22 |             Self::A => {}
   |             ^^^^^^^ constant of non-structural type

error: constant of non-structural type `StructuralType<T>` in a pattern
  --> src/lib.rs:23:13
   |
 4 | pub struct StructuralType<T: PartialEq> {
   | --------------------------------------- `StructuralType<T>` must be annotated with `#[derive(PartialEq)]` to be usable in patterns
...
 9 | impl<T: PartialEq> StructuralType<T> {
   | ------------------------------------
...
15 |     const B: Self = StructuralType {
   |     ------------- constant defined here
...
23 |             Self::B => {}
   |             ^^^^^^^ constant of non-structural type

error: could not compile `test_structural_ty` (lib) due to 2 previous errors

Desired output

Undecided, however the suggestion to annotate #[derive(PartialEq)] is incorrect.

Rust Version

rustc 1.92.0 (ded5c06cf 2025-12-08)
binary: rustc
commit-hash: ded5c06cf21d2b93bffd5d884aa6e96934ee4234
commit-date: 2025-12-08
host: x86_64-unknown-linux-gnu
release: 1.92.0
LLVM version: 21.1.3

Additional Information

Activity

  1. added
    A-diagnosticsArea: Messages for errors, warnings, and lints
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Dec 23, 2025
  2. added
    D-incorrectDiagnostics: A diagnostic that is giving misleading or incorrect information.
    on Dec 23, 2025
  3. dianne commented on Jan 10, 2026

    @dianne
    Member

    Similar to #150296, I think this is because when checking if ADTs shallowly support structural equality, we use an empty ParamEnv; i.e. we ignore the T: Sized and T: PartialEq in the environment when trying to prove that StructuralType<T>: StructuralPartialEq. Since those bounds are both required by the definition of StructuralType to use StructuralType<T> as a type at all, we can't prove it's StructuralPartialEq. Usually using an empty ParamEnv is fine (and better for query caching) since generic params aren't supported in const patterns, but that's caught when evaluating the constant to a valtree; we usually can't do that in the presence of generics. In this case, the generic is effectively unused, so evaluation to a valtree succeeds, meaning we check for structural equality (which fails due to missing clauses in the environment).

    As with #150296, I think the easy fix here is to be more strict about not supporting params in const patterns' types. I'd personally prefer a simple, consistent rule over carving out special cases where it technically can work. We can always relax it later if we want to support this.

  4. dianne commented on Jul 24, 2026

    @dianne
    Member

    On nightly, the errors are now

    error[E0158]: constant pattern cannot depend on generic parameters
      --> src/lib.rs:22:13
       |
     9 | impl<T: PartialEq> StructuralType<T> {
       | ------------------------------------
       |      |
       |      constant depends on this generic parameter
    10 |     const A: Self = StructuralType {
       |     ------------- constant defined here
    ...
    20 |     fn broken(self) {
       |        ------
    21 |         match self {
    22 |             Self::A => {}
       |             ^^^^^^^ `const` depends on a generic parameter
    
    error[E0158]: constant pattern cannot depend on generic parameters
      --> src/lib.rs:23:13
       |
     9 | impl<T: PartialEq> StructuralType<T> {
       | ------------------------------------
       |      |
       |      constant depends on this generic parameter
    ...
    15 |     const B: Self = StructuralType {
       |     ------------- constant defined here
    ...
    20 |     fn broken(self) {
       |        ------
    ...
    23 |             Self::B => {}
       |             ^^^^^^^ `const` depends on a generic parameter
    

    Closing as fixed by #159504.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsD-incorrectDiagnostics: A diagnostic that is giving misleading or incorrect information.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