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

Improve pattern-checking error message with variable that resembles an enum variant #4612

Closed
Kimundi opened this issue Jan 24, 2013 · 9 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-frontend Area: Compiler frontend (errors, parsing and HIR) C-enhancement Category: An issue proposing an enhancement or a PR with one.

Comments

@Kimundi
Copy link
Member

Kimundi commented Jan 24, 2013

This code:

mod foo {
  pub enum Bars {
    BarFoo,
    BarBar,
    BarBaz
  }
}

fn main() {
    decide(foo::BarBar);
}

fn decide(bar: foo::Bars) -> int {
    match bar {
        BarFoo => 0,
        BarBar => 42,
        BarBaz => 128
    }
}

should fail to compile because it can't resolve the enum variants in the match statement.
But currently it outputs this error message instead:

match_namespace.rs:16:8: 16:17 error: unreachable pattern
match_namespace.rs:16         BarBar => 42,
                              ^~~~~~~~~
match_namespace.rs:17:8: 17:17 error: unreachable pattern
match_namespace.rs:17         BarBaz => 128
                              ^~~~~~~~~

Which is curious because it doesn't complaint about the first item in the match statement, and because it somehow confuses 'Don't know what it is' with 'Can't reach it'.

@jdm
Copy link
Contributor

jdm commented Jan 24, 2013

The problem here is subtle. BarFoo gets treated as the name for any value, meaning that the subsequent statements actually are unreachable (and they are just treated as names for any value as well).

@catamorphism
Copy link
Contributor

This isn't a bug: like @jdm said, because there's no enum variant named BarFoo, resolve assumes you mean to introduce a variable named BarFoo.

There's really no way around this, but I guess we could add some extra logic to the pattern-matching checking that detects this kind of situation and prints out extra diagnostics along with "unreachable pattern" (like, "...because variable pattern BarFoo matches any value"). I'll change the subject line and make this an enhancement issue.

@Kimundi
Copy link
Member Author

Kimundi commented Jan 25, 2013

Oh, you're right this is fully correct behavior.

I guess the compiler should then warn, if:

  • it treats something in camel case as a variable
  • the thing it matches on is an enum and the pattern is a valid enum variant in its namespace
  • the variable it captures is not used in the match arm

@nikomatsakis
Copy link
Contributor

I think having #3070 (and making it enabled by default) would effectively solve this problem, and in a much easier way.

@catamorphism
Copy link
Contributor

I don't like the idea of just letting lint solve the problem (though I think we should have the lint pass too) since lint happens after match checking. Reading the error messages, it would still be confusing to read the "unreachable pattern" error; you might try to figure out what the error means without continuing to the rest of the errors. I think the error message should be self-contained.

@nikomatsakis
Copy link
Contributor

I agree with your point regarding not having too many error messages. However, there is no reason that lint-style checks have to be done in the lint pass. They could just as easily be done in the exhaustiveness checker. I think we want to do a lint-style check regardless in order to catch things like this:

match foo {
    Bar => { ... } // I thought there was only one variant, but actually I'm getting a variable
}

I was thinking that another useful lint rule would be something like this: if there is ever a variable binding "foo" whose type is an enum E that includes a variant named "foo" (which clearly is not in scope), report a warning.

@catamorphism
Copy link
Contributor

Oh, well if it's a lint check that's not actually part of the lint module, then I guess we're basically agreeing :-)

@nikomatsakis
Copy link
Contributor

I think so. All I really mean is that we don't have to complicate the exhaustiveness checker by having it figure out why some branch is dead, it can instead just look at at the capitalized variable names and give a warning about those.

@catamorphism
Copy link
Contributor

I think #3070 captures the work that needs to be done here.

flip1995 pushed a commit to flip1995/rust that referenced this issue Dec 20, 2020
Add --no-deps option to avoid running on path dependencies in workspaces

Since rust-lang/cargo#8758 has hit nightly, this allows us to address the second bullet point and [the concern related to `--fix`](rust-lang/cargo#8143 (comment)) in the [RUSTC_WORKSPACE_WRAPPER tracking issue](rust-lang/cargo#8143).

As a reminder stabilizing that env var will solve rust-lang#4612 (Clippy not running after `cargo check` in stable) and would allow to stabilize the `--fix` option in Clippy.

changelog: Add `--no-deps` option to avoid running on path dependencies in workspaces

Fixes rust-lang#3025
flip1995 pushed a commit to flip1995/rust that referenced this issue Feb 11, 2021
Stabilize workspace wrapper.

This fixes it so that `cargo clippy` doesn't share the same cache artifacts as `cargo check`. The Cargo side was stabilized a while ago (rust-lang/cargo#8976), so this should be ready to go. I'm not aware of any blockers or concerns.

Closes rust-lang#4612

---

changelog: `cargo clippy` no longer shares the same build cache as `cargo check`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-frontend Area: Compiler frontend (errors, parsing and HIR) C-enhancement Category: An issue proposing an enhancement or a PR with one.
Projects
None yet
Development

No branches or pull requests

4 participants