fix interpreter tracing output
https://github.com/rust-lang/rust/pull/144708 accidentally changed the output of `MIRI_LOG=info <miri run>` in two ways:
- by adding `stmt=`/`terminator=` prefixes
- by changing the statement printing to be a verbose debug version instead of MIR pretty-printing
This fixes both of these:
- use explicit format strings to avoid the prefixes
- fix inconsistency in Debug impls for MIR types: now both TerminatorKind and StatementKind are pretty-printed, and Terminator and Statement just forward to the *Kind output
Remove `impl IntoQueryParam<P> for &'a P`.
`IntoQueryParam` is a trait that lets query callers be a bit sloppy with the passed-in key.
- Types similar to `DefId` will be auto-converted to `DefId`. Likewise for `LocalDefId`.
- Reference types will be auto-derefed.
The auto-conversion is genuinely useful; the auto-derefing much less so. In practice it's only used for passing `&DefId` to queries that accept `DefId`, which is an anti-pattern because `DefId` is marked with `#[rustc_pass_by_value]`.
This commit removes the auto-deref impl and makes the necessary sigil adjustments. (I generally avoid using `*` to deref manually at call sites, preferring to deref via `&` in patterns or via `*` in match expressions. Mostly because that way a single deref often covers multiple call sites.)
r? @cjgillot
Fix ICE in const eval of packed SIMD types with non-power-of-two element counts
fixesrust-lang/rust#151537
const evaluation of packed SIMD types with non-power-of-two element counts (like `Simd<_, 3>`) was hitting an ICE. the issue was in `check_simd_ptr_alignment` - it asserted that `backend_repr` must be `BackendRepr::SimdVector`, but for packed SIMD types with non-power-of-two counts the compiler uses `BackendRepr::Memory` instead (as mentioned in `rustc_abi/src/layout.rs:1511`).
was fixed by making `check_simd_ptr_alignment` accept both `BackendRepr::SimdVector` and `BackendRepr::Memory` for SIMD types. added a check to ensure we're dealing with a SIMD type, and the alignment logic works the same for both representations.
also i added a test that reproduces the original ICE.
`IntoQueryParam` is a trait that lets query callers be a bit sloppy with
the passed-in key.
- Types similar to `DefId` will be auto-converted to `DefId`. Likewise
for `LocalDefId`.
- Reference types will be auto-derefed.
The auto-conversion is genuinely useful; the auto-derefing much less so.
In practice it's only used for passing `&DefId` to queries that accept
`DefId`, which is an anti-pattern because `DefId` is marked with
`#[rustc_pass_by_value]`.
This commit removes the auto-deref impl and makes the necessary sigil
adjustments. (I generally avoid using `*` to deref manually at call
sites, preferring to deref via `&` in patterns or via `*` in match
expressions. Mostly because that way a single deref often covers
multiple call sites.)
Reflection TypeKind::FnPtr
This is for https://github.com/rust-lang/rust/issues/146922.
Const-eval currently lacks full support for function pointer (fn) types. We should implement handling of FnPtr TypeKind, covering safe and unsafe functions, Rust and custom ABIs, input and output types, higher-ranked lifetimes, and variadic functions.
- Implement handling of FnPtr TypeKind in const-eval, including:
- Unsafety flag (safe vs unsafe fn)
- ABI variants (Rust, Named(C), Named(custom))
- Input and output types
- Variadic function pointers
- Add const-eval tests covering:
- Basic Rust fn() pointers
- Unsafe fn() pointers
- Extern C and custom ABI pointers
- Functions with multiple inputs and output types
- Variadic functions
- Use const TypeId checks to verify correctness of inputs, outputs, and payloads
Miri: recursive validity: also recurse into Boxes
Now that https://github.com/rust-lang/rust/issues/97270 is fixed, the recursive validity mode for Miri can recuse into Boxes without exploding everywhere.
replace box_new with lower-level intrinsics
The `box_new` intrinsic is super special: during THIR construction it turns into an `ExprKind::Box` (formerly known as the `box` keyword), which then during MIR building turns into a special instruction sequence that invokes the exchange_malloc lang item (which has a name from a different time) and a special MIR statement to represent a shallowly-initialized `Box` (which raises [interesting opsem questions](https://github.com/rust-lang/rust/issues/97270)).
This PR is the n-th attempt to get rid of `box_new`. That's non-trivial because it usually causes a perf regression: replacing `box_new` by naive unsafe code will incur extra copies in debug builds, making the resulting binaries a lot slower, and will generate a lot more MIR, making compilation measurably slower. Furthermore, `vec!` is a macro, so the exact code it expands to is highly relevant for borrow checking, type inference, and temporary scopes.
To avoid those problems, this PR does its best to make the MIR almost exactly the same as what it was before. `box_new` is used in two places, `Box::new` and `vec!`:
- For `Box::new` that is fairly easy: the `move_by_value` intrinsic is basically all we need. However, to avoid the extra copy that would usually be generated for the argument of a function call, we need to special-case this intrinsic during MIR building. That's what the first commit does.
- `vec!` is a lot more tricky. As a macro, its details leak to stable code, so almost every variant I tried broke either type inference or the lifetimes of temporaries in some ui test or ended up accepting unsound code due to the borrow checker not enforcing all the constraints I hoped it would enforce. I ended up with a variant that involves a new intrinsic, `fn write_box_via_move<T>(b: Box<MaybeUninit<T>>, x: T) -> Box<MaybeUninit<T>>`, that writes a value into a `Box<MaybeUninit<T>>` and returns that box again. In exchange we can get rid of somewhat similar code in the lowering for `ExprKind::Box`, and the `exchange_malloc` lang item. (We can also get rid of `Rvalue::ShallowInitBox`; I didn't include that in this PR -- I think @cjgillot has a commit for this somewhere [around here](https://github.com/rust-lang/rust/pull/147862/commits).)
See [here](https://github.com/rust-lang/rust/pull/148190#issuecomment-3457454814) for the latest perf numbers. Most of the regressions are in deep-vector which consists entirely of an invocation of `vec!`, so any change to that macro affects this benchmark disproportionally.
This is my first time even looking at MIR building code, so I am very low confidence in that part of the patch, in particular when it comes to scopes and drops and things like that.
I also had do nerf some clippy tests because clippy gets confused by the new expansion of `vec!` so it makes fewer suggestions when `vec!` is involved.
### `vec!` FAQ
- Why does `write_box_via_move` return the `Box` again? Because we need to expand `vec!` to a bunch of method invocations without any blocks or let-statements, or else the temporary scopes (and type inference) don't work out.
- Why is `box_assume_init_into_vec_unsafe` (unsoundly!) a safe function? Because we can't use an unsafe block in `vec!` as that would necessarily also include the `$x` (due to it all being one big method invocation) and therefore interpret the user's code as being inside `unsafe`, which would be bad (and 10 years later, we still don't have safe blocks for macros like this).
- Why does `write_box_via_move` use `Box` as input/output type, and not, say, raw pointers? Because that is the only way to get the correct behavior when `$x` panics or has control effects: we need the `Box` to be dropped in that case. (As a nice side-effect this also makes the intrinsic safe, which is imported as explained in the previous bullet.)
- Can't we make it safe by having `write_box_via_move` return `Box<T>`? Yes we could, but there's no easy way for the intrinsic to convert its `Box<MaybeUninit<T>>` to a `Box<T>`. Transmuting would be unsound as the borrow checker would no longer properly enforce that lifetimes involved in a `vec!` invocation behave correctly.
- Is this macro truly cursed? Yes, yes it is.
Start using pattern types in libcore (NonZero and friends)
part of rust-lang/rust#136006
This PR only changes the internal representation of `NonZero`, `NonMax`, ... and other integral range types in libcore. This subsequently affects other types made up of it, but nothing really changes except that the field of `NonZero` is now accessible safely in contrast to the `rustc_layout_scalar_range_start` attribute, which has all kinds of obscure rules on how to properly access its field.
Support ADT types in type info reflection
Tracking issue: rust-lang/rust#146922 `#![feature(type_info)]`
This PR supports ADT types for feature `type_info` reflection.
(It's still a draft PR, with implementation in progress)
Note that this PR does not take SemVer into consideration (I left a FIXME comment). As discussed earlier ([comment](https://github.com/rust-lang/rust/pull/146923#discussion_r2372249477)), this requires further discussion. However, I hope we could get an initial implementation to land first, so we can start playing with it.
### Progress / Checklist
- [x] Struct support.
- [x] Enum
- [x] Union
- [x] Generics
- [ ] ~Methods~ Implemented and to be implemented in other PRs
- [ ] ~Traits~ Implemented and to be implemented in other PRs
- [x] Rebasing PR to `main` branch
~~(It's currently based on PR rust-lang/rust#151123, so here's an extra commit)~~
- [x] Cleanup and Rebase.
- [x] Fix field info for references. (see [comment](https://github.com/rust-lang/rust/pull/151142#discussion_r2777920512))
r? @oli-obk