Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Matching struct-like enum with wildcard is broken #5530

Closed
gifnksm opened this issue Mar 25, 2013 · 5 comments
Closed

Matching struct-like enum with wildcard is broken #5530

gifnksm opened this issue Mar 25, 2013 · 5 comments

Comments

@gifnksm
Copy link
Contributor

gifnksm commented Mar 25, 2013

fun1 and fun2 should return same value.

enum Enum {
    Foo { foo: uint },
    Bar { bar: uint }
}

fn fun1(e1: &Enum, e2: &Enum) -> uint {
    match (e1, e2) {
        (&Foo { foo: _ }, &Foo { foo: _ }) => 0,
        (&Foo { foo: _ }, &Bar { bar: _ }) => 1,
        (&Bar { bar: _ }, &Bar { bar: _ }) => 2,
        (&Bar { bar: _ }, &Foo { foo: _ }) => 3,
    }
}

fn fun2(e1: &Enum, e2: &Enum) -> uint {
    match (e1, e2) {
        (&Foo { foo: _ }, &Foo { foo: _ }) => 0,
        (&Foo { foo: _ }, _              ) => 1,
        (&Bar { bar: _ }, &Bar { bar: _ }) => 2,
        (&Bar { bar: _ }, _              ) => 3,
    }
}

fn main() {
    let foo = Foo { foo: 1 };
    let bar = Bar { bar: 1 };

    assert_eq!(fun1(&foo, &foo), 0);
    assert_eq!(fun1(&foo, &bar), 1);
    assert_eq!(fun1(&bar, &bar), 2);
    assert_eq!(fun1(&bar, &foo), 3);

    assert_eq!(fun2(&foo, &foo), 0);
    assert_eq!(fun2(&foo, &bar), 1); // fun2 returns 0
    assert_eq!(fun2(&bar, &bar), 2);
    assert_eq!(fun2(&bar, &foo), 3); // fun2 returns 2
}
$ ./test
rust: task failed at 'expected: 1, given: 0', ./test.rs:34
rust: domain main @0x25b79c0 root task failed
@catamorphism
Copy link
Contributor

This works now. I'll check in the test case.

@catamorphism
Copy link
Contributor

Hmm, it passed for me but failed on the Linux bot. Nominating for milestone 5, production-ready

@pnkfelix
Copy link
Member

I get a failure on Mac OS X:

% ./iss5530-a
rust: task failed at 'left: 0 does not equal right: 1', iss5530-a.rs:34
rust: domain main @0x7fb6f2813c10 root task failed

(line 34 is the case: assert_eq!(fun2(&foo, &bar), 1); // fun2 returns 0)

@smvv
Copy link
Contributor

smvv commented Jul 18, 2013

The following program fails: the match returns true, but should return false.

enum AB {
    None,
    A { a: int },
    B { b: int }
}

fn main() {
    let b = Some(B {b: 1});
    assert!(!match b {
        Some(A { a: _ }) => true,
        _ => false
    })
}

I believe the cause of the failure is similar to the failures described in this issue.

@graydon
Copy link
Contributor

graydon commented Aug 8, 2013

Incoming PR, will fix when landed (hopefully)

bors added a commit that referenced this issue Aug 9, 2013
Code that collects fields in struct-like patterns used to ignore
wildcard patterns like `Foo{_}`. But `enter_defaults` considered
struct-like patterns as default in order to overcome this
(accoring to my understanding of situation).

However such behaviour caused code like this:
```
enum E {
    Foo{f: int},
    Bar
}
let e = Bar;
match e {
    Foo{f: _f} => { /* do something (1) */ }
    _ => { /* do something (2) */ }
}
```
consider pattern `Foo{f: _f}` as default. That caused inproper behaviour
and even segfaults while trying to destruct `Bar` as `Foo{f: _f}`.
Issues: #5625 , #5530.

This patch fixes `collect_record_or_struct_fields` to split cases of
single wildcard struct-like pattern and no struct-like pattern at all.
Former case resolved with `enter_rec_or_struct` (and not with
`enter_defaults`).

Closes #5625.
Closes #5530.
@bors bors closed this as completed in 0fadfc5 Aug 9, 2013
oli-obk pushed a commit to oli-obk/rust that referenced this issue May 2, 2020
map_clone: avoid suggesting `copied()` for &mut

changelog: map_clone: avoid suggesting `copied()` for &mut

Fixes rust-lang#5524
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants