raw-dylib is a link kind that allows rustc to link against a library
without having any library files present.
This currently only exists on Windows. rustc will take all the symbols
from raw-dylib link blocks and put them in an import library, where they
can then be resolved by the linker.
While import libraries don't exist on ELF, it would still be convenient
to have this same functionality. Not having the libraries present at
build-time can be convenient for several reasons, especially
cross-compilation. With raw-dylib, code linking against a library can be
cross-compiled without needing to have these libraries available on the
build machine. If the libc crate makes use of this, it would allow
cross-compilation without having any libc available on the build
machine. This is not yet possible with this implementation, at least
against libc's like glibc that use symbol versioning.
The raw-dylib kind could be extended with support for symbol versioning
in the future.
This implementation is very experimental and I have not tested it very
well. I have tested it for a toy example and the lz4-sys crate, where it
was able to successfully link a binary despite not having a
corresponding library at build-time.
Change interners to start preallocated with an increased capacity
Inspired by https://github.com/rust-lang/rust/issues/137005.
Added a `with_capacity` function to `InternedSet`. Changed the `CtxtInterners` to start with `InternedSets` preallocated with a capacity.
This *does* increase memory usage at very slightly(by ~1 MB at the start), altough that increase quickly disaperars for larger crates(since they require such capacity anyway).
A local perf run indicates this improves compiletimes for small crates(like `ripgrep`), without a negative effect on larger ones.
Include version number of libs being built in cargo lib metadata (esp. `librustc_driver*.so`)
Previously, on a non-stable channel, it's possible for two builds from different versioned sources (e.g. 1.84.0 vs 1.84.1) to produce a `librustc_driver*.so` with the same filename hashes. This causes problems with side-by-side installs wrt. linker search paths because 1.84.1 rustc bin and 1.84.0 rustc bin may try to link to the "same" `librustc_driver*.so` (same filename hash) but fail because the contents of the so is actually different.
We try to mitigate this by including the version number of artifacts being built via `__CARGO_DEFAULT_LIB_METADATA` (kind of an ugly hack, but I don't think cargo has a way for us to tell cargo to use a package version override).
Fixes#136701 (mitigates, really).
### Testing
Tested manually[^host] by:
```bash
$ cat src/version
1.86.0
$ ./x build library # w/ compiler profile, (non-stable) dev channel
$ lddtree build/host/stage1/bin/rustc
rustc => build/host/stage1/bin/rustc (interpreter => /lib64/ld-linux-x86-64.so.2)
librustc_driver-ea1b1b2291881cc4.so => build/host/stage1/bin/../lib/librustc_driver-ea1b1b2291881cc4.so
[...]
```
and observing that changing `src/version` to bump a point release causes `librustc_driver*.so` to have a different hash while sources are unmodified otherwise.
```bash
$ cat src/version
1.86.1
$ ./x build library # w/ compiler profile, (non-stable) dev channel
$ lddtree build/host/stage1/bin/rustc
rustc => build/host/stage1/bin/rustc (interpreter => /lib64/ld-linux-x86-64.so.2)
librustc_driver-746badadbcb74721.so => build/host/stage1/bin/../lib/librustc_driver-746badadbcb74721.so
[...]
```
cc `@clan` `@demize` could you check that if you backport this change against 1.84.{0,1} as reported in #136701, that the produced `rustc` binary works, under the context of the Gentoo build system setup?
[^host]: on a `x86_64-unknown-linux-gnu` host, no cross
Build GCC on CI
Previously, we have downloaded a specific commit of GCC and prebuilt it inside Docker using the `build-gccjit.sh` script. This PR removes that scripts and uses the bootstrap GCC step. This allows us to use the `src/gcc` submodule for determining which GCC should be built, and it also moves the logic closer to LLVM, which is also built by bootstrap.
A few things to note:
- The `sccache` option is currently in the `llvm` block, so the GCC build uses `llvm.ccache`, which is a bit weird :) We could either add `gcc.ccache`, or (what I think would be better) to just move `ccache` to the `build` section, as I don't think that it will be necessary to use ccache for LLVM, but not for GCC.
- When the GCC codegen backend is built, it needs to depend on a step that first builds GCC. This is currently done in a hacky way. The proper solution is to create a separate step for the GCC codegen backend, but that is a larger change. Let me know what you think.
r? `@onur-ozkan`
try-job: i686-msvc-1
try-job: x86_64-mingw-1
Make `#[used]` work when linking with `ld64`
To make `#[used]` work in static libraries, we use the `symbols.o` trick introduced in https://github.com/rust-lang/rust/pull/95604.
However, the linker shipped with Xcode, ld64, works a bit differently from other linkers; in particular, [it completely ignores undefined symbols by themselves](https://github.com/apple-oss-distributions/ld64/blob/ld64-954.16/src/ld/parsers/macho_relocatable_file.cpp#L2455-L2468), and only consider them if they have relocations (something something atoms something fixups, I don't know the details).
So to make the `symbols.o` file work on ld64, we need to actually insert a relocation. That's kinda cumbersome to do though, since the relocation must be valid, and hence must point to a valid piece of machine code, and is hence very architecture-specific.
Fixes https://github.com/rust-lang/rust/issues/133491, see that for investigation.
---
Another option would be to pass `-u _foo` to the final linker invocation. This has the problem that `-u` causes the linker to not be able to dead-strip the symbol, which is undesirable. (If we did this, we would possibly also want to do it by putting the arguments in a file by itself, and passing that file via ``@`,` e.g. ``@undefined_symbols.txt`,` similar to https://github.com/rust-lang/rust/issues/52699, though that [is only supported since Xcode 12](https://developer.apple.com/documentation/xcode-release-notes/xcode-12-release-notes#Linking), and I'm not sure we wanna bump that).
Various other options that are probably all undesirable as they affect link time performance:
- Pass `-all_load` to the linker.
- Pass `-ObjC` to the linker (the Objective-C support in the linker has different code paths that load more of the binary), and instrument the binaries that contain `#[used]` symbols.
- Pass `-force_load` to libraries that contain `#[used]` symbols.
Failed attempt: Embed `-u _foo` in the object file with `LC_LINKER_OPTION`, akin to https://github.com/rust-lang/rust/issues/121293. Doesn't work, both because `ld64` doesn't read that from archive members unless it already has a reason to load the member (which is what this PR is trying to make it do), and because `ld64` only support the `-l`, `-needed-l`, `-framework` and `-needed_framework` flags in there.
---
TODO:
- [x] Support all Apple architectures.
- [x] Ensure that this works regardless of the actual type of the symbol.
- [x] Write up more docs.
- [x] Wire up a few proper tests.
`@rustbot` label O-apple
librustdoc: Use `pulldown-cmark-escape` for HTML escaping
Implementation of `@notriddle` 's [suggestion](https://github.com/rust-lang/rust/pull/137274#issuecomment-2669001585).
Somewhat related to #137274 , but the two PRs should be complementary.
Local perf results look like a nice improvement! (so would love a perf run on the CI)
Emit getelementptr inbounds nuw for pointer::add()
Lower pointer::add (via intrinsic::offset with unsigned offset) to getelementptr inbounds nuw on LLVM versions that support it. This lets LLVM make use of the pre-condition that the offset addition does not wrap in an unsigned sense. Together with inbounds, this also implies that the offset is non-negative.
Fixes https://github.com/rust-lang/rust/issues/137217.
vectorcall ABI: require SSE2
According to the official docs at https://learn.microsoft.com/en-us/cpp/cpp/vectorcall, SSE2 is required for this ABI. Add a check that enforces this.
I put this together with the other checks ensuring the target features required for a function are present... however, since the ABI is known pre-monomorphization, it would be possible to do this check earlier, which would have the advantage of checking even in `cargo check`. It would have the disadvantage of spreading this code in yet more places.
The first commit just does a little refactoring of the mono-time ABI check to make it easier to add the new check.
Cc `@workingjubilee`
try-job: dist-i586-gnu-i586-i686-musl
Rollup of 9 pull requests
Successful merges:
- #135354 ([Debuginfo] Add MSVC Synthetic and Summary providers to LLDB)
- #136826 (Replace mem::zeroed with mem::MaybeUninit::uninit for large struct in Unix)
- #137194 (More const {} init in thread_local)
- #137334 (Greatly simplify lifetime captures in edition 2024)
- #137382 (bootstrap: add doc for vendor build step)
- #137423 (Improve a bit HIR pretty printer)
- #137435 (Fix "missing match arm body" suggestion involving `!`)
- #137448 (Fix bugs due to unhandled `ControlFlow` in compiler)
- #137458 (Fix missing self subst when rendering `impl Fn*<T>` with no output type)
r? `@ghost`
`@rustbot` modify labels: rollup
Improve a bit HIR pretty printer
This PR improve (a bit) the HIR pretty printer.
It does so by:
- Not printing elided lifetimes (those are not expressible in surface Rust anyway)
- And by rendering implicit self with the shorthand syntax
I also tried fixing some indentation and other things but gave up for now.
Best reviewed commit by commit.
Replace mem::zeroed with mem::MaybeUninit::uninit for large struct in Unix
As discussion in #136737.
- Replace `mem::zeroed()` with `MaybeUninit::uninit()` for `sockaddr_storage` in `accept()` and `recvfrom()` since these functions fill in the address structure
- Replace `mem::zeroed()` with `MaybeUninit::uninit()` for `pthread_attr_t` in thread-related functions since `pthread_attr_init()` initializes the structure
- Add references to man pages to document this behavior
[Debuginfo] Add MSVC Synthetic and Summary providers to LLDB
Adds handling for `tuple$<>`, `ref$<slice$2<>`, `ref$<str$>` and `enum2$<>`.
Also fixes a bug in MSVC vec/string handling where the script was unable to determine the element's type due to LLDB ignoring template arg debug information
<details>
<summary>Sample code</summary>
```rust
pub enum Number {
One = 57,
Two = 99,
}
#[repr(u8)]
pub enum Container {
First(u32),
Second { val: u64, val2: i8 },
Third,
}
...
let u8_val = b'a';
let float = 42.78000000000001;
let tuple = (u8_val, float);
let str_val = "eef";
let mut string = "freef".to_owned();
let mut_str = string.as_mut_str();
let array: [u8; 4] = [1, 2, 3, 4];
let ref_array = array.as_slice();
let mut array2: [u32; 4] = [1, 2, 3, 4];
let mut_array = array2.as_mut_slice();
let enum_val = Number::One;
let mut enum_val2 = Number::Two;
let sum_val = Container::First(15);
let sum_val_2 = Container::Second { val: 0, val2: 0 };
let sum_val_3 = Container::Third;
let non_zero = NonZeroU128::new(100).unwrap();
let large_discr = NonZeroU128::new(255);
```
</details>
Before:

After:

try-job: aarch64-apple
try-job: x86_64-msvc-1
try-job: i686-msvc-1
try-job: x86_64-mingw-1
try-job: i686-mingw
try-job: aarch64-gnu
stabilize stage management for rustc tools
https://github.com/rust-lang/rust/pull/135990 got out of control due to excessive complexity. This PR aims to achieve the same goal with a simpler approach, likely through multiple smaller PRs. I will keep the other one read-only and open as a reference for future work.
This work stabilizes the staging logic for `ToolRustc` programs, so you no longer need to handle build and target compilers separately in steps. Previously, most tools didn't do this correctly, which was causing the compiler to be built twice (e.g., `x test cargo --stage 1` would compile the stage 2 compiler before, but now it only compiles the stage 1 compiler).
I also tried to document how we should write `ToolRustc` steps as they are quite different and require more attention than other tools.
Next goal is to stabilize how stages are handled for the rustc itself. Currently, `x build --stage 1` builds the stage 1 compiler which is fine, but `x build compiler --stage 1` builds stage 2 compiler.
~~for now, r? ghost~~
Remove `NtVis` and `NtTy`
The next part of #124141. The first actual remove of `Nonterminal` variants. `NtVis` is a simple case that doesn't get much use, but `NtTy` is more complex.
r? `@petrochenkov`
Emit `trunc nuw` for unchecked shifts and `to_immediate_scalar`
- For shifts this shrinks the IR by no longer needing an `assume` while still providing the UB information
- Having this on the `i8`→`i1` truncations will hopefully help with some places that have to load `i8`s or pass those in LLVM structs without range information
Bump sccache in CI to 0.9.1
We haven't updated the used sccache version for years, it has accrued a bunch of fixes and features in the meantime. It now supports the `--show-adv-stats` flag, which gives a more detailed summary of the results of caching. And it can also cache Rust code, which could be useful in the future (https://github.com/rust-lang/rust/pull/136942 - although now there are no large wins).
It also supports caching PGO now, but since the PGO profiles are always different, it won't make any real difference.
https://github.com/rust-lang/rust/pull/133076 previously tried to update the version to 0.3 (CC `@klensy)`
r? `@marcoieni`
Organize `OsString`/`OsStr` shims
Synchronize the `bytes.rs` and `wtf8.rs` shims for `OsString`/`OsStr` so they're easier to diff between each other. This is mostly ordering items the same between the two. I tried to minimize moves and went for the average locations between the files.
With them in the same order, it is clear that `FromInner<_>` is not implemented for `bytes::Buf` and `Clone::clone_from` is not implemented for `wtf8::Buf`, but they are for the other. Fix that.
I added #[inline] to all inherent methods of the `OsString`/`OsStr` shims, because it seemed that was already the rough pattern. `bytes.rs` has more inlining than `wtf8.rs`, so I added the corresponding ones to `wtf8.rs`. Then, the common missing ones have no discernible pattern to me. They're not divided by non-allocating/allocating. Perhaps the pattern is that UTF-8 validation isn't inlined? Since these types are merely the inner values in `OsStr`/`OsString`, I put inline on all methods and let those public types dictate inlining. I have not inspected codegen or run benchmarks.
Also, touch up some (private) documentation comments.
r? ``````@ChrisDenton``````
Lint `#[must_use]` attributes applied to methods in trait impls
The `#[must_use]` attribute has no effect when applied to methods in trait implementations. This PR adds it to the unused `#[must_use]` lint, and cleans the extra attributes in portable-simd and Clippy.
CI: Stop /msys64/bin from being prepended to PATH in msys2 shell
We used to do this along time ago but we stopped doing it when we started installing msys2 manually. 4fd3cf96a1/src/ci/scripts/install-msys2.sh (L11-L13)Fixes#136795
try-job: dist-i686-mingw
Use more explicit and reliable ptr select in sort impls
Using `if ...` with the intent to avoid branches can be surprising to readers and carries the risk of turning into jumps/branches generated by some future compiler version, breaking crucial optimizations.
This commit replaces their usage with the explicit and IR annotated `bool::select_unpredictable`.
Add `MAX_LEN_UTF8` and `MAX_LEN_UTF16` Constants
This pull request adds the `MAX_LEN_UTF8` and `MAX_LEN_UTF16` constants as per #45795, gated behind the `char_max_len` feature.
The constants are currently applied in the `alloc`, `core` and `std` libraries.
coverage: Get hole spans from nested items without fully visiting them
This is a small simplification to the code that collects the spans of nested items within a function, so that those spans can be treated as “holes” to be avoided by the current function's coverage mappings.
The old code was using `nested_filter::All` to ensure that the visitor would see nested items. But we don't need the actual items themselves; we just need their spans, which we can obtain via a custom implementation of `visit_nested_item`.
This avoids the more expansive queries required by `nested_filter::All`.
Don't mention `FromResidual` on bad `?`
Unless `try_trait_v2` is enabled, don't mention that `FromResidual` isn't implemented for a specific type when the implicit `From` conversion of a `?` fails. For the end user on stable, `?` might as well be a compiler intrinsic, so we remove that note to avoid further confusion and allowing other parts of the error to be more prominent.
```
error[E0277]: `?` couldn't convert the error to `u8`
--> $DIR/bad-interconversion.rs:4:20
|
LL | fn result_to_result() -> Result<u64, u8> {
| --------------- expected `u8` because of this
LL | Ok(Err(123_i32)?)
| ------------^ the trait `From<i32>` is not implemented for `u8`
| |
| this can't be annotated with `?` because it has type `Result<_, i32>`
|
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
= help: the following other types implement trait `From<T>`:
`u8` implements `From<Char>`
`u8` implements `From<bool>`
```
Add a bullet point to `std::fs::copy`
I needed to copy a file but I got the following error:
```
Os { code: 2, kind: NotFound, message: "No such file or directory" }
```
After read the documentation, I though the error was generated by the `from` parameter, forgetting the `to` part. Anyway, I got the error because the parent folder of `to` didn't exist.
Even if the documentation explicitly saying `but is not limited to just these cases`, I would like to add this case because I spent 3 hours around it.
This PR just wants to put a mention about it.
Added project-specific Zed IDE settings
This repository currently has project-specific VS Code IDE settings in `.vscode` and `compiler/rustc_codegen_cranelift/.vscode`. Now there are equivalent project-specific Zed IDE settings alongside those.
This fixes `rust-analyzer` not being able to properly handle this project.
Note that:
1. The contents of `src/tools/rust-analyzer/.vscode` could not be translated to Zed, as they aren't basic IDE settings.
2. One of the VS Code settings in `.vscode` has no corresponding setting in Zed, and so this has been noted like this:
```json
"_settings_only_in_vs_code_not_yet_in_zed": {
"git.detectSubmodulesLimit": 20
},
```
improve cold_path()
#120370 added a new instrinsic `cold_path()` and used it to fix `likely` and `unlikely`
However, in order to limit scope, the information about cold code paths is only used in 2-target switch instructions. This is sufficient for `likely` and `unlikely`, but limits usefulness of `cold_path` for idiomatic rust. For example, code like this:
```
if let Some(x) = y { ... }
```
may generate 3-target switch:
```
switch y.discriminator:
0 => true branch
1 = > false branch
_ => unreachable
```
and therefore marking a branch as cold will have no effect.
This PR improves `cold_path()` to work with arbitrary switch instructions.
Note that for 2-target switches, we can use `llvm.expect`, but for multiple targets we need to manually emit branch weights. I checked Clang and it also emits weights in this situation. The Clang's weight calculation is more complex that this PR, which I believe is mainly because `switch` in `C/C++` can have multiple cases going to the same target.
Rollup of 7 pull requests
Successful merges:
- #137095 (Replace some u64 hashes with Hash64)
- #137100 (HIR analysis: Remove unnecessary abstraction over list of clauses)
- #137105 (Restrict DerefPure for Cow<T> impl to T = impl Clone, [impl Clone], str.)
- #137120 (Enable `relative-path-include-bytes-132203` rustdoc-ui test on Windows)
- #137125 (Re-add missing empty lines in the releases notes)
- #137145 (use add-core-stubs / minicore for a few more tests)
- #137149 (Remove SSE ABI from i586-pc-windows-msvc)
r? `@ghost`
`@rustbot` modify labels: rollup
Restrict DerefPure for Cow<T> impl to T = impl Clone, [impl Clone], str.
Fixes#136046
`feature(deref_patterns)` tracking issue: https://github.com/rust-lang/rust/issues/87121
`Cow<'_, T>` should only implement `DerefPure` if its `Deref` impl is pure, which requires `<T::Owned as Borrow<T>>::borrow` to be pure. This PR restricts `impl DerefPure for Cow<'_, T>` to `T: Sized + Clone`, `T = [U: Clone]`, and `T = str` (for all of whom `<T::Owned as Borrow<T>>::borrow` is implemented in the stdlib and is pure).
cc ``@Nadrieril``
------
An alternate approach would be to introduce a new `unsafe trait BorrowPure<T>` analogous to `DerefPure` that could be implemented for `T: Sized`, `&T`, `&mut T`, `String`, `Vec`, `Box`, `PathBuf`, `OsString`, etc. https://github.com/rust-lang/rust/compare/master...zachs18:borrow-pure-trait
HIR analysis: Remove unnecessary abstraction over list of clauses
`rustc_hir_analysis::bounds::Bounds` with its methods is nowadays a paper-thin wrapper around `Vec<(Clause, Span)>`s and `Vec::push` essentially.
Its existence slightly annoyed me (and I keep opening its corresp. file instead of the identically named `bounds.rs` in `hir_ty_lowering/` that I actually want most of the time :P).
Opening to check if you agree with inlining it.
r? compiler-errors or reassign
Replace some u64 hashes with Hash64
I introduced the Hash64 and Hash128 types in https://github.com/rust-lang/rust/pull/110083, essentially as a mechanism to prevent hashes from landing in our leb128 encoding paths. If you just have a u64 or u128 field in a struct then derive Encodable/Decodable, that number gets leb128 encoding. So if you need to store a hash or some other value which behaves very close to a hash, don't store it as a u64.
This reverts part of https://github.com/rust-lang/rust/pull/117603, which turned an encoded Hash64 into a u64.
Based on https://github.com/rust-lang/rust/pull/110083, I don't expect this to be perf-sensitive on its own, though I expect that it may help stabilize some of the small rmeta size fluctuations we currently see in perf reports.
Fix const items not being allowed to be called `r#move` or `r#static`
Because of an ambiguity with const closures, the parser needs to ensure that for a const item, the `const` keyword isn't followed by a `move` or `static` keyword, as that would indicate a const closure:
```rust
fn main() {
const move // ...
}
```
This check did not take raw identifiers into account, therefore being unable to distinguish between `const move` and `const r#move`. The latter is obviously not a const closure, so it should be allowed as a const item.
This fixes the check in the parser to only treat `const ...` as a const closure if it's followed by the *proper keyword*, and not a raw identifier.
Additionally, this adds a large test that tests for all raw identifiers in all kinds of positions, including `const`, to prevent issues like this one from occurring again.
fixes#137128
Use `const_error!` when possible
Replace usages of `io::Error::new(io::ErrorKind::Variant, "constant string")` with `io::const_error!(io::ErrorKind::Variant, "constant string")` to avoid allocations when possible. Additionally, fix `&&str` error messages in SGX and missing/misplaced trailing commas in `const_error!`.