Change `span_suggestion` (and variants) to take `impl ToString` rather
than `String` for the suggested code, as this simplifies the
requirements on the diagnostic derive.
Signed-off-by: David Wood <david.wood@huawei.com>
By heap allocating the argument within `NtPath`, `NtVis`, and `NtStmt`.
This slightly reduces cumulative and peak allocation amounts, most
notably on `deep-vector`.
This commit updates the signatures of all diagnostic functions to accept
types that can be converted into a `DiagnosticMessage`. This enables
existing diagnostic calls to continue to work as before and Fluent
identifiers to be provided. The `SessionDiagnostic` derive just
generates normal diagnostic calls, so these APIs had to be modified to
accept Fluent identifiers.
In addition, loading of the "fallback" Fluent bundle, which contains the
built-in English messages, has been implemented.
Each diagnostic now has "arguments" which correspond to variables in the
Fluent messages (necessary to render a Fluent message) but no API for
adding arguments has been added yet. Therefore, diagnostics (that do not
require interpolation) can be converted to use Fluent identifiers and
will be output as before.
Suggest `i += 1` when we see `i++` or `++i`
Closes#83502 (for `i++` and `++i`; `--i` should be covered by #82987, and `i--`
is tricky to handle).
This is a continuation of #83536.
r? `@estebank`
* Recover from invalid `'label: ` before block.
* Make suggestion to enclose statements in a block multipart.
* Point at `match`, `while`, `loop` and `unsafe` keywords when failing
to parse their expression.
* Do not suggest `{ ; }`.
* Do not suggest `|` when very unlikely to be what was wanted (in `let`
statements).
fix ICE when parsing lifetime as function argument
I don't really like this, but we basically need to emit an error instead of just delaying an bug, because there are too many places in the AST that aren't covered by my previous PRs...
cc: https://github.com/rust-lang/rust/issues/93282#issuecomment-1028052945
Fix suggesting turbofish with lifetime arguments
Now we suggest turbofish correctly given exprs like `foo<'_>`.
Also fix suggestion when we have `let x = foo<bar, baz>;` which was broken.
Swift has specific syntax that desugars to `Option<T>` similar to our
`?` operator, which means that people might try to use it in Rust. Parse
it and gracefully recover.
Remove `SymbolStr`
This was originally proposed in https://github.com/rust-lang/rust/pull/74554#discussion_r466203544. As well as removing the icky `SymbolStr` type, it allows the removal of a lot of `&` and `*` occurrences.
Best reviewed one commit at a time.
r? `@oli-obk`
By changing `as_str()` to take `&self` instead of `self`, we can just
return `&str`. We're still lying about lifetimes, but it's a smaller lie
than before, where `SymbolStr` contained a (fake) `&'static str`!
Recover on invalid operators `<>` and `<=>`
Thanks to #89871 for showing me how to do this.
Next, I think it'd be nice to recover on `<=>` too, like #89871 intended, if this even works.
"Fix" an overflow in byte position math
r? `@estebank`
help! I fixed the ICE only to brick the diagnostic.
I mean, it was wrong previously (using an already expanded macro span), but it is really bad now XD
Newcomers may write `{1, 2, 3}` for making arrays, and the current error
message is not informative enough to quickly convince them what is
needed to fix the error.
This PR implements a diagnostic for this case, and its output looks like
this:
```text
error: this code is interpreted as a block expression, not an array
--> src/lib.rs:1:22
|
1 | const FOO: [u8; 3] = {
| ______________________^
2 | | 1, 2, 3
3 | | };
| |_^
|
= note: to define an array, one would use square brackets instead of curly braces
help: try using [] instead of {}
|
1 | const FOO: [u8; 3] = [
2 | 1, 2, 3
3 | ];
|
```
Fix#87672
Recover from `Foo(a: 1, b: 2)`
Detect likely `struct` literal using parentheses as delimiters and emit
targeted suggestion instead of type ascription parse error.
Fix#61326.
This commit focuses on emitting clean errors for the following syntax
error:
```
Some(42).map(|a|
dbg!(a);
a
);
```
Previous implementation tried to recover after parsing the closure body
(the `dbg` expression) by replacing the next `;` with a `,`, which made
the next expression belong to the next function argument. As such, the
following errors were emitted (among others):
- the semicolon token was not expected,
- a is not in scope,
- Option::map is supposed to take one argument, not two.
This commit allows us to gracefully handle this situation by adding
giving the parser the ability to remember when it has just parsed a
closure body inside a function call. When this happens, we can treat the
unexpected `;` specifically and try to parse as much statements as
possible in order to eat the whole block. When we can't parse statements
anymore, we generate a clean error indicating that the braces are
missing, and return an ExprKind::Err.
Improve diagnostics for unary plus operators (#88276)
This pull request improves the diagnostics emitted on parsing a unary plus operator. See #88276.
Before:
```
error: expected expression, found `+`
--> src/main.rs:2:13
|
2 | let x = +1;
| ^ expected expression
```
After:
```
error: leading `+` is not supported
--> main.rs:2:13
|
2 | let x = +1;
| ^
| |
| unexpected `+`
| help: try removing the `+`
```
Old error output:
3 | let _: usize = $f;
| ----- ^ expected `usize`, found struct `Baz`
| |
| expected due to this
New error output:
3 | let _: usize = $f;
| ----- ^^ expected `usize`, found struct `Baz`
| |
| expected due to this
Old error output:
= note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
help: wrap this expression in parentheses
|
4 | break '_l $f(;)
| ^ ^
New error output:
= note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
help: wrap this expression in parentheses
|
4 | break '_l ($f);
| ^ ^
Add diagnostics for mistyped inclusive range
Inclusive ranges are correctly typed as `..=`. However, it's quite easy to think of it as being like `==`, and type `..==` instead. This PR adds helpful diagnostics for this case.
Resolves#86395 (there are some other cases there, but I think those should probably have separate issues).
r? `@estebank`
Re-add support for parsing (and pretty-printing) inner-attributes in match body
Re-add support for parsing (and pretty-printing) inner-attributes within body of a `match`.
In other words, we can do `match EXPR { #![inner_attr] ARM_1 ARM_2 ... }` again.
I believe this unbreaks the only four crates that crater flagged as broken by PR #83312.
(I am putting this up so that the lang-team can check it out and decide whether it changes their mind about what to do regarding PR #83312.)
In other words, we can do `match EXPR { #![inner_attr] ARM_1 ARM_2 ... }` again.
I believe this unbreaks the only four crates that crater flagged as broken by PR 83312.
(I am putting this up so that the lang-team can check it out and decide whether
it changes their mind about what to do regarding PR 83312.)
This PR modifies the macro expansion infrastructure to handle attributes
in a fully token-based manner. As a result:
* Derives macros no longer lose spans when their input is modified
by eager cfg-expansion. This is accomplished by performing eager
cfg-expansion on the token stream that we pass to the derive
proc-macro
* Inner attributes now preserve spans in all cases, including when we
have multiple inner attributes in a row.
This is accomplished through the following changes:
* New structs `AttrAnnotatedTokenStream` and `AttrAnnotatedTokenTree` are introduced.
These are very similar to a normal `TokenTree`, but they also track
the position of attributes and attribute targets within the stream.
They are built when we collect tokens during parsing.
An `AttrAnnotatedTokenStream` is converted to a regular `TokenStream` when
we invoke a macro.
* Token capturing and `LazyTokenStream` are modified to work with
`AttrAnnotatedTokenStream`. A new `ReplaceRange` type is introduced, which
is created during the parsing of a nested AST node to make the 'outer'
AST node aware of the attributes and attribute target stored deeper in the token stream.
* When we need to perform eager cfg-expansion (either due to `#[derive]` or `#[cfg_eval]`),
we tokenize and reparse our target, capturing additional information about the locations of
`#[cfg]` and `#[cfg_attr]` attributes at any depth within the target.
This is a performance optimization, allowing us to perform less work
in the typical case where captured tokens never have eager cfg-expansion run.
StructField -> FieldDef ("field definition")
Field -> ExprField ("expression field", not "field expression")
FieldPat -> PatField ("pattern field", not "field pattern")
Also rename visiting and other methods working on them.