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

Allow _ @ CONST in match arms #2941

Open
mahkoh opened this issue Jun 4, 2020 · 5 comments
Open

Allow _ @ CONST in match arms #2941

mahkoh opened this issue Jun 4, 2020 · 5 comments

Comments

@mahkoh
Copy link
Contributor

mahkoh commented Jun 4, 2020

The following is currently not valid:

const CONST: u32 = 1;

fn main() {
    let x = 2;
    match x {
	    _ @ CONST => { },
	    _ => { }
    }
}
error: pattern on wrong side of `@`
 --> src/main.rs:6:6
  |
6 |         _ @ CONST => { },
  |         -^^^-----
  |         |   |
  |         |   binding on the right, should be on the left
  |         pattern on the left, should be on the right
  |         help: switch the order: `CONST @ _`

Apparently because the grammar requires an identifier on the lhs of @. Replacing _ by _x makes the code compile.

Writing

    match x {
	    CONST => { },
	    _ => { }
    }

is ambiguous without a complete analysis of the surrounding module. CONST might be a variable name or a constant. The difference impacts which arm is taken.

On the other hand,

    match x {
	    _x @ CONST => { },
	    _ => { }
    }

is unambiguous but introduces the useless variable _x.

Therefore my proposal is as follows:

  • Make
    match x {
	    _ @ CONST => { },
	    _ => { }
    }

valid syntax.

  • Deprecate
    match x {
	    CONST => { },
	    _ => { }
    }

where CONST could either be a constant or a variable name in the next edition.

@kennytm
Copy link
Member

kennytm commented Jun 4, 2020

with #2920 you could also write

match x {
    const { CONST } => { },
    _ => { },
}

furthermore, because of rust-lang/rust#65490, it is not an error that the CONST in _x @ CONST being another variable.

@mahkoh
Copy link
Contributor Author

mahkoh commented Jun 4, 2020

The problem with _x @ CONST is that it adds useless noise. const { CONST } is unfortunately even noisier.

Using const { CONST } also does not fix the ambiguity (for the reader not the compiler) of code using plain CONST in a match pattern. Consider

match x {
	CONST1 => { },
	CONST2 => { },
}

The compiler will warn you if you forgot to import CONST2 but only because CONST2 is not snake case. This can easily slip through code review and if this particular warning was disabled or if there are many warnings anyway, it might not get caught at all.

@kennytm
Copy link
Member

kennytm commented Jun 4, 2020

if we follow the roadmap in #263 (comment) treating @ as pattern intersection, _ @ CONST would naturally be supported but not having the effect OP desired (if you forget to import CONST there won't be error).

@scottmcm
Copy link
Member

scottmcm commented Jun 9, 2020

I raised the const { CONST } version on IRLO about two months back: https://internals.rust-lang.org/t/bring-enum-variants-in-scope-for-patterns/12104/51?u=scottmcm

There are two interesting replies that suggest the extra noise from requiring the keyword in the pattern would be too annoying for the value.

We're very good at emitting at least one warning in the mistaken cases here; is there maybe a subset that we could upgrade to be deny-by-default because it's so unlikely to be correct?

@igotfr

This comment was marked as off-topic.

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

No branches or pull requests

4 participants