type_id_eq: check that the hash fully matches the type
The previous logic wouldn't always detect when the hash mismatches the provenance. Fix that by adding a new helper, `read_type_id`, that reads a single type ID while fully checking it for validity and consistency.
r? ``@oli-obk``
Make frame spans appear on a separate trace line
This PR changes tracing_chrome's `tracing::Layer` so that if a span has the "tracing_separate_line" field as one of the span arguments, that span is put on a separate trace line. See https://github.com/rust-lang/miri/pull/4451 for an earlier attempt and for screenshots explaining better what I mean by "separate trace line".
This PR also makes the "frame" span use this feature (so it appears on a separate trace line, see https://github.com/rust-lang/miri/pull/4451 for motivation), but passes `tracing::field::Empty` as the span parameter value so it is ignored by other tracing layers (e.g. the logger):
```rust
info_span!("frame", tracing_separate_line = Empty, "{}", instance);
```
<details><summary>Also see the following discussion I had with ``@RalfJung</summary>``
> Is there no way to attach metadata we could use instead?
[These](https://docs.rs/tracing-core/0.1.34/src/tracing_core/metadata.rs.html#57) are the **static** metadata items we can control about a span. We can't add more metadata outside of them. The most relevant are:
- `name` (for the frame span it's currently "frame")
- `target` which acts as the category (for the frame span it's currently "rustc_const_eval::interpret::stack" by default)
- `fields` which contains a list of the *names* of each of the arguments passed to the `span!` macro (for the frame span it's currently ["message"], where "message" is the default identifier for data passed in the `format!` syntax)
When the tracing code is called at runtime, the **dynamic** values of the arguments are collected into a [`ValueSet`](https://docs.rs/tracing-core/0.1.34/src/tracing_core/field.rs.html#166). Each argument value stored there corresponds with one of the static names stored in `fields` (see above).
---
We have already determined that filtering out spans by `name` is not a good idea, and I would say the same goes for `target`. Both the `name` and the `target` fields are printed to stderr when `MIRI_LOG=` is enabled, so changing them to contain an identifier (e.g. "frame:tracing_separate_root" instead of "frame" as the name) would uselessly clutter the text logs (unless we add one more filter [there](https://github.com/rust-lang/rust/blob/master/compiler/rustc_log/src/lib.rs#L137), but then it gets even more complicated).
```rust
// examples of how the above (problematic) solutions would look like
info_span!("frame:tracing_separate_root", "{}", instance);
info_span!(target: "tracing_separate_root", "frame", "{}", instance);
```
---
So that leaves us with `fields` and their runtime values. Now, my initial thought (inspired by [this comment](https://github.com/rust-lang/miri/pull/4451#issuecomment-3068072303)) was to use a field with the static name "tracing_separate_root" and with a dynamic boolean value of "true". In `tracing_chrome.rs` we can easily check if this field is true and act accordingly. This would work but then again this field would also be picked up by the logger when `MIRI_LOG=` is enabled, and would uselessly clutter the text logs.
```rust
// example of how the above (problematic) solution would look like
info_span!("frame", tracing_separate_root = true, "{}", instance);
```
---
To avoid cluttering the text logs, we can instead set "tracing_separate_root" to the dynamic value of `tracing::field::Empty`. Citing from [here](https://docs.rs/tracing/0.1.41/tracing/field/struct.Empty.html), "when a field’s value is `Empty`, it will not be recorded". "not being recorded" means that the field and its value won't be printed to stderr text logs, nor will it be printed by any other tracing layers that might be attached in the future. In `tracing_chrome.rs` we would still be able to check if "tracing_separate_root" is in the list of static `fields`, and act accordingly. So I believe this solution would effectively allow us to attach metadata to a span in a way that does not clutter logs and still allows being read in `tracing_chrome.rs`.
If we ever wanted to pass arbitrary metadata (i.e. not just a present/not present flag), it would be possible with a custom `Empty` that also holds data and implement `Value` without doing anything ([like `Empty` does](https://docs.rs/tracing-core/0.1.34/src/tracing_core/field.rs.html#775)).
```rust
// example of how the above solution would look like
info_span!("frame", tracing_separate_root = tracing::field::Empty, "{}", instance);
```
</details>
Add tracing to `InterpCx::fn_abi_of_instance/fn_abi_of_fn_ptr`
This PR adds tracing to the `InterpCx::fn_abi_of_instance`/`::fn_abi_of_fn_ptr` functions by shadowing `FnAbiOf`'s trait methods with inherent methods on `InterpCx`, like done in rust-lang/rust#142721. The reason why I am targeting these two functions is because they are used for Miri interpretation, and they make a `layout_of` query down the line without passing through the `layout_of` that was traced in rust-lang/rust#142721.
There are other places where `layout_of` is called without being traced (see the analysis below), but that's because the `Machine` used there is not `MiriMachine` but rather `CompileTimeMachine` which does not implement `enter_trace_span()`. But after discussing with ```````@RalfJung``````` we agreed that the const-eval part should not be traced together with Miri, that's why I am ignoring the other places where `layout_of` is called.
r? ```````@RalfJung```````
<details><summary>Analysis of the places where <code>layout_of</code> is called</summary>
I did some analysis for https://github.com/rust-lang/rust/pull/142721#discussion_r2171494841, and these are all the places where the query `tcx.layout_of` is called (directly or indirectly) outside of a traced `InterpCx::layout_of` while a program is being interpreted by Miri:
```
adjust_for_rust_scalar at ./compiler/rustc_ty_utils/src/abi.rs:302:35
{closure#2} at ./compiler/rustc_ty_utils/src/abi.rs:522:25
eval_body_using_ecx<> at ./compiler/rustc_const_eval/src/const_eval/eval_queries.rs:49:22
{closure#1}<> at ./compiler/rustc_const_eval/src/interpret/operand.rs:851:76
{closure#0}<> at ./compiler/rustc_const_eval/src/interpret/stack.rs:612:18
size_and_align at ./compiler/rustc_middle/src/mir/interpret/mod.rs:387:38
```
I got these by:
- patching rustc with this patch that adds a span to the `layout_of` query which prints the backtrace:
[layout_of_other_places.diff.txt](https://github.com/user-attachments/files/21235523/layout_of_other_places.diff.txt)
- adding this to my bootstrap.toml to have debug symbols inside the Miri binary: `rust.debuginfo-level = "line-tables-only"` and also `build.tool.miri.features = ["tracing"]`
- obtaining a trace file with `MIRI_TRACING=1 ./x.py run miri --stage 1 --warnings warn --args src/tools/miri/tests/pass/hello.rs` (note: maybe using a file different than "src/tools/miri/tests/pass/hello.rs" would lead to more places where layout_of is called?)
- running this query in Perfetto to select all `layout_of` spans that have as a direct parent a span named "frame" (as opposed to the parent being `InterpCx::layout_of`) and extract their backtrace: `select args.string_value from slice left join args on slice.arg_set_id = args.id where slice.name = "tcx.layout_of" and slice.parent_id in (select slice2.id from slice as slice2 where slice2.name = "frame") group by args.string_value`
- exporting the data as `.tsv` and processing that file through this Python script. It finds the first path in the backtraces where "layout" isn't mentioned, which imo is a good heuristic to not consider `layout_of` wrappers/friends as call places, but rather go down the backtrace until an actual call place is reached. [layout_of_other_places.py.txt](https://github.com/user-attachments/files/21235529/layout_of_other_places.py.txt)
</details>
interpret/allocation: expose init + write_wildcards on a range
Part of https://github.com/rust-lang/miri/pull/4456, so that we can mark down when a foreign access to our memory happened. Should this also move `prepare_for_native_access()` itself into Miri, given that everything there can be implemented on Miri's side?
r? `````@RalfJung`````
Allow custom default address spaces and parse `p-` specifications in the datalayout string
Some targets, such as CHERI, use as default an address space different from the "normal" default address space `0` (in the case of CHERI, [200 is used](https://www.cl.cam.ac.uk/techreports/UCAM-CL-TR-877.pdf)). Currently, `rustc` does not allow to specify custom address spaces and does not take into consideration [`p-` specifications in the datalayout string](https://llvm.org/docs/LangRef.html#langref-datalayout).
This patch tries to mitigate these problems by allowing targets to define a custom default address space (while keeping the default value to address space `0`) and adding the code to parse the `p-` specifications in `rustc_abi`. The main changes are that `TargetDataLayout` now uses functions to refer to pointer-related informations, instead of having specific fields for the size and alignment of pointers in the default address space; furthermore, the two `pointer_size` and `pointer_align` fields in `TargetDataLayout` are replaced with an `FxHashMap` that holds info for all the possible address spaces, as parsed by the `p-` specifications.
The potential performance drawbacks of not having ad-hoc fields for the default address space will be tested in this PR's CI run.
r? workingjubilee
setup typos check in CI
This allows to check typos in CI, currently for compiler only (to reduce commit size with fixes). With current setup, exclude list is quite short, so it worth trying?
Also includes commits with actual typo fixes.
MCP: https://github.com/rust-lang/compiler-team/issues/817
typos check currently turned for:
* ./compiler
* ./library
* ./src/bootstrap
* ./src/librustdoc
After merging, PRs which enables checks for other crates (tools) can be implemented too.
Found typos will **not break** other jobs immediately: (tests, building compiler for perf run). Job will be marked as red on completion in ~ 20 secs, so you will not forget to fix it whenever you want, before merging pr.
Check typos: `python x.py test tidy --extra-checks=spellcheck`
Apply typo fixes: `python x.py test tidy --extra-checks=spellcheck:fix` (in case if there only 1 suggestion of each typo)
Current fail in this pr is expected and shows how typo errors emitted. Commit with error will be removed after r+.
miri: improve errors for type validity assertion failures
Miri has pretty nice errors for type validity violations, printing which field in the type the problem occurs at and so on.
However, we don't see these errors when using e.g. `mem::zeroed` as that uses `assert_zero_valid` to bail out before Miri can detect the UB.
Similar to what we did with `@saethlin's` UB checks, I think we should disable such language UB checks in Miri so that we can get better error messages. If we go for this we should probably say this in the intrinsic docs as well so that people don't think they can rely on these intrinsics catching anything.
Furthermore, I slightly changed `MaybeUninit::assume_init` so that the `.value` field does not show up in error messages any more.
`@rust-lang/miri` what do you think?
give Pointer::into_parts a more scary name and offer a safer alternative
`into_parts` is a bit too innocent of a name for a somewhat subtle operation.
r? `@oli-obk`
const-eval: error when initializing a static writes to that static
Fixes https://github.com/rust-lang/rust/issues/142404 by also calling the relevant hook for writes, not just reads. To avoid erroring during the actual write of the initial value, we neuter the hook when popping the final stack frame.
Calling the hook during writes requires changing its signature since we cannot pass in the entire interpreter any more.
While doing this I also realized a gap in https://github.com/rust-lang/rust/pull/142575 for zero-sized copies on the read side, so I fixed that and added a test.
r? `@oli-obk`
Add tracing to `validate_operand`
This PR adds a tracing call to keep track of how much time is spent in `validate_operand` and `const_validate_operand`. Let me know if more fine-grained tracing is needed (e.g. adding tracing to `validate_operand_internal` too, which is just called from those two functions).
I also fixed the rustdoc of `validate_operand` and `const_validate_operand` since it was referencing an older name for the `val` parameter which was renamed in cbdcbf0d6a586792c5e0a0b8965a3179bac56120.
Here is some tracing output when Miri is run on `src/tools/miri/tests/pass/hello.rs`, visualizable in [ui.perfetto.dev](https://ui.perfetto.dev/): [trace-1750932222218210.json](https://github.com/user-attachments/files/20924000/trace-1750932222218210.json)
**Note: obtaining tracing output depends on https://github.com/rust-lang/miri/pull/4406, but this PR is standalone and can be merged without waiting for https://github.com/rust-lang/miri/pull/4406.**
r? `@RalfJung`