Currently, the rustc_macros::symbols macro generates two
`macro_rules!` macros as its output. These two macros are
used in rustc_span/src/symbol.rs.
This means that each Symbol that we define is represented
in the AST of rustc_symbols twice: once in the definition
of the `define_symbols!` macro (similarly for the
`keywords! macro), and once in the rustc_span::symbols
definition.
That would be OK if there were only a handful of symbols,
but currently we define over 1100 symbols. The definition
of the `define_symbols!` macro contains the expanded definition
of each symbol, so that's a lot of AST storage wasted on a
macro that is used exactly once.
This commit removes the `define_symbols` macro, and simply
allows the proc macro to directly generate the
`rustc_symbols::symbol::sym` module.
The benefit is mainly in reducing memory wasted during
compilation of rustc itself. It should also reduce memory used
by Rust Analyzer.
This commit also reduces the size of the AST for symbol
definitions, by moving two `#[allow(...)]` attributes from
the symbol constants to the `sym` module. This eliminates 2200+
attribute nodes.
This commit also eliminates the need for the `digits_array`
constant. There's no need to store an array of Symbol values
for digits. We can simply define a constant of the base value,
and add to that base value.
This improves how the `symbols` proc-macro handles errors.
If it finds an error in its input, the macro does not panic.
Instead, it still produces an output token stream. That token
stream will contain `compile_error!(...)` macro invocations.
This will still cause compilation to fail (which is what we want),
but it will prevent meaningless errors caused by the output not
containing symbols that the macro normally generates.
This solves a small (but annoying) problem. When you're editing
rustc_span/src/symbol.rs, and you get something wrong (dup
symbol name, misordered symbol), you want to get only the errors
that are relevant, not a burst of errors that are irrelevant.
This change also uses the correct Span when reporting errors,
so you get errors that point to the correct place in
rustc_span/src/symbol.rs where something is wrong.
This also adds several unit tests which test the `symbols` proc-macro.
This commit also makes it easy to run the `symbols` proc-macro
as an ordinary Cargo test. Just run `cargo test`. This makes it
easier to do development on the macro itself, such as running it
under a debugger.
This commit also uses the `Punctuated` type in `syn` for parsing
comma-separated lists, rather than doing it manually.
The output of the macro is not changed at all by this commit,
so rustc should be completely unchanged. This just improves
quality of life during development.
Introduce `TypeVisitor::BreakTy`
Implements MCP rust-lang/compiler-team#383.
r? `@ghost`
cc `@lcnr` `@oli-obk`
~~Blocked on FCP in rust-lang/compiler-team#383.~~
Add derive macro for specifying diagnostics using attributes.
Introduces `#[derive(SessionDiagnostic)]`, a derive macro for specifying structs that can be converted to Diagnostics using directions given by attributes on the struct and its fields. Currently, the following attributes have been implemented:
- `#[code = "..."]` -- this sets the Diagnostic's error code, and must be provided on the struct iself (ie, not on a field). Equivalent to calling `code`.
- `#[message = "..."]` -- this sets the Diagnostic's primary error message.
- `#[label = "..."]` -- this must be applied to fields of type `Span`, and is equivalent to `span_label`
- `#[suggestion(..)]` -- this allows a suggestion message to be supplied. This attribute must be applied to a field of type `Span` or `(Span, Applicability)`, and is equivalent to calling `span_suggestion`. Valid arguments are:
- `message = "..."` -- this sets the suggestion message.
- (Optional) `code = "..."` -- this suggests code for the suggestion. Defaults to empty.
`suggestion`also comes with other variants: `#[suggestion_short(..)]`, `#[suggestion_hidden(..)]` and `#[suggestion_verbose(..)]` which all take the same keys.
Within the strings passed to each attribute, fields can be referenced without needing to be passed explicitly into the format string -- eg, `#[error = "{ident} already declared"] ` will set the error message to `format!("{} already declared", &self.ident)`. Any fields on the struct can be referenced in this way.
Additionally, for any of these attributes, Option fields can be used to only optionally apply the decoration -- for example:
```rust
#[derive(SessionDiagnostic)]
#[code = "E0123"]
struct SomeKindOfError {
...
#[suggestion(message = "informative error message")]
opt_sugg: Option<(Span, Applicability)>
...
}
```
will not emit a suggestion if `opt_sugg` is `None`.
We plan on iterating on this macro further; this PR is a start.
Closes#61132.
r? `@oli-obk`
If a symbol name can only be imported from one place for a type, and
as long as it was not glob-imported anywhere in the current crate, we
can trim its printed path and print only the name.
This has wide implications on error messages with types, for example,
shortening `std::vec::Vec` to just `Vec`, as long as there is no other
`Vec` importable anywhere.
This adds a new '-Z trim-diagnostic-paths=false' option to control this
feature.
On the good path, with no diagnosis printed, we should try to avoid
issuing this query, so we need to prevent trimmed_def_paths query on
several cases.
This change also relies on a previous commit that differentiates
between `Debug` and `Display` on various rustc types, where the latter
is trimmed and presented to the user and the former is not.