Recover from using `;` as separator between fields
Partially fixes#101440 (only for record structs).
Doing that for tuple structs is harder as their parsing passes through a bunch of helper functions. I don't know how to do that. But [their error message is better anyway](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=cc6ee8bb2593596c0cea89d49e79bcb4) and suggests using a comma, even if it doesn't suggest replacing the semicolon with it.
Recover keywords in trait bounds
(_this pr was inspired by [this tweet](https://twitter.com/Azumanga/status/1552982326409367561)_)
Recover keywords in trait bound, motivational example:
```rust
fn f(_: impl fn()) {} // mistyped, meant `Fn`
```
<details><summary>Current nightly (3 needless and confusing errors!)</summary>
<p>
```text
error: expected identifier, found keyword `fn`
--> ./t.rs:1:15
|
1 | fn _f(_: impl fn()) {}
| ^^ expected identifier, found keyword
|
help: escape `fn` to use it as an identifier
|
1 | fn _f(_: impl r#fn()) {}
| ++
error: expected one of `:` or `|`, found `)`
--> ./t.rs:1:19
|
1 | fn _f(_: impl fn()) {}
| ^ expected one of `:` or `|`
error: expected one of `!`, `(`, `)`, `,`, `?`, `for`, `~`, lifetime, or path, found keyword `fn`
--> ./t.rs:1:15
|
1 | fn _f(_: impl fn()) {}
| -^^ expected one of 9 possible tokens
| |
| help: missing `,`
error: at least one trait must be specified
--> ./t.rs:1:10
|
1 | fn _f(_: impl fn()) {}
| ^^^^
```
</p>
</details>
This PR:
```text
error: expected identifier, found keyword `fn`
--> ./t.rs:1:15
|
1 | fn _f(_: impl fn()) {}
| ^^ expected identifier, found keyword
|
help: escape `fn` to use it as an identifier
|
1 | fn _f(_: impl r#fn()) {}
| ++
error[E0405]: cannot find trait `r#fn` in this scope
--> ./t.rs:1:15
|
1 | fn _f(_: impl fn()) {}
| ^^ help: a trait with a similar name exists (notice the capitalization): `Fn`
|
::: /home/waffle/projects/repos/rust/library/core/src/ops/function.rs:74:1
|
74 | pub trait Fn<Args>: FnMut<Args> {
| ------------------------------- similarly named trait `Fn` defined here
```
It would be nice to have suggestion in the first error like "have you meant `Fn` trait", instead of a separate error, but the recovery is deep inside ident parsing, which makes it a lot harder to do.
r? `@compiler-errors`
Reenable disabled early syntax gates as future-incompatibility lints
- MCP: https://github.com/rust-lang/compiler-team/issues/535
The approach taken by this PR is
- Introduce a new lint, `unstable_syntax_pre_expansion`, and reenable the early syntax gates to emit it
- Use the diagnostic stashing mechanism to stash warnings the early warnings
- When the hard error occurs post expansion, steal and cancel the early warning
- Don't display any stashed warnings if errors are present to avoid the same noise problem that hiding type ascription errors is avoiding
Commits are working commits, but in a coherent steps-to-implement manner. Can be squashed if desired.
The preexisting `soft_unstable` lint seems like it would've been a good fit, but it is deny-by-default (appropriate for `#[bench]`) and these gates should be introduced as warn-by-default.
It may be desirable to change the stash mechanism's behavior to not flush lint errors in the presence of other errors either (like is done for warnings here), but upgrading a stash-using lint from warn to error perhaps is enough of a request to see the lint that they shouldn't be hidden; additionally, fixing the last error to get new errors thrown at you always feels bad, so if we know the lint errors are present, we should show them.
Using a new flag/mechanism for a "weak diagnostic" which is suppressed by other errors may also be desirable over assuming any stashed warnings are "weak," but this is the first user of stashing warnings and seems an appropriate use of stashing (it follows the "know more later to refine the diagnostic" pattern; here we learn that it's in a compiled position) so we get to define what it means to stash a non-hard-error diagnostic.
cc `````@petrochenkov````` (seconded MCP)
Improve diagnostics for `const a: = expr;`
Adds a suggestion to write a type when there is a colon, but the type is not present.
I've also shrunk spans a little, so the suggestions are a little nicer.
Resolves#100146
r? `@compiler-errors`
Warn about dead tuple struct fields
Continuation of #92972. Fixes#92790.
The language team has already commented on this in https://github.com/rust-lang/rust/pull/92972#issuecomment-1021511970; I have incorporated their requests here. Specifically, there is now a new allow-by-default `unused_tuple_struct_fields` lint (name bikesheddable), and fields of unit type are ignored (https://github.com/rust-lang/rust/pull/92972#issuecomment-1021815408), so error messages look like this:
```
error: field is never read: `1`
--> $DIR/tuple-struct-field.rs:6:21
|
LL | struct Wrapper(i32, [u8; LEN], String);
| ^^^^^^^^^
|
help: change the field to unit type to suppress this warning while preserving the field numbering
|
LL | struct Wrapper(i32, (), String);
| ~~
```
r? `@joshtriplett`
Add diagnostic when using public instead of pub
Forwarding from https://github.com/rust-lang/rust/pull/99706
I accidentally broke something(??) in git and the commits in that PR are absolutely not what I did in that branch
Anyways, this is the PR for this now. Adding tests again in a minute.
cc `@davidtwco`