Skip to content

Misleading compiler suggestion when trying to match NonZero type #85049

Closed
@baumanj

Description

@baumanj

I tried this code (playground link):

    let n = std::num::NonZeroU32::new(1).unwrap();
    match n {
        std::num::NonZeroU32(i) => {},
    }

I expected this to work.

Instead, this happened:

error[E0532]: expected tuple struct or tuple variant, found struct `std::num::NonZeroU32`
   --> src/lib.rs:4:9
    |
4   |           std::num::NonZeroU32(i) => {},
    |           ^^^^^^^^^^^^^^^^^^^^^^^ help: use struct pattern syntax instead: `std::num::NonZeroU32 { 0 }

And trying that (playground link):

error[E0769]: tuple variant `std::num::NonZeroU32` written as struct variant
 --> src/lib.rs:4:9
  |
4 |         std::num::NonZeroU32 { 0 } => {},
  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
help: use the tuple variant pattern syntax instead
  |
4 |         std::num::NonZeroU32(0) => {},
  |                             ^^^

Results are the same in beta and nightly.

I recognize the real issue here is that the field of the NonZero newtype structs is private, but the error message could be better.

As an aside, it would be nice to be able to do this matching. In the end I resorted to

        match std::num::NonZeroU32::new(1).unwrap().get() {
            0 => unreachable!(),
            1 => Ok(n),
            d => {}
        }

which can't be compile-time verified

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions