Skip to content

Inconsistency: let mut _ = 0; is rejected by the parser when let mut _a = 0; is not #32501

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

Closed
nodakai opened this issue Mar 26, 2016 · 7 comments
Labels
A-parser Area: The lexing & parsing of Rust source code to an AST

Comments

@nodakai
Copy link
Contributor

nodakai commented Mar 26, 2016

fn main() {
    let a = 0;
    let _b = 0;
    let _ = 0;
    let mut b = 0;
    let mut _b = 0;
//    let mut _ = 0; // error: expected identifier, found `_`
}
@nodakai nodakai changed the title Inconsistency: let mut _ = 0 raises an error when let mut _a = 0 does not Inconsistency: let mut _ = 0 is rejected by the parser when let mut _a = 0 does not Mar 26, 2016
@nodakai nodakai changed the title Inconsistency: let mut _ = 0 is rejected by the parser when let mut _a = 0 does not Inconsistency: let mut _ = 0; is rejected by the parser when let mut _a = 0; is not Mar 26, 2016
@KalitaAlexey
Copy link
Contributor

_ is not a identifier. It is used to suppress result.

@petrochenkov
Copy link
Contributor

This is correct, ref/mut can't be followed by an arbitrary pattern (like _), they expect a single identifier (like a or _a).

@bluss
Copy link
Member

bluss commented Mar 26, 2016

Here's an example that shows a clear difference between _ and _s (playground)

fn main() {
    let s = String::new();
    let _ = s;  // no op
    let _t = s; // move
    let _u = s; // ERROR: use of moved value
}

@nodakai
Copy link
Contributor Author

nodakai commented Mar 26, 2016

Yes, _a is just a variable whose should_warn() happens to return false (librustc/middle/liveness.rs) wherease _ aka token::Underscore generates a placeholder pattern (PatKind::Wild.)
When parse_pat() (libsyntax/parse/parser.rs) finds mut in a let-binding, it accepts only a proper identifier.

Nevertheless I perceive the language design is inconsistent here and scarcely documented. Is it only me who think something has to be improved?

@nodakai
Copy link
Contributor Author

nodakai commented Mar 26, 2016

@bluss Well, in fact let _a = 0; println!("{}", _a) has no problems.

    let _ = s;  // no op

This is surprising, but I might have seen a discussion on something like that long before, perhaps in relation to mem::drop()

@petrochenkov
Copy link
Contributor

Is it only me who think something has to be improved?

Something may be improved, i.e. a custom error message can be issued, but I suppose specialized diagnostics need to be data-driven, i.e. targeted at people en masse and not individuals experimenting in the playpen in the search of consistency :)
How likely is this construction written accidentally by a person not familiar with the difference between patterns and identifiers? let _ = foo; - very likely, let mut _ = foo; - probably unlikely (I wish we had a way to measure these things somehow).

@petrochenkov
Copy link
Contributor

I've added a bit more general diagnostic message in #32506

@steveklabnik steveklabnik added the A-parser Area: The lexing & parsing of Rust source code to an AST label Mar 28, 2016
bors added a commit that referenced this issue Mar 31, 2016
syntax: Extra diagnostics for `_` used in an identifier position

Closes #32501
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-parser Area: The lexing & parsing of Rust source code to an AST
Projects
None yet
Development

No branches or pull requests

5 participants