Remove the x86_64-rumprun-netbsd target
Herein we remove the target from the compiler and the code from libstd intended to support the now-defunct rumprun project.
Closes#81514
Link crtbegin/crtend on musl to terminate .eh_frame
For some targets, rustc uses a "CRT fallback", where it links CRT
object files it ships instead of letting the host compiler link
them.
On musl, rustc currently links crt1, crti and crtn (provided by
libc), but does not link crtbegin and crtend (provided by libgcc).
In particular, crtend is responsible for terminating the .eh_frame
section. Lack of terminator may result in segfaults during
unwinding, as reported in #47551 and encountered by the LLVM 12
update in #81451.
This patch links crtbegin and crtend for musl as well, following
the table at the top of crt_objects.rs.
r? ``@nagisa``
For some targets, rustc uses a "CRT fallback", where it links CRT
object files it ships instead of letting the host compiler link
them.
On musl, rustc currently links crt1, crti and crtn (provided by
libc), but does not link crtbegin and crtend (provided by libgcc).
In particular, crtend is responsible for terminating the .eh_frame
section. Lack of terminator may result in segfaults during
unwinding, as reported in #47551 and encountered by the LLVM 12
update in #81451.
This patch links crtbegin and crtend for musl as well, following
the table at the top of crt_objects.rs.
add s390x-unknown-linux-musl target
This is the first step in bringup for Rust on s390x.
The libc and std crates need modifications as well, but getting this upstream makes that work easier.
Add new `rustc` target for Arm64 machines that can target the iphonesimulator
This PR lands a new target (`aarch64-apple-ios-sim`) that targets arm64 iphone simulator, previously unreachable from Apple Silicon machines.
resolves#81632
r? `@shepmaster`
LLVM picks the right things to put into the compiled object file based
on the target deployment version.
We need to communicate it through the target triple.
Only with that LLVM will use the right commands in the file to make it
look and behave like code compiled for the arm64 iOS simulator target.
Add a new ABI to support cmse_nonsecure_call
This adds support for the `cmse_nonsecure_call` feature to be able to perform non-secure function call.
See the discussion on Zulip [here](https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Support.20for.20callsite.20attributes/near/223054928).
This is a followup to #75810 which added `cmse_nonsecure_entry`. As for that PR, I assume that the changes are small enough to not have to go through a RFC but I don't mind doing one if needed 😃
I did not yet create a tracking issue, but if most of it is fine, I can create one and update the various files accordingly (they refer to the other tracking issue now).
On the Zulip chat, I believe `@jonas-schievink` volunteered to be a reviewer 💯
Add AArch64 big-endian and ILP32 targets
This PR adds 3 new AArch64 targets:
- `aarch64_be-unknown-linux-gnu`
- `aarch64-unknown-linux-gnu_ilp32`
- `aarch64_be-unknown-linux-gnu_ilp32`
It also fixes some ABI issues on big-endian ARM and AArch64.
This commit adds a new ABI to be selected via `extern
"C-cmse-nonsecure-call"` on function pointers in order for the compiler to
apply the corresponding cmse_nonsecure_call callsite attribute.
For Armv8-M targets supporting TrustZone-M, this will perform a
non-secure function call by saving, clearing and calling a non-secure
function pointer using the BLXNS instruction.
See the page on the unstable book for details.
Signed-off-by: Hugues de Valon <hugues.devalon@arm.com>
Don't link with --export-dynamic on wasm32-wasi
Remove --export-dynamic from the link arguments on the wasm32-wasi
target, as it emits spurious exports and increases code size.
Leave it in place for wasm32-unknown-unknown and
wasm32-unknown-emscripten. Even though it isn't a great solution
there, users are likely depending on its behavior there.
This seems right, given that conceptually bools are unsigned, but the
implications of this change may have more action at distance that I'm
not sure how to exhaustively consider.
For instance there are a number of cases where code attaches range
metadata if `scalar.is_bool()` holds. Supposedly it would no longer be
attached to the `repr(i8)` enums? Though I'm not sure why booleans are
being special-cased here in the first place...
Fixes#80556
Rollup of 10 pull requests
Successful merges:
- #79570 (rustc: Stabilize `-Zrun-dsymutil` as `-Csplit-debuginfo`)
- #79819 (Add `SEMICOLON_IN_EXPRESSIONS_FROM_MACROS` lint)
- #79991 (rustdoc: Render HRTB correctly for bare functions)
- #80215 (Use -target when linking binaries for Mac Catalyst)
- #81158 (Point to span of upvar making closure FnMut)
- #81176 (Improve safety of `LateContext::qpath_res`)
- #81287 (Split rustdoc JSON types into separately versioned crate)
- #81306 (Fuse inner iterator in FlattenCompat and improve related tests)
- #81333 (clean up some const error reporting around promoteds)
- #81459 (Fix rustdoc text selection for page titles)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
rustc: Stabilize `-Zrun-dsymutil` as `-Csplit-debuginfo`
This commit adds a new stable codegen option to rustc,
`-Csplit-debuginfo`. The old `-Zrun-dsymutil` flag is deleted and now
subsumed by this stable flag. Additionally `-Zsplit-dwarf` is also
subsumed by this flag but still requires `-Zunstable-options` to
actually activate. The `-Csplit-debuginfo` flag takes one of
three values:
* `off` - This indicates that split-debuginfo from the final artifact is
not desired. This is not supported on Windows and is the default on
Unix platforms except macOS. On macOS this means that `dsymutil` is
not executed.
* `packed` - This means that debuginfo is desired in one location
separate from the main executable. This is the default on Windows
(`*.pdb`) and macOS (`*.dSYM`). On other Unix platforms this subsumes
`-Zsplit-dwarf=single` and produces a `*.dwp` file.
* `unpacked` - This means that debuginfo will be roughly equivalent to
object files, meaning that it's throughout the build directory
rather than in one location (often the fastest for local development).
This is not the default on any platform and is not supported on Windows.
Each target can indicate its own default preference for how debuginfo is
handled. Almost all platforms default to `off` except for Windows and
macOS which default to `packed` for historical reasons.
Some equivalencies for previous unstable flags with the new flags are:
* `-Zrun-dsymutil=yes` -> `-Csplit-debuginfo=packed`
* `-Zrun-dsymutil=no` -> `-Csplit-debuginfo=unpacked`
* `-Zsplit-dwarf=single` -> `-Csplit-debuginfo=packed`
* `-Zsplit-dwarf=split` -> `-Csplit-debuginfo=unpacked`
Note that `-Csplit-debuginfo` still requires `-Zunstable-options` for
non-macOS platforms since split-dwarf support was *just* implemented in
rustc.
There's some more rationale listed on #79361, but the main gist of the
motivation for this commit is that `dsymutil` can take quite a long time
to execute in debug builds and provides little benefit. This means that
incremental compile times appear that much worse on macOS because the
compiler is constantly running `dsymutil` over every single binary it
produces during `cargo build` (even build scripts!). Ideally rustc would
switch to not running `dsymutil` by default, but that's a problem left
to get tackled another day.
Closes#79361
This commit adds a new stable codegen option to rustc,
`-Csplit-debuginfo`. The old `-Zrun-dsymutil` flag is deleted and now
subsumed by this stable flag. Additionally `-Zsplit-dwarf` is also
subsumed by this flag but still requires `-Zunstable-options` to
actually activate. The `-Csplit-debuginfo` flag takes one of
three values:
* `off` - This indicates that split-debuginfo from the final artifact is
not desired. This is not supported on Windows and is the default on
Unix platforms except macOS. On macOS this means that `dsymutil` is
not executed.
* `packed` - This means that debuginfo is desired in one location
separate from the main executable. This is the default on Windows
(`*.pdb`) and macOS (`*.dSYM`). On other Unix platforms this subsumes
`-Zsplit-dwarf=single` and produces a `*.dwp` file.
* `unpacked` - This means that debuginfo will be roughly equivalent to
object files, meaning that it's throughout the build directory
rather than in one location (often the fastest for local development).
This is not the default on any platform and is not supported on Windows.
Each target can indicate its own default preference for how debuginfo is
handled. Almost all platforms default to `off` except for Windows and
macOS which default to `packed` for historical reasons.
Some equivalencies for previous unstable flags with the new flags are:
* `-Zrun-dsymutil=yes` -> `-Csplit-debuginfo=packed`
* `-Zrun-dsymutil=no` -> `-Csplit-debuginfo=unpacked`
* `-Zsplit-dwarf=single` -> `-Csplit-debuginfo=packed`
* `-Zsplit-dwarf=split` -> `-Csplit-debuginfo=unpacked`
Note that `-Csplit-debuginfo` still requires `-Zunstable-options` for
non-macOS platforms since split-dwarf support was *just* implemented in
rustc.
There's some more rationale listed on #79361, but the main gist of the
motivation for this commit is that `dsymutil` can take quite a long time
to execute in debug builds and provides little benefit. This means that
incremental compile times appear that much worse on macOS because the
compiler is constantly running `dsymutil` over every single binary it
produces during `cargo build` (even build scripts!). Ideally rustc would
switch to not running `dsymutil` by default, but that's a problem left
to get tackled another day.
Closes#79361
Target stack-probe support configurable finely
This adds capability to configure the target's stack probe support in a
more precise manner than just on/off. In particular now we allow
choosing between always inline-asm, always call or either one of those
depending on the LLVM version.
Note that this removes the ability to turn off the generation of the
stack-probe attribute. This is valid to replace it with inline-asm for all targets because
`probe-stack="inline-asm"` will not generate any machine code on targets
that do not currently support stack probes. This makes support for stack
probes on targets that don't have any right now automatic with LLVM
upgrades in the future.
(This is valid to do based on the fact that clang unconditionally sets
this attribute when `-fstack-clash-protection` is used, AFAICT)
cc #77885
r? `@cuviper`
Abi::ScalarPair is only ever used for types that don't have a stable
layout anyway so this doesn't break any FFI. It does however reduce the
amount of special casing on the abi outside of the code responsible for
abi specific adjustments to the pass mode.
Remove --export-dynamic from the link arguments on the wasm32-wasi
target, as it emits spurious exports and increases code size.
Leave it in place for wasm32-unknown-unknown and
wasm32-unknown-emscripten. Even though it isn't a great solution
there, users are likely depending on its behavior there.
This adds capability to configure the target's stack probe support in a
more precise manner than just on/off. In particular now we allow
choosing between always inline-asm, always call or either one of those
depending on the LLVM version on a per-target basis.
Added support for i386-unknown-linux-gnu and i486-unknown-linux-gnu
Support for both can be useful when creating new firmware, boot loaders,
or embedded operating systems.
Split a func into cold/hot parts, reducing binary size
I noticed that the Size::bits function is called in many places,
and is inlined into them. On x86_64-pc-windows-msvc, this function
is inlined 527 times, and compiled separately (non-inlined) 3 times.
Each of those inlined calls contains code that panics. This commit
moves the `panic!` call into a separate function and marks that
function with `#[cold]`.
This reduces binary size by 24 KB. Not much, but it's something.
Changes like this often reduce pressure on instruction-caches,
since it reduces the amount of code that is inlined into hot code
paths. Or more precisely, it removes cold code from hot cache lines.
Use correct ABI for wasm32 by default
Introduces `wasm32-unknown-bindgen` for those wishing to use the bindgen compat abi. `wasm32-*` now uses the correct abi by default.
Fixes https://github.com/rustwasm/team/issues/291
I noticed that the Size::bits function is called in many places,
and is inlined into them. On x86_64-pc-windows-msvc, this function
is inlined 527 times, and compiled separately (non-inlined) 3 times.
Each of those inlined calls contains code that panics. This commit
moves the `panic!` call into a separate function and marks that
function with `#[cold]`.
This reduces binary size by 24 KB. By itself, that's not a substantial
reduction. However, changes like this often reduce pressure on
instruction-caches, since it reduces the amount of code that is inlined
into hot code paths. Or more precisely, it removes cold code from hot
cache lines. It also removes all conditionals from Size::bits(),
which is called in many places.
Use Symbol for inline asm register class names
This takes care of one "FIXME":
// FIXME: use direct symbol comparison for register class names
Instead of using string literals, this uses Symbol for register
class names.
This is part of work I am doing to improve how Symbol interning works.
This takes care of one "FIXME":
// FIXME: use direct symbol comparison for register class names
Instead of using string literals, this uses Symbol for register
class names.
Add wasm32 support to inline asm
There is some contention around inline asm and wasm, and I really only made this to figure out the process of hacking on rustc, but I figured as long as the code existed, it was worth uploading.
cc `@Amanieu`
It is applied exactly when the return value has an indirect pass mode.
Except for InReg on x86 fastcall, arg attrs are now only used for
optimization purposes and thus are fine to ignore.
rustc_target: Mark UEFI targets as `is_like_windows`/`is_like_msvc`
And document what `is_like_windows` and `is_like_msvc` actually mean in more detail.
Addresses FIXMEs left from https://github.com/rust-lang/rust/pull/71030.
r? `@nagisa`
Add asm register information for SPIR-V
As discussed in [zulip](https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/Defining.20asm!.20for.20new.20architecture), we at [rust-gpu](https://github.com/EmbarkStudios/rust-gpu) would like to support `asm!` for our SPIR-V backend. However, we cannot do so purely without frontend support: [this match](d4ea0b3e46/compiler/rustc_target/src/asm/mod.rs (L185)) fails and so `asm!` is not supported ([error reported here](d4ea0b3e46/compiler/rustc_ast_lowering/src/expr.rs (L1095))). To resolve this, we need to stub out register information for SPIR-V to support getting the `asm!` content all the way to [`AsmBuilderMethods::codegen_inline_asm`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_codegen_ssa/traits/trait.AsmBuilderMethods.html#tymethod.codegen_inline_asm), at which point the rust-gpu backend can do all the parsing and codegen that is needed.
This is a pretty weird PR - adding support for a backend that isn't in-tree feels pretty gross to me, but I don't see an easy way around this. ``@Amanieu`` said I should submit it anyway, so, here we are! Let me know if this needs to go through a more formal process (MCP?) and what I should do to help this along.
I based this off the [wasm asm PR](https://github.com/rust-lang/rust/pull/78684), which unfortunately this PR conflicts with that one quite a bit, sorry for any merge conflict pain :(
---
Some open questions:
- What do we call the register class? Some context, SPIR-V is an SSA-based IR, there are "instructions" that create IDs (referred to as `<id>` in the spec), which can be referenced by other instructions. So, `reg` isn't exactly accurate, they're SSA IDs, not re-assignable registers.
- What happens when a SPIR-V register gets to the LLVM backend? Right now it's a `bug!`, but should that be a `sess.fatal()`? I'm not sure if it's even possible to reach that point, maybe there's a check that prevents the `spirv` target from even reaching that codepath.
Majority of targets use "unknown" vendor and changing it from "unknown" to omitted doesn't make sense.
From the LLVM docs (https://clang.llvm.org/docs/CrossCompilation.html#target-triple):
>Most of the time it can be omitted (and Unknown) will be assumed, which sets the defaults for the specified architecture.
>When a parameter is not important, it can be omitted, or you can choose unknown and the defaults will be used. If you choose a parameter that Clang doesn’t know, like blerg, it’ll ignore and assume unknown
rustc_target: Further cleanup use of target options
Follow up to https://github.com/rust-lang/rust/pull/77729.
Implements items 2 and 4 from the list in https://github.com/rust-lang/rust/pull/77729#issue-500228243.
The first commit collapses uses of `target.options.foo` into `target.foo`.
The second commit renames some target options to avoid tautology:
`target.target_endian` -> `target.endian`
`target.target_c_int_width` -> `target.c_int_width`
`target.target_os` -> `target.os`
`target.target_env` -> `target.env`
`target.target_vendor` -> `target.vendor`
`target.target_family` -> `target.os_family`
`target.target_mcount` -> `target.mcount`
r? `@Mark-Simulacrum`
with an eye on merging `TargetOptions` into `Target`.
`TargetOptions` as a separate structure is mostly an implementation detail of `Target` construction, all its fields logically belong to `Target` and available from `Target` through `Deref` impls.
Revert "Allow dynamic linking for iOS/tvOS targets."
This reverts PR #73516.
On macOS I compile static libs for iOS, automated using [cargo-mobile](https://github.com/BrainiumLLC/cargo-mobile), which has worked smoothly for the past 2 years. However, upon updating to Rust 1.46.0, I was no longer able to use Rust on iOS. I've bisected this to the PR referenced above.
For most projects tested, apps now immediately crash with a message like this:
```
dyld: Library not loaded: /Users/francesca/Projects/example/target/aarch64-apple-ios/debug/deps/libexample.dylib
Referenced from: /private/var/containers/Bundle/Application/745912AF-A928-465C-B340-872BD1C9F368/example.app/example
Reason: image not found
dyld: launch, loading dependent libraries
DYLD_LIBRARY_PATH=/usr/lib/system/introspection
DYLD_INSERT_LIBRARIES=/Developer/usr/lib/libBacktraceRecording.dylib:/Developer/usr/lib/libMainThreadChecker.dylib:/Developer/Library/PrivateFrameworks/DTDDISupport.framework/libViewDebuggerSupport.dylib:/Developer/Library/PrivateFrameworks/GPUTools.framework/libglInterpose.dylib:/usr/lib/libMTLCapture.dylib
```
This can be reproduced by using cargo-mobile to generate a winit example project, and then attempting to run it on an iOS device (`cargo mobile init && cargo apple open`).
In our projects that depend on DisplayLink, the build instead fails with a linker error:
```
= note: Undefined symbols for architecture arm64:
"_CACurrentMediaTime", referenced from:
display_link::ios::run_callback_ios10::hda81197ff46aedbd in libapp-4f0abc1d7684103f.rlib(app-4f0abc1d7684103f.40d4iro0yz1iy487.rcgu.o)
display_link::ios::run_callback_pre_ios10::h91f085da19374320 in libapp-4f0abc1d7684103f.rlib(app-4f0abc1d7684103f.40d4iro0yz1iy487.rcgu.o)
ld: symbol(s) not found for architecture arm64
```
After reverting the change to enable dynamic linking on iOS, everything works the same as it did on Rust 1.45.2 for me.
In the future, would it be possible for me to be pinged when iOS-related PRs are made? I work for a company that intends on using Rust on iOS in production, so I'd gladly provide testing.
cc @aspenluxxxy
Preparation for a subsequent change that replaces
rustc_target::config::Config with its wrapped Target.
On its own, this commit breaks the build. I don't like making
build-breaking commits, but in this instance I believe that it
makes review easier, as the "real" changes of this PR can be
seen much more easily.
Result of running:
find compiler/ -type f -exec sed -i -e 's/target\.target\([)\.,; ]\)/target\1/g' {} \;
find compiler/ -type f -exec sed -i -e 's/target\.target$/target/g' {} \;
find compiler/ -type f -exec sed -i -e 's/target.ptr_width/target.pointer_width/g' {} \;
./x.py fmt
Rename target_pointer_width to pointer_width because it is already
member of the Target struct.
The compiler supports only three valid values for target_pointer_width:
16, 32, 64. Thus it can safely be turned into an int.
This means less allocations and clones as well as easier handling of the type.
Also change target_pointer_width to pointer_width.
Preparation for a subsequent type change of
target_pointer_width to an integer together with a rename
to pointer_width.
On its own, this commit breaks the build. I don't like making
build-breaking commits, but in this instance I believe that it
makes review easier, as the "real" changes of this PR can be
seen much more easily.
Result of running:
find compiler/rustc_target/src/spec/ -type f -exec sed -i -e 's/target_pointer_width: "\(.*\)"\..*,/pointer_width: \1,/g' {} \;
Add LLVM flags to limit DWARF version to 2 on BSD
This has been a thorn in my side for a while, I can finally generate flamegraphs of rust programs on bsd again. This fixes dtrace profiling on freebsd, I think it might help with lldb as well but I can't test that because my current rust-lldb setup is messed up.
I'm limiting the dwarf version to 2 on all bsd's (netbsd/openbsd/freebsd) since it looks like this applies to all of them, but I have only tested on freebsd.
Let me know if there's anything I can improve!
---
Currently on FreeBSD dtrace profiling does not work and shows jumbled/incorrect
symbols in the backtraces. FreeBSD does not support the latest versions of DWARF
in dtrace (and lldb?) yet, and needs to be limited to DWARF2 in the same way as macos.
This adds an is_like_bsd flag since it was missing. NetBSD/OpenBSD/FreeBSD all
match this.
This effectively copies #11864 but targets FreeBSD instead of macos.
Certain platforms need to limit the DWARF version emitted (oxs, *bsd). This
change adds a dwarf_version entry to the options that allows a platform to
specify the dwarf version to use. By default this option is none and the default
DWARF version is selected.
Also adds an option for printing Option<u32> json keys
Add asm! support for mips64
- [x] Updated `src/doc/unstable-book/src/library-features/asm.md`.
- [ ] No vector type support. I don't know much about those types.
cc #76839
rustc_target: Refactor away `TargetResult`
Follow-up to https://github.com/rust-lang/rust/pull/77202.
Construction of a built-in target is always infallible now, so `TargetResult` is no longer necessary.
The second commit contains some further cleanup based on built-in target construction being infallible.
With this change, it's possible to build on a linux-gnu target and pass
RUSTFLAGS='-C target-feature=+crt-static' or the equivalent via a
`.cargo/config.toml` file, and get a statically linked executable.
This requires libc 0.2.79, which adds support for static linking with
glibc.
Add `crt_static_respected` to the `linux_base` target spec.
Update `android_base` and `linux_musl_base` accordingly. Avoid enabling
crt_static_respected on Android platforms, since that hasn't been
tested.
Defer Apple SDKROOT detection to link time.
This defers the detection of the SDKROOT for Apple iOS/tvOS targets to link time, instead of when the `Target` is defined. This allows commands that don't need to link to work (like `rustdoc` or `rustc --print=target-list`). This also makes `--print=target-list` a bit faster.
This also removes the note in the platform support documentation about these targets being missing. When I wrote it, I misunderstood how the SDKROOT stuff worked.
Notes:
* This means that JSON spec targets can't explicitly override these flags. I think that is probably fine, as I believe the value is generally required, and can be set with the SDKROOT environment variable.
* This changes `x86_64-apple-tvos` to use `appletvsimulator`. I think the original code was wrong (it was using `iphonesimulator`). Also, `x86_64-apple-tvos` seems broken in general, and I cannot build it locally. The `data_layout` does not appear to be correct (it is a copy of the arm64 layout instead of the x86_64 layout). I have not tried building Apple's LLVM to see if that helps, but I suspect it is just wrong (I'm uncertain since I don't know how the tvOS simulator works with its bitcode-only requirements).
* I'm tempted to remove the use of `Result` for built-in target definitions, since I don't think they should be fallible. This was added in https://github.com/rust-lang/rust/pull/34980, but that only relates to JSON definitions. I think the built-in targets shouldn't fail. I can do this now, or not.
Fixes#36156Fixes#76584
might_permit_raw_init: also check aggregate fields
This is the next step for https://github.com/rust-lang/rust/issues/66151: when doing `mem::zeroed`/`mem::uninitialized`, also recursively check fields of aggregates (except for arrays) for whether they permit zero/uninit initialization.
This patch also:
* Add soft-float supports: only f32
* zero-extend i8/i16 to i32 because MIPS only supports register-length
arithmetic.
* Update table in asm! chapter in unstable book.
Return values up to 128 bits in registers
This fixes https://github.com/rust-lang/rust/issues/26494#issuecomment-619506345 by making Rust's default ABI pass return values up to 128 bits in size in registers, just like the System V ABI.
The result is that these methods from the comment linked above now generate the same code, making the Rust ABI as efficient as the `"C"` ABI:
```rust
pub struct Stats { x: u32, y: u32, z: u32, }
pub extern "C" fn sum_c(a: &Stats, b: &Stats) -> Stats {
return Stats {x: a.x + b.x, y: a.y + b.y, z: a.z + b.z };
}
pub fn sum_rust(a: &Stats, b: &Stats) -> Stats {
return Stats {x: a.x + b.x, y: a.y + b.y, z: a.z + b.z };
}
```
```asm
sum_rust:
movl (%rsi), %eax
addl (%rdi), %eax
movl 4(%rsi), %ecx
addl 4(%rdi), %ecx
movl 8(%rsi), %edx
addl 8(%rdi), %edx
shlq $32, %rcx
orq %rcx, %rax
retq
```
Late link args order
MSYS2 changed how winpthreads is built and as the result it now depends on more mingw-w64 libraries.
This PR affects only MinGW targets since nobody else is using `late_link_args_{dynamic,static}`. Now the order is similar to how it used to be before https://github.com/rust-lang/rust/pull/67502.