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

seemingly incorrect nontrivial_structural_match warning #110508

Open
jmhain opened this issue Apr 18, 2023 · 4 comments
Open

seemingly incorrect nontrivial_structural_match warning #110508

jmhain opened this issue Apr 18, 2023 · 4 comments
Assignees
Labels
A-const-eval Area: Constant evaluation, covers all const contexts (static, const fn, ...) A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html A-patterns Relating to patterns and pattern matching C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@jmhain
Copy link

jmhain commented Apr 18, 2023

For the following code, I get a compiler warning:

#[derive(PartialEq, Eq)]
pub enum Thing { Foo(bool), Bar(Vec<()>) }

impl Thing {
    pub const FOO: Thing = Self::Foo(true);
}

pub fn foo(thing: Thing) {
    match thing {
        Thing::FOO => {},
        _ => {},
    }
}

Playground link

And the warning:

warning: to use a constant of type `Vec<()>` in a pattern, the constant's initializer must be trivial or `Vec<()>` must be annotated with `#[derive(PartialEq, Eq)]`
  --> src/lib.rs:10:9
   |
10 |         Thing::FOO => {},
   |         ^^^^^^^^^^
   |
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, [see issue #73448 <https://github.com/rust-lang/rust/issues/73448>](https://github.com/rust-lang/rust/issues/73448)
   = note: `#[warn(nontrivial_structural_match)]` on by default

What makes me think this warning is incorrect is that the constant's initializer does not produce the Vec-containing variant like the warning suggests, and changing Self:: to Thing:: in the initializer resolves the error despite those (afaik) being equivalent.

@jmhain jmhain added the C-bug Category: This is a bug. label Apr 18, 2023
@compiler-errors
Copy link
Member

changing Self:: to Thing:: in the initializer resolves the error despite those (afaik) being equivalent.

Strange... Given:

#[derive(PartialEq, Eq)]
pub enum Thing { Foo(bool), Bar(Vec<()>) }

impl Thing {
    pub const FOO: Thing = Thing::Foo(true);
    pub const BAR: Thing = Self::Foo(true);
}

fn main() {}

The MIR we generate for either associated const is quite different...

const <impl at [src/main.rs:4:1: 4:11](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021#)>::FOO: Thing = {
    let mut _0: Thing;                   // return place in scope 0 at [src/main.rs:5:20: 5:25](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021#)

    bb0: {
        Deinit(_0);                      // scope 0 at [src/main.rs:5:28: 5:44](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021#)
        ((_0 as Foo).0: bool) = const true; // scope 0 at [src/main.rs:5:28: 5:44](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021#)
        discriminant(_0) = 0;            // scope 0 at [src/main.rs:5:28: 5:44](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021#)
        return;                          // scope 0 at [src/main.rs:5:5: 5:45](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021#)
    }
}

const <impl at [src/main.rs:4:1: 4:11](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021#)>::BAR: Thing = {
    let mut _0: Thing;                   // return place in scope 0 at [src/main.rs:6:20: 6:25](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021#)

    bb0: {
        _0 = Thing::Foo(const true) -> bb1; // scope 0 at [src/main.rs:6:28: 6:43](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021#)
                                         // mir::Constant
                                         // + span: [src/main.rs:6:28: 6:37](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021#)
                                         // + literal: Const { ty: fn(bool) -> Thing {Thing::Foo}, val: Value(<ZST>) }
    }

    bb1: {
        return;                          // scope 0 at [src/main.rs:6:5: 6:44](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021#)
    }
}

🤔

@jyn514 jyn514 added A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html A-const-eval Area: Constant evaluation, covers all const contexts (static, const fn, ...) A-patterns Relating to patterns and pattern matching T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Apr 20, 2023
@ericmarkmartin
Copy link
Contributor

I'd like to take a swing at this

@ericmarkmartin
Copy link
Contributor

@rustbot claim

@ericmarkmartin
Copy link
Contributor

@compiler-errors I looked at the thir generated for your program

#[derive(PartialEq, Eq)]
pub enum Thing { Foo(bool), Bar(Vec<()>) }

impl Thing {
    pub const FOO: Thing = Thing::Foo(true);
    pub const BAR: Thing = Self::Foo(true);
}

fn main() {}

and FOO and BAR are already different. FOO has kind Adt whereas BAR has kind Call.

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jul 8, 2023
…-ctor-to-adt, r=cjgillot

resolve typerelative ctors to adt

Associated issue: rust-lang#110508

r? `@spastorino`
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jul 8, 2023
…-ctor-to-adt, r=cjgillot

resolve typerelative ctors to adt

Associated issue: rust-lang#110508

r? ``@spastorino``
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-const-eval Area: Constant evaluation, covers all const contexts (static, const fn, ...) A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html A-patterns Relating to patterns and pattern matching C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants