[rustdoc] Fix `doc_cfg` feature on reexports
Part of rust-lang/rust#150268.
I don't mark the issue as fixed as I need to check the third case described in the issue. First commit comes from https://github.com/rust-lang/rust/pull/156020, will need to rebase this PR once the original is merged.
r? @Urgau
Remove unused spans from AttributeKind
Recently I noticed some spans in diagnostic attributes were never used. I went through and checked the other variants too.
Make retags an implicit part of typed copies
Ever since Stacked Borrows was first implemented in Miri, that was done with `Retag` statements: given a place (usually a local variable), those statements find all references stored inside the place and refresh their tags to ensure the aliasing requirements are upheld. However, this is a somewhat unsatisfying approach for multiple reasons:
- It leaves open the [question](https://github.com/rust-lang/unsafe-code-guidelines/issues/371) of where to even put `Retag` statements. Over time, the AddRetag pass settled on one possible answer to this, but it wasn't very canonical.
- For assignments of the form `*ptr = expr`, if the assignment involves copying a reference, we probably want to do a retag -- but if we do a `Retag(*ptr)` as the next instruction, it can be non-trivial to argue that this even retags the right value, so we refrained from doing retags in that case. This has [come up](https://github.com/llvm/llvm-project/pull/160913#issuecomment-3341908717) as a potential issue for Rust making better use of LLVM "captures" annotations. (That said, there might be [other ways](https://github.com/rust-lang/unsafe-code-guidelines/issues/593#issuecomment-4328112031) to obtain this desired optimization.)
- Normal compilation avoids generating retags, but we still generate LLVM IR with `noalias`. What does that even mean? How do MIR optimization passes interact with retags? These are questions we have to figure out to make better use of aliasing information, but currently we can't even really ask such questions.
I think we should resolve all that by making retags part of what happens during a typed copy (a concept and interpreter infrastructure that did not exist yet when retags were initially introduced). Under this proposal, when executing a MIR assignment statement, what conceptually happens is as follows:
- We evaluate the LHS to a place.
- We evaluate the RHS to a value. This does a typed load from memory if needed, raising UB if memory does not contain a valid representation of the assignment's type.
- We walk that value, identify all references inside of it, and retag them. If this happens as part of passing a function argument, this is a protecting retag.
- We store (a representation of) the value into the place.
However, this semantics doesn't fully work: there's a mandatory MIR pass that turns expressions like `&mut ***ptr` into intermediate deref's. Those must *not* do any retags. So far this happened because the AddRetag pass did not add retags for assignments to deref temporaries, but that information is not recorded in cross-crate MIR. Therefore I instead added a field to `Rvalue::Use` to indicate whether this value should be retagged or not. A non-retagging copy seems like a sufficiently canonical primitive that we should be able to express it. Dealing with the fallout from that is a large chunk of the overall diff. (I also considered adding this field to `StatementKind::Assign` instead, but decided against that as we only actually need it for `Rvalue::Use`. I am not sure if this was the right call...)
This neatly answers the question of when retags should occur, and handles cases like `*ptr = expr`. It avoids traversing values twice in Miri. It makes codegen's use of `noalias` sound wrt the actual MIR that it is working on. It also gives us a target semantics to evaluate MIR opts against. However, I did not carefully check all MIR opts -- in particular, GVN needs a thorough look under the new semantics; it currently can turn alias-correct code into alias-incorrect code. (But this PR doesn't make things any worse for normal compilation where the retag indicator is anyway ignored.)
Another side-effect of this PR is that `-Zmiri-disable-validation` now also disables alias checking. It'd be nicer to keep them orthogonal but I find this an acceptable price to pay.
- [rustc benchmark results](https://github.com/rust-lang/rust/pull/154341#issuecomment-4125313290)
- [miri benchmark results](https://github.com/rust-lang/rust/pull/154341#issuecomment-4129840926)
Add extra symbol check for `.to_owned()`
Follow up of rust-lang/rust#154646
Previously when adding a suggestion for using `Cow::into_owned()` instead of `ToOwned::to_owned()`, the compiler would just convert the methods `Span` into a `String` and do checks on that `String`. This PR adds an extra guard to that suggestion by checking if the method is `sym::to_owned_method`.
r? @davidtwco since you added the review to the previous PR
Previously when adding a suggestion for using `Cow::into_owned()`
instead of `ToOwned::to_owned()`, the compiler would just convert the
methods `Span` into a `String` and do checks on that `String`. This PR
adds an extra guard to that suggestion by checking if the method is
`sym::to_owned_method`.
Improve source code for `librustdoc/visit_ast.rs`
While working on this part of rustdoc, got annoyed at the tuples and decided to transform them into types. Code is now much easier to follow. :3
r? @Urgau
Specifically:
- `HashStable` -> `StableHash` (trait)
- `HashStable` -> `StableHash` (derive)
- `HashStable_NoContext` -> `StableHash_NoContext` (derive)
Note: there are some names in `compiler/rustc_macros/src/hash_stable.rs`
that are still to be renamed, e.g. `HashStableMode`.
Part of MCP 983.
Fix alias path for rustdoc
I ran this command:
```console
x build --stage 1 --skip rustdoc
Building bootstrap
Compiling bootstrap v0.0.0 (/Users/yukang/rust/src/bootstrap)
Finished `dev` profile [unoptimized] target(s) in 1.08s
/Users/yukang/rust/build/aarch64-apple-darwin/ci-llvm/bin/llvm-strip does not exist; skipping copy
Building stage1 compiler artifacts (stage0 -> stage1, aarch64-apple-darwin)
Finished `release` profile [optimized + debuginfo] target(s) in 0.45s
Creating a sysroot for stage1 compiler (use `rustup toolchain link 'name' build/host/stage1`)
Building stage1 library artifacts{alloc, compiler_builtins, core, panic_abort, panic_unwind, proc_macro, rustc-std-workspace-core, std, std_detect, sysroot, test, unwind} (stage1 -> stage1, aarch64-apple-darwin)
Finished `dist` profile [optimized + debuginfo] target(s) in 0.10s
Skipping Set({build::src/tools/rustdoc}) because it is excluded
Building stage1 rustdoc_tool_binary (stage0 -> stage1, aarch64-apple-darwin)
Finished `release` profile [optimized + debuginfo] target(s) in 0.19s
```
expect all `rustdoc` related compiling phase will be exlcuded, but from the log we can see `rustdoc_tool_binary` is still compiled.
`src/tools/rustdoc` and `src/librustdoc` are documented as aliases in path set here:
https://github.com/rust-lang/rust/blob/a25435bcf7cfc9b953d356eda3a51db8da9e3386/src/bootstrap/src/core/builder/mod.rs#L355-L360
we can also see here two paths are treated as alias:
https://github.com/rust-lang/rust/blob/a25435bcf7cfc9b953d356eda3a51db8da9e3386/src/bootstrap/src/core/build_steps/check.rs#L818-L822
but bootstrap registered them as two different sets with `.path(..).path(...)`:
https://github.com/rust-lang/rust/blob/a25435bcf7cfc9b953d356eda3a51db8da9e3386/src/bootstrap/src/core/build_steps/tool.rs#L691-L693
That meant commands like `x build --skip rustdoc`, `--skip src/tools/rustdoc`, or `--skip src/librustdoc` only excluded one side.
linker-messages is warn-by-default again
cc rust-lang/rust#136096
I ended up keeping it a lint and adding an option for lints to ignore `-Dwarnings` (there was already a lint that did that actually, it was just hard-coded in rustc_middle instead of in rustc_lint_defs like I'd expect). This allows people to actually see the warnings without them failing the build in CI.
Do not run jump-threading for GPUs
GPU targets have convergent operations that must not be duplicated or
moved in or out of control-flow.
An example convergent operation is a barrier/syncthreads.
The only MIR pass affected by this is jump-threading, it can duplicate
calls. Disable jump-hreading for GPU targets to prevent generating
incorrect code.
This affects the amdgpu and nvptx targets.
Fixesrust-lang/rust#137086, see this issue for details.
Tracking issue: rust-lang/rust#135024
cc @RDambrosio016 @kjetilkjeka for nvptx
cc @ZuseZ4
Move `feature*` methods from `parse` mod to `errors` mod.
As the FIXME comment says, these no longer use `ParseSess` and so the `parse` mod is not a good place for them. The `errors` mod is a better home.
r? @TaKO8Ki
rustdoc: preserve parent doc cfg for `macro_export` macros
The detached-item context is discovered before `propagate_doc_cfg`, it is carried on the clean item and consumed by the pass.
Closesrust-lang/rust#100916
It currently only depends on two things:
- `rustc_ast::AttrId`: this is just a re-export of `rustc_span::AttrId`,
so we can import the original instead.
- `rustc_ast::AttributeExt`: needed only for the `name` and `id`
methods. We can instead pass in the `name` and `id` directly.