`ast::Item` has an `ident` field.
- It's always non-empty for these item kinds: `ExternCrate`, `Static`,
`Const`, `Fn`, `Mod`, `TyAlias`, `Enum`, `Struct`, `Union`,
`Trait`, `TraitAlias`, `MacroDef`, `Delegation`.
- It's always empty for these item kinds: `Use`, `ForeignMod`,
`GlobalAsm`, `Impl`, `MacCall`, `DelegationMac`.
There is a similar story for `AssocItemKind` and `ForeignItemKind`.
Some sites that handle items check for an empty ident, some don't. This
is a very C-like way of doing things, but this is Rust, we have sum
types, we can do this properly and never forget to check for the
exceptional case and never YOLO possibly empty identifiers (or possibly
dummy spans) around and hope that things will work out.
The commit is large but it's mostly obvious plumbing work. Some notable
things.
- `ast::Item` got 8 bytes bigger. This could be avoided by boxing the
fields within some of the `ast::ItemKind` variants (specifically:
`Struct`, `Union`, `Enum`). I might do that in a follow-up; this
commit is big enough already.
- For the visitors: `FnKind` no longer needs an `ident` field because
the `Fn` within how has one.
- In the parser, the `ItemInfo` typedef is no longer needed. It was used
in various places to return an `Ident` alongside an `ItemKind`, but
now the `Ident` (if present) is within the `ItemKind`.
- In a few places I renamed identifier variables called `name` (or
`foo_name`) as `ident` (or `foo_ident`), to better match the type, and
because `name` is normally used for `Symbol`s. It's confusing to see
something like `foo_name.name`.
`expand_test_case` looks for any item with a `#[test_case]` attribute
and adds a `test_path_symbol` attribute to it while also fiddling with
the item's ident's span.
This is pretty weird, because `#[test_case]` is only valid on
`fn`/`const`/`static` items, as far as I can tell. But you don't
currently get an error or warning if you use it on other kinds of items.
This commit changes things so that a `#[test_case]` item is modified
only if it is `fn`/`const`/`static`. This is relevant for moving idents
from `Item` to `ItemKind`, because some item kinds don't have an ident,
e.g. `impl` blocks.
The commit also does the following.
- Renames a local variable `test_id` as `test_ident`.
- Changes a `const` to `static` in
`tests/ui/custom_test_frameworks/full.rs` to give the `static` case
some test coverage.
- Adds a `struct` and `impl` to the same test to give some test coverage
to the non-affected item kinds. These have a `FIXME` comment
identifying the weirdness here. Hopefully this will be useful
breadcrumbs for somebody else in the future.
`rustc_span::symbol` defines some things that are re-exported from
`rustc_span`, such as `Symbol` and `sym`. But it doesn't re-export some
closely related things such as `Ident` and `kw`. So you can do `use
rustc_span::{Symbol, sym}` but you have to do `use
rustc_span::symbol::{Ident, kw}`, which is inconsistent for no good
reason.
This commit re-exports `Ident`, `kw`, and `MacroRulesNormalizedIdent`,
and changes many `rustc_span::symbol::` qualifiers in `compiler/` to
`rustc_span::`. This is a 200+ net line of code reduction, mostly
because many files with two `use rustc_span` items can be reduced to
one.
Since #130025, the compiler don't ignore missing_docs when compiling the tests.
But there is now a false positive warning for every `#[test]`
For example, this code
```rust
//! Crate docs
fn just_a_test() {}
```
Would emit this warning when running `cargo test`
```
warning: missing documentation for a constant
--> src/lib.rs:5:1
|
4 | #[test]
| ------- in this procedural macro expansion
5 | fn just_a_test() {}
| ^^^^^^^^^^^^^^^^^^^
```
This makes their intent and expected location clearer. We see some
examples where these comments were not clearly separate from `use`
declarations, which made it hard to understand what the comment is
describing.
warning: this argument is a mutable reference, but not used mutably
--> compiler\rustc_builtin_macros\src\asm.rs:306:28
|
306 | fn err_duplicate_option(p: &mut Parser<'_>, symbol: Symbol, span: Span) {
| ^^^^^^^^^^^^^^^ help: consider changing to: `&Parser<'_>`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut
warning: this argument is a mutable reference, but not used mutably
--> compiler\rustc_builtin_macros\src\asm.rs:318:8
|
318 | p: &mut Parser<'a>,
| ^^^^^^^^^^^^^^^ help: consider changing to: `&Parser<'a>`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut
warning: this argument is a mutable reference, but not used mutably
--> compiler\rustc_builtin_macros\src\assert.rs:114:25
|
114 | fn parse_assert<'a>(cx: &mut ExtCtxt<'a>, sp: Span, stream: TokenStream) -> PResult<'a, Assert> {
| ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'a>`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut
warning: this argument is a mutable reference, but not used mutably
--> compiler\rustc_builtin_macros\src\asm.rs:32:10
|
32 | ecx: &mut ExtCtxt<'a>,
| ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'a>`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut
warning: this argument is a mutable reference, but not used mutably
--> compiler\rustc_builtin_macros\src\test.rs:99:9
|
99 | cx: &mut ExtCtxt<'_>,
| ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut
warning: this argument is a mutable reference, but not used mutably
--> compiler\rustc_builtin_macros\src\source_util.rs:237:9
|
237 | cx: &mut ExtCtxt<'_>,
| ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut
warning: this argument is a mutable reference, but not used mutably
--> compiler\rustc_builtin_macros\src\format.rs:809:10
|
809 | ecx: &mut ExtCtxt<'_>,
| ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut
warning: this argument is a mutable reference, but not used mutably
--> compiler\rustc_builtin_macros\src\format.rs:737:10
|
737 | ecx: &mut ExtCtxt<'a>,
| ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'a>`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut
warning: this argument is a mutable reference, but not used mutably
--> compiler\rustc_builtin_macros\src\format.rs:68:24
|
68 | fn parse_args<'a>(ecx: &mut ExtCtxt<'a>, sp: Span, tts: TokenStream) -> PResult<'a, MacroInput> {
| ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'a>`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut
warning: this argument is a mutable reference, but not used mutably
--> compiler\rustc_builtin_macros\src\format.rs:607:10
|
607 | ecx: &mut ExtCtxt<'_>,
| ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut
warning: this argument is a mutable reference, but not used mutably
--> compiler\rustc_builtin_macros\src\edition_panic.rs:43:9
|
43 | cx: &'cx mut ExtCtxt<'_>,
| ^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut
warning: this argument is a mutable reference, but not used mutably
--> compiler\rustc_builtin_macros\src\concat_bytes.rs:11:9
|
11 | cx: &mut ExtCtxt<'_>,
| ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut
warning: this argument is a mutable reference, but not used mutably
--> compiler\rustc_builtin_macros\src\cfg.rs:38:22
|
38 | fn parse_cfg<'a>(cx: &mut ExtCtxt<'a>, span: Span, tts: TokenStream) -> PResult<'a, ast::MetaItem> {
| ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'a>`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut
warning: this argument is a mutable reference, but not used mutably
--> compiler\rustc_builtin_macros\src\cfg_accessible.rs:13:28
|
13 | fn validate_input<'a>(ecx: &mut ExtCtxt<'_>, mi: &'a ast::MetaItem) -> Option<&'a ast::Path> {
| ^^^^^^^^^^^^^^^^ help: consider changing to: `&ExtCtxt<'_>`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut
`is_force_warn` is only possible for diagnostics with `Level::Warning`,
but it is currently stored in `Diagnostic::code`, which every diagnostic
has.
This commit:
- removes the boolean `DiagnosticId::Lint::is_force_warn` field;
- adds a `ForceWarning` variant to `Level`.
Benefits:
- The common `Level::Warning` case now has no arguments, replacing
lots of `Warning(None)` occurrences.
- `rustc_session::lint::Level` and `rustc_errors::Level` are more
similar, both having `ForceWarning` and `Warning`.
In #119606 I added them and used a `_mv` suffix, but that wasn't great.
A `with_` prefix has three different existing uses.
- Constructors, e.g. `Vec::with_capacity`.
- Wrappers that provide an environment to execute some code, e.g.
`with_session_globals`.
- Consuming chaining methods, e.g. `Span::with_{lo,hi,ctxt}`.
The third case is exactly what we want, so this commit changes
`DiagnosticBuilder::foo_mv` to `DiagnosticBuilder::with_foo`.
Thanks to @compiler-errors for the suggestion.
This works for most of its call sites. This is nice, because `emit` very
much makes sense as a consuming operation -- indeed,
`DiagnosticBuilderState` exists to ensure no diagnostic is emitted
twice, but it uses runtime checks.
For the small number of call sites where a consuming emit doesn't work,
the commit adds `DiagnosticBuilder::emit_without_consuming`. (This will
be removed in subsequent commits.)
Likewise, `emit_unless` becomes consuming. And `delay_as_bug` becomes
consuming, while `delay_as_bug_without_consuming` is added (which will
also be removed in subsequent commits.)
All this requires significant changes to `DiagnosticBuilder`'s chaining
methods. Currently `DiagnosticBuilder` method chaining uses a
non-consuming `&mut self -> &mut Self` style, which allows chaining to
be used when the chain ends in `emit()`, like so:
```
struct_err(msg).span(span).emit();
```
But it doesn't work when producing a `DiagnosticBuilder` value,
requiring this:
```
let mut err = self.struct_err(msg);
err.span(span);
err
```
This style of chaining won't work with consuming `emit` though. For
that, we need to use to a `self -> Self` style. That also would allow
`DiagnosticBuilder` production to be chained, e.g.:
```
self.struct_err(msg).span(span)
```
However, removing the `&mut self -> &mut Self` style would require that
individual modifications of a `DiagnosticBuilder` go from this:
```
err.span(span);
```
to this:
```
err = err.span(span);
```
There are *many* such places. I have a high tolerance for tedious
refactorings, but even I gave up after a long time trying to convert
them all.
Instead, this commit has it both ways: the existing `&mut self -> Self`
chaining methods are kept, and new `self -> Self` chaining methods are
added, all of which have a `_mv` suffix (short for "move"). Changes to
the existing `forward!` macro lets this happen with very little
additional boilerplate code. I chose to add the suffix to the new
chaining methods rather than the existing ones, because the number of
changes required is much smaller that way.
This doubled chainging is a bit clumsy, but I think it is worthwhile
because it allows a *lot* of good things to subsequently happen. In this
commit, there are many `mut` qualifiers removed in places where
diagnostics are emitted without being modified. In subsequent commits:
- chaining can be used more, making the code more concise;
- more use of chaining also permits the removal of redundant diagnostic
APIs like `struct_err_with_code`, which can be replaced easily with
`struct_err` + `code_mv`;
- `emit_without_diagnostic` can be removed, which simplifies a lot of
machinery, removing the need for `DiagnosticBuilderState`.
Because it's redundant w.r.t. `Diagnostic::is_lint`, which is present
for every diagnostic level.
`struct_lint_level_impl` was the only place that set the `Error` field
to `true`, and it's also the only place that calls
`Diagnostic::is_lint()` to set the `is_lint` field.
`Diagnostic` has 40 methods that return `&mut Self` and could be
considered setters. Four of them have a `set_` prefix. This doesn't seem
necessary for a type that implements the builder pattern. This commit
removes the `set_` prefixes on those four methods.
There are only three. It's simpler to make the type
`DiagnosticBuilder<'_, ()>` from the start, no matter the level, than to
change the guarantee later.
fix: fix ICE in `custom-test-frameworks` feature
Fixes#107454
Simple fix to emit error instead of ICEing. At some point, all the code in `tests.rs` should be refactored, there is a bit of duplication (this PR's code is repeated five times over lol).
r? `@Nilstrieb` (active on the linked issue?)