Use sort_by_cached_key where appropriate
A follow-up to https://github.com/rust-lang/rust/pull/48639, converting various slice sorting calls to `sort_by_cached_key` when the key functions are more expensive.
Impressing confused Python users with magical diagnostics is perhaps
worth this not-grossly-unreasonable (only 40ish lines) extra complexity
in the parser?
Thanks to Vadim Petrochenkov for guidance.
This resolves#46836.
Expand macros in `extern {}` blocks
This permits macro and proc-macro and attribute invocations (the latter only with the `proc_macro` feature of course) in `extern {}` blocks, gated behind a new `macros_in_extern` feature.
A tracking issue is now open at #49476closes#48747
Expand Attributes on Statements and Expressions
This enables attribute-macro expansion on statements and expressions while retaining the `stmt_expr_attributes` feature requirement for attributes on expressions.
closes#41475
cc #38356 @petrochenkov @jseyfried
r? @nrc
Fix escaped backslash in windows file not found message
When a module is declared, but no matching file exists, rustc gives
an error like `help: name the file either foo.rs or foo/mod.rs inside
the directory "src/bar"`. However, at on windows, the backslash was
double-escaped when naming the directory.
It did this because the string was printed in debug mode (`"{:?}"`) to
surround it with quotes. However, it should just be printed like any
other directory in an error message and surrounded by escaped quotes,
rather than relying on the debug print to add quotes (`"\"{}\""`).
I also checked the test suite to see if this output is being correctly tested. It's not - it only tests up to the word "directory". Presumably this is so that the test is not dependent on its exact position in the source tree. I don't know a better way to test this, unless the test suite supports regex?
When a module is declared, but no matching file exists, rustc gives
an error like 'help: name the file either foo.rs or foo/mod.rs inside
the directory "src/bar"'. However, at on windows, the backslash was
double-escaped when naming the directory.
It did this because the string was printed in debug mode ( "{:?}" ) to
surround it with quotes. However, it should just be printed like any
other directory in an error message and surrounded by escaped quotes,
rather than relying on the debug print to add quotes ( "\"{}\"" ).
They are disallowed because they have different precedence than
expressions. I assume parenthesis in pattern will be soon stabilized and
thus write that as suggestion directly.
(Meanwhile, a couple of parse-fail tests are moved to UI tests so that
the reader can see the new output, and an existing UI test is given a
more evocative name.)
Warn about ignored generic bounds in `for`
This adds a new lint to fix#42181. For consistency and to avoid code duplication, I also moved the existing "bounds in type aliases are ignored" here.
Questions to the reviewer:
* Is it okay to just remove a diagnostic error code like this? Should I instead keep the warning about type aliases where it is? The old code provided a detailed explanation of what's going on when asked, that information is now lost. On the other hand, `span_warn!` seems deprecated (after this patch, it has exactly one user left!).
* Did I miss any syntactic construct that can appear as `for` in the surface syntax? I covered function types (`for<'a> fn(...)`), generic traits (`for <'a> Fn(...)`, can appear both as bounds as as trait objects) and bounds (`for<'a> F: ...`).
* For the sake of backwards compatibility, this adds a warning, not an error. @nikomatsakis suggested an error in https://github.com/rust-lang/rust/issues/42181#issuecomment-306924389, but I feel that can only happen in a new epoch -- right?
Cc @eddyb
Programmers used to working in some other languages (such as Python or
Go) might expect to be able to destructure values with comma-separated
identifiers but no parentheses on the left side of an assignment.
Previously, the first name in such code would get parsed as a
single-indentifier pattern—recognizing, for example, the
`let a` in `let a, b = (1, 2);`—whereupon we would have a fatal syntax
error on seeing an unexpected comma rather than the expected semicolon
(all the way nearer to the end of `parse_full_stmt`).
Instead, let's look for that comma when parsing the pattern, and if we
see it, momentarily make-believe that we're parsing the remaining
elements in a tuple pattern, so that we can suggest wrapping it all in
parentheses. We need to do this in a separate wrapper method called on
the top-level pattern (or `|`-patterns) in a `let` statement, `for`
loop, `if`- or `while let` expression, or match arm rather than within
`parse_pat` itself, because `parse_pat` gets called recursively to parse
the sub-patterns within a tuple pattern.
Resolves#48492.
Also move the check for not having type parameters into ast_validation.
I was not sure what to do with compile-fail/issue-23046.rs: The issue looks like
maybe the bounds actually played a role in triggering the ICE, but that seems
unlikely given that the compiler seems to entirely ignore them. However, I
couldn't find a testcase without the bounds, so I figured the best I could do is
to just remove the bounds and make sure at least that keeps working.
When unnecessarily using a fat arrow after an if condition, suggest the
removal of it.
When finding an if statement with no block, point at the `if` keyword to
provide more context.
When finding:
```rust
match &Some(3) {
&None => 1
&Some(2) => { 3 }
_ => 2
}
```
provide the following diagnostic:
```
error: expected one of `,`, `.`, `?`, `}`, or an operator, found `=>`
--> $DIR/missing-comma-in-match.rs:15:18
|
X | &None => 1
| -- - help: missing comma
| |
| while parsing the match arm starting here
X | &Some(2) => { 3 }
| ^^ expected one of `,`, `.`, `?`, `}`, or an operator here
```