gccrs icon indicating copy to clipboard operation
gccrs copied to clipboard

Dataless enum variants can be matched without full path

Open philberty opened this issue 3 years ago • 2 comments

I tried this code: https://godbolt.org/z/7eqP9vrTn

extern "C" {
    fn printf(s: *const i8, ...);
}

enum Foo {
   A,
   B(i32),
}

fn main() {
    let result = Foo::B(123);

    match result {
        A => unsafe {
            let a = "A\n\0";
            let b = a as *const str;
            let c = b as *const i8;

            printf(c);
        },
        Foo::B(x) => unsafe {
            let a = "Result: %i\n\0";
            let b = a as *const str;
            let c = b as *const i8;

            printf(c, x);
        },
    }
}

I expected to see this happen: compile without error Instead, this happened:

rust1: error: expected [Foo{A = 1, B (0:Int:i32:(Ref: 28 TyRef: 8[8,]):bounds:[])}] got [<tyty::error>]
<source>:13:5: error: failed to type resolve expression
   13 |     match result {
      |     ^
<source>:10:1: error: expected [()] got [<tyty::error>]
   10 | fn main() {
      | ^

Meta

  • What version of Rust GCC were you using, git sha if possible.

philberty avatar Jan 04 '22 12:01 philberty

No, this isn't matching the Foo::A variant. In this case A is a pattern binding. You could have written foo and it would have worked the same. Rustc gave you three warnings to notify you of this.

warning[E0170]: pattern binding `A` is named the same as one of the variants of the type `Foo`
  --> <source>:14:9
   |
14 |         A => unsafe {
   |         ^ help: to match on the variant, qualify the path: `Foo::A`
   |
   = note: `#[warn(bindings_with_variant_name)]` on by default

warning: unreachable pattern
  --> <source>:21:9
   |
14 |         A => unsafe {
   |         - matches any value
...
21 |         Foo::B(x) => unsafe {
   |         ^^^^^^^^^ unreachable pattern
   |
   = note: `#[warn(unreachable_patterns)]` on by default

warning: unused variable: `A`
  --> <source>:14:9
   |
14 |         A => unsafe {
   |         ^ help: if this is intentional, prefix it with an underscore: `_A`
   |
   = note: `#[warn(unused_variables)]` on by default

bjorn3 avatar Jan 04 '22 13:01 bjorn3

@bjorn3 thanks so much i missed this! This is a huge relief that this is the case as I was trying to figure out how that would work lol

philberty avatar Jan 04 '22 13:01 philberty

This isn’t actually fixed; the test added in #2072 behaves differently on gccrs than on rustc: Godbolt link (Expected output is A because A is a pattern that matches anything.)

See also https://github.com/Rust-GCC/gccrs/issues/2082#issuecomment-1681246225

narpfel avatar Aug 16 '23 20:08 narpfel

@narpfel yes, I had reopened https://github.com/Rust-GCC/gccrs/issues/2144 as a follow up. We closed this issue because the original code would not compile, even though it should (with warnings)

CohenArthur avatar Aug 17 '23 10:08 CohenArthur