Lint level cleanups
Some naming improvements, some type safety improvements, and some simplifications. Details in individual commits.
r? @GuillaumeGomez
Hand-written Debug implementation for `TypeTest`
This adds a hand-written debug format for `TypeTest`s that at least was helpful for me when debugging because I always struggle to remember which component is which. It formats a type test using the Unicode turnstile symbol (for "computes") to illustrate that the test encodes a typing rule that, if it holds, produces a conclusion.
The format is: `TypeTest from {originating span} {bound} ⊢ T: 'lower_bound`, where `T` is the generic type being tested and `lower_bound` is the lower bound. Bounds are formatted as you would expect, but where the region for `'lower_bound` is included in the outlives constraints for context. I resisted the urge to turn `ALL [A, ..., Z]` into `[A ∧ ... ∧ Z]` etc.
## What it looks like
Here's an example of a simple type test from the test suite that says that some type `I/#0` will be lower-bounded (outlive) `?4` iff `'?1: '?4`:
Before:
```
$ RUSTC_LOG="rustc_borrowck::region_infer=debug" rustc +stage1 tests/ui/associated-types/associated-types-eq-3.rs
...
DEBUG rustc_borrowck::region_infer type tests: [
TypeTest {
generic_kind: I/#0,
lower_bound: '?4,
span: tests/ui/associated-types/associated-types-eq-3.rs:21:18: 21:25 (#0),
verify_bound: OutlivedBy(
'?1,
),
},
TypeTest {
generic_kind: I/#0,
lower_bound: '?4,
span: tests/ui/associated-types/associated-types-eq-3.rs:21:18: 21:25 (#0),
verify_bound: OutlivedBy(
'?1,
),
},
]
...
```
After:
```
$ RUSTC_LOG="rustc_borrowck::region_infer=debug" rustc +stage1 tests/ui/associated-types/associated-types-eq-3.rs
...
DEBUG rustc_borrowck::region_infer type tests: [
TypeTest from tests/ui/associated-types/associated-types-eq-3.rs:21:18: 21:25 (#0)['?1: '?4] ⊢ I/#0: '?4,
TypeTest from tests/ui/associated-types/associated-types-eq-3.rs:21:18: 21:25 (#0)['?1: '?4] ⊢ I/#0: '?4,
]
...
```
feat(rustdoc): stabilize `--emit` flag
### [---> FCP <---](https://github.com/rust-lang/rust/pull/146220#issuecomment-3740447985)
## Stabilization Report: `rustdoc --emit`
**Feature:** `rustdoc --emit`
**Tracking issue:** rust-lang/rust#83784
**Stabilization PR:** rust-lang/rust#146220
### What we are stabilizing
This stabilizes the `rustdoc --emit` flag, which controls what types of output rustdoc produces. The flag accepts a comma-separated list of the following emit types:
- `html-static-files` --- Shared static files with content-hashed filenames for safe caching.
- `html-non-static-files` --- Per-crate documentation files with deterministic filenames.
- `dep-info[=<path>]` --- A Makefile-compatible `.d` file listing all source files loaded during documentation generation. Same as rustc's dep-info files.
When `--emit` is not specified, the default behavior is `--emit=html-static-files,html-non-static-files` (i.e., full HTML documentation output, no dep-info).
### What we are not stabilizing
* Interaction between other unstable options, such as `-Zrustdoc-mergeable-info` and `--output-format=doctest`
* Available options and the default options when `--emit` not specified.
* Extension of per-type emit paths for options currently missing that.
### Motivation
#### Cargo
The primary consumer is Cargo, which needs `--emit=dep-info=<path>` to precisely track the input dependencies of a rustdoc invocation (see the [`-Zrustdoc-depinfo`] unstable Cargo feature). Without dep-info, Cargo cannot detect changes to files pulled in via `#[path = "..."]` or similar mechanisms and leads to stale documentation in incremental builds.
Cargo also uses the selective emission mechanism (`html-static-files` / `html-non-static-files`) when the unstable [`-Zrustdoc-mergeable-info`] feature is active. It skips writing shared static files and search index during per-crate doc generation and defer them to a final merge phase.
Under stable usage, Cargo passes all three emit types together.
#### docs.rs
docs.rs is the other major consumer. It uses selective emission to avoid redundantly copying toolchain-wide static files for every crate, which has historically been a source of breakage. See the tracking rust-lang/rust#83784 and the about page for more <https://docs.rs/about/download>.
### Tests
- `tests/run-make/emit-shared-files` --- Verifies selective emission of static vs non-static files.
- `tests/run-make/rustdoc-dep-info` --- Verifies dep-info generation, including explicit path and `--out-dir` interaction.
- `tests/run-make/rustdoc-scrape-examples-dep-info` --- Verifies dep-info works with scrape-examples.
- `tests/run-make/rustdoc-default-output/` --- Verifies `--help` output shows `[html-static-files,html-non-static-files,dep-info]`
[`-Zrustdoc-depinfo`]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#rustdoc-depinfo
[`-Zrustdoc-mergeable-info`]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#rustdoc-mergeable-info
`LevelSpec` has two related fields, `level` and `lint_id`. This commit
makes the fields private (and introduces getters) to ensure they are set
together using only valid combinations.
The commit also introduces `is_allow` and `is_expect` methods because
those are useful.
These methods return `Option<(Self, Option<LintExpectationId>)>`. But
all the call sites except one don't look at the
`Option<LintExpectationId>`.
This commit simplifies these methods to not return the
`Option<LintExpectationId>`. This means they no longer need to be passed
a closure to compute an `AttrId` (which is usually discarded anyway).
The commit also renames `from_attr` as `from_opt_symbol`, because it
takes an `Option<Symbol>`, not an `Attribute`.
These changes simplify all the call sites that don't need the
`Option<LintExpectationId>`, and also the one call site that does (in
`LintLevelsBuilder::add`): that call site no longer needs to do an
awkward destructuring, and can instead build the appropriate
`LintExpectationId` directly.
Rollup of 2 pull requests
Successful merges:
- rust-lang/rust#156450 (compiletest: Enforce that directives are consistently used with or without a colon)
- rust-lang/rust#156531 (compiletest: Rename `//@ ignore-pass` to `//@ no-pass-override`)
compiletest: Rename `//@ ignore-pass` to `//@ no-pass-override`
By convention, compiletest directives starting with `ignore-*` normally cause the test itself to be skipped under certain conditions.
The `//@ ignore-pass` directive was the only exception to that convention. The new name should hopefully do a better job of communicating its effect, which is to cause the `--pass` flag to not override the test's `build-pass` or `run-pass` directive.
The `//@ no-pass-override` directive is mainly useful for tests that expect warnings produced during codegen.
---
r? jieyouxu
compiletest: Enforce that directives are consistently used with or without a colon
With the notable exception of `//@ pp-exact`, all directives expect to either always be used *with* a colon, or always be used *without* a colon. For example:
- `//@ uses-colon: value`
- `//@ no-colon` or `//@ no-colon (remark)`
Currently we just silently discard directives that use the wrong syntax, which is not great.
This PR therefore makes `parse_name_directive` and `parse_name_value_directive` panic if the wrong syntax is encountered.
The parser for `pp-exact` has been adjusted to check for the colon before deciding which parse method to call.
r? jieyouxu
The name is misleading because the field contains a `Level` *and* an
`Option<LintExpectationId>`. This commit renames it `level_plus` which
better communicates that it's more than just a level.
It is misnamed, given that it has three fields: `level`, `lint_id`, and
`src`. (Presumably the `lint_id` was added later.)
This commit renames it as `LevelSpec`. (I also considered `LevelInfo`
but that's very generic. `Spec` has pre-existing uses in
`LintLevelsProvider::current_specs` and `LintSet::specs` and
`ShallowLintLevelMap::specs`.)
Related things renamed as well:
- `level` -> `level_spec` (where appropriate)
- `lint_levels` -> `lint_level_specs`
- `get_lint_level` -> `get_lint_level_spec`
- `level_and_source` -> `level_spec`
- `CodegenLintLevels` -> `CodegenLintLevelSpecs`
- `raw_lint_id_level` -> `raw_lint_level_spec`
- `lint_level_at_node` -> `lint_level_spec_at_node`
- `reveal_actual_level` -> `reveal_actual_level_spec`
- `probe_for_lint_level` -> `probe_for_lint_level_spec`
This clears up a lot of `Level` vs. `LevelSpec` ambiguity. E.g. no more
`level.level` expressions.
test: suppress deprecation warning
The newer mac os ld linker emits a deprecation warning:
```
warning: linker stderr: ld: -ld_classic is deprecated and will be removed in a future release
|
= note: `#[warn(linker_messages)]` on by default
```
Privacy: move macros handling to early stage
The patch moves effective visibility computation for macros from `rustc_privacy` to `rustc_resolve`. It will enable this optimization: https://github.com/rust-lang/rust/pull/156228.
However, I found some problems with macro handling while I was doing this. The current implementation was written ~6 years ago and checks the reachability of a definition from a macro by nominal visibility. In general this is incorrect.
For example, in the current implementation modules are not traversed if their nominal visibility is less then the nominal visibility of a module defining macro: https://github.com/rust-lang/rust/blob/29b7590130c83542a095cdf1323ed0f78eec2bb8/compiler/rustc_privacy/src/lib.rs#L618-L626
As a result, in order to compile code like `tests/ui/definition-reachable/auxiliary/field-method-macro.rs`. we have to additionally traverse types of adt fields: https://github.com/rust-lang/rust/blob/29b7590130c83542a095cdf1323ed0f78eec2bb8/compiler/rustc_privacy/src/lib.rs#L628-L638
This is a hack and the proper solution would be to check definitions with `EffectiveVisibilities::is_reachable`. I haven’t done this yet, as it would start to trigger many lints as more items become reachable. I think it’s better to leave the change to another commit.
r? @petrochenkov
Do not index past end of buffer when checking heuristic in error index syntax highlighter
When checking whether the current token is a function indentifier by inspecting the syntax, do not attempt to access past the end of the code buffer.
Fixrust-lang/rust#156326.
Clippy subtree update
r? Manishearth
`Cargo.lock` update due to patch version bump in `ui_test`.
One day early, as I won't have access to my laptop from tomorrow till Sunday
Split the node_id_to_def_id table into a per-owner table
*[View all comments](https://triagebot.infra.rust-lang.org/gh-comments/rust-lang/rust/pull/138995)*
My goal is to split all the resolver tables that get passed to act lowering into per-owner tables, so that all information that ast lowering needs from the resolver is separated by owners. This should allow us to fully split ast lowering to have one query invocation per owner that steal the individual resolver results for each owner.
part of https://github.com/rust-lang/rust-project-goals/issues/620
Fix unused assignments in diverging branches
Fixesrust-lang/rust#156416
Add `location` and use `is_predecessor_of` to check in the control flow graph.
r? @ghost
I'd like to see whether there is performence regression.
Add Swift function call ABI
Adds an unstable `extern "Swift"` ABI behind the `abi_swift` feature gate, mapping to LLVM's `swiftcc` calling convention. This is only allowed (a) for `is_darwin_like` targets, since the [ABI is only stable for those platforms](https://www.swift.org/blog/abi-stability-and-more/) and (b) with the LLVM backend, since the other backends don't support it.
Current approaches to interoperability with Swift lower to Objective-C (or require a Swift stub exposing a C ABI), but that is an optional mapping on the Swift side that some newer Apple frameworks omit. It would be great to be able to more directly/natively be able to call into Swift code directly via its stable API (on Apple platforms at least).
Reimplements rust-lang/rust#64582 on top of current main. The main objection to the previous PR seemed to be that it needed an RFC, but there was pushback (which seems sensible to me) that an RFC could be deferred until stabilization.
I think this needs a tracking issue? Would be happy to write one up if/when there is a consensus that this will be merged.
It's currrently `(Option<(Level, Option<LintExpectationId>)>,
LintLevelSource)`. But when the first element of the pair is `None` the
second element is always `LintLevelSource::Default`. So this commit
moves the `LintLevelSource` within the `Option`, which simplifies
things a bit.
It currently returns a triple: `(Level, Option<LintExpectationId>,
LintLevelSource)`. That's structurally identical to `LevelAndSource`, so
this commit changes it accordingly.
`reveal_actual_level` has two call sites, which look like this:
```
let (level, mut src) = self.raw_lint_id_level(lint, idx, aux);
let (level, lint_id) = reveal_actual_level(level, &mut src, sess, lint, |id| {
self.raw_lint_id_level(id, idx, aux)
});
```
and:
```
let (level, mut src) = self.probe_for_lint_level(tcx, lint, cur);
let (level, lint_id) = reveal_actual_level(level, &mut src, tcx.sess, lint, |lint| {
self.probe_for_lint_level(tcx, lint, cur)
});
```
They both have the same pattern: there's a prior call expression that is then
repeated within a closure passed to `reveal_actual_level`.
This commit moves that prior call inside `reveal_actual_level`, making things
simpler.
Remove the dummy `PreCodegen` mir-opt pass, and use `runtime-optimized` instead
- Alternative to https://github.com/rust-lang/rust/pull/156358.
The `PreCodegen` pass doesn't do anything on its own; it was only serving as a marker to allow `-Zdump-mir` and mir-opt tests to easily dump the final MIR just before codegen.
However, https://github.com/rust-lang/rust/pull/156358#issuecomment-4422445297 pointed out that the `runtime-optimized` phase transition should dump the same MIR, so there shouldn't be any need for a separate *PreCodegen* pass.
---
r? oli-obk (or compiler)