Rollup of 7 pull requests
Successful merges:
- rust-lang/rust#147701 (rustdoc: don't ignore path distance for doc aliases)
- rust-lang/rust#148735 (Fix ICE caused by invalid spans for shrink_file)
- rust-lang/rust#148839 (fix rtsan_nonblocking_async lint closure ICE)
- rust-lang/rust#148846 (add a test for combining RPIT with explicit tail calls)
- rust-lang/rust#148872 (fix: Do not ICE when missing match arm with ill-formed subty is met)
- rust-lang/rust#148880 (Remove explicit install of `eslint` inside of `tidy`'s Dockerfile)
- rust-lang/rust#148883 (bootstrap: dont require cmake if local-rebuild is enabled)
r? `@ghost`
`@rustbot` modify labels: rollup
fix: Do not ICE when missing match arm with ill-formed subty is met
Fixesrust-lang/rust#148192
The ICE comes from the following line, calling `normalize_erasing_regions` to a projection type whose trait bound is not met:
https://github.com/rust-lang/rust/blob/2fcbda6c1a70606bdb09857e01d01fc6229da712/compiler/rustc_pattern_analysis/src/rustc.rs#L185-L194
The above function is called while trying to lint missing match arms, or scrutinize ctors of missing(not necessary error) match arms.
So, the following code can trigger ICEs.
```rust
trait WhereTrait {
type Type;
}
fn foo(e: Enum) {
match e {
Enum::Map(_) => (), // ICE, while trying to lint missing arms
}
if let Enum::Map(_) = e {} // ICE, while trying to scrutinize missing ctors (even worse)
}
enum Enum {
Map(()),
Map2(<() as WhereTrait>::Type),
}
```
This ICE won't be triggered with the following code, as this is filtered out before `check_match` as the existence of ill-formed type inside the variant marks the body as tainted by error in `hir_typeck`, but for the above code, the `hir_typeck` complains nothing because everything it sees is locally correct.
```rust
fn foo(e: Enum) {
match e {
Enum::Map2(_) => (), // No ICE
}
}
```
I've considered visiting and wf checking for the match scrutinee before entering `check_match`, but that might regress the perf and I think just emitting delayed bug would enough as the normalization failure would be originated by other errors like ill-formdness.
Fix ICE caused by invalid spans for shrink_file
Fixesrust-lang/rust#148732
There are two issues in this function:
1. the original issue is caused by a typo error, which is fixed in the first commit
2. another different ice(Patch span `7..7` is beyond the end of buffer `0`) will be reported after fixing the first one, is caused by spans cross file boundaries due to macro expansion. It is fixed in the second commit.
r? `@nnethercote`
edited: also fixesrust-lang/rust#148684, added a new testcase for it in the last commit.
New format_args!() and fmt::Arguments implementation
Part of https://github.com/rust-lang/rust/issues/99012
This is a new implementation of `format_args!()` and `fmt::Arguments`. With this implementation, `fmt::Arguments` is only two pointers in size. (Instead of six, before.) This makes it the same size as a `&str` and makes it fit in a register pair.
---
This `fmt::Arguments` can store a `&'static str` _without any indirection_ or additional storage. This means that simple cases like `print_fmt(format_args!("hello"))` are now just as efficient for the caller as `print_str("hello")`, as shown by this example:
> code:
> ```rust
> fn main() {
> println!("Hello, world!");
> }
> ```
>
> before:
> ```asm
> main:
> sub rsp, 56
> lea rax, [rip + .Lanon_hello_world]
> mov qword ptr [rsp + 8], rax
> mov qword ptr [rsp + 16], 1
> mov qword ptr [rsp + 24], 8
> xorps xmm0, xmm0
> movups xmmword ptr [rsp + 32], xmm0
> lea rdi, [rsp + 8]
> call qword ptr [rip + std::io::stdio::_print]
> add rsp, 56
> ret
> ```
>
> after:
> ```asm
> main:
> lea rsi, [rip + .Lanon_hello_world]
> mov edi, 29
> jmp qword ptr [rip + std::io::stdio::_print]
> ```
(`panic!("Hello, world!");` shows a similar change.)
---
This implementation stores all static information as just a single (byte) string, without any indirection:
> code:
> ```rust
> format_args!("Hello, {name:-^20}!")
> ```
>
> lowering before:
> ```rust
> fmt::Arguments::new_v1_formatted(
> &["Hello, ", "!\n"],
> &args,
> &[
> Placeholder {
> position: 0usize,
> flags: 3355443245u32,
> precision: format_count::Implied,
> width: format_count::Is(20u16),
> },
> ],
> )
> ```
>
> lowering after:
> ```rust
> fmt::Arguments::new(
> b"\x07Hello, \xc3-\x00\x00\xc8\x14\x00\x02!\n\x00",
> &args,
> )
> ```
This saves a ton of pointers and simplifies the expansion significantly, but does mean that individual pieces (e.g. `"Hello, "` and `"!\n"`) cannot be reused. (Those pieces are often smaller than a pointer to them, though, in which case reusing them is useless.)
---
The details of the new representation are documented in [library/core/src/fmt/mod.rs](https://github.com/m-ou-se/rust/blob/new-fmt-args-alt/library/core/src/fmt/mod.rs#L609-L712).
fix(rustdoc): Color doctest errors
`@fmease's` [Deep analysis](https://github.com/rust-lang/rust/issues/148749#issuecomment-3508455278) on the problem
> Yeah, here's a deep analysis by me from a few weeks back of what's going on ([#148101 (comment)](https://github.com/rust-lang/rust/pull/148101#discussion_r2462756875)):
>
> > […]
> > However, since said PR ([#147207](https://github.com/rust-lang/rust/pull/147207): migrating coloring crates), `HumanEmitter::supports_color()` unconditionally(!) returns `false` (in fact, `Emitter::supports_color` is no longer used by anyone else and should be removed), so there's no reason to keep it. Rephrased, since that PR all compiler diagnostics for doctests are uncolored.
> > You could argue that I should keep it and patch `supports_color` in rustc to "work again". However, I'd rather rework our doctest coloring wholesale in a separate PR. At least before that migration PR, our setup was quite busted:
> >
> > 1. First of all, it didn't query+set `supports_color` for syntactically invalid doctests, so syntax errors were always shown without color (contrary to e.g., name resolution errors).
> > 2. Second of all, calling `supports_color()` here was quite frankly wrong: Piping the output of `rustdoc … --test` into a file (or `| cat` or whatever) did **not** suppress colors. I'm not actually sure if we can ever address that nicely (without stripping ANSI codes after the fact) since we pass that diagnostic to `libtest`, right? I might very well be wrong here, maybe it's a non-issue.
<hr>
```rust
/// ```
/// foo
/// ```
fn foo() {}
```
```
rustdoc --test lib.rs
```
Stable:
<img width="377" height="290" alt="stable" src="https://github.com/user-attachments/assets/cd20f947-b58d-42db-8735-797613baa9cc" />
Beta:
<img width="377" height="290" alt="beta" src="https://github.com/user-attachments/assets/f02588fd-41d2-4642-b03a-5554a68671eb" />
Nightly:
<img width="377" height="290" alt="nightly" src="https://github.com/user-attachments/assets/871cb417-f47e-4058-8a76-3bcd538ce141" />
After:
<img width="377" height="290" alt="after" src="https://github.com/user-attachments/assets/5734c01f-3f1c-44bb-9404-628c0c33b440" />
Note: This will need to be backported to `beta`
Fixes: rust-lang/rust#148749
rustc_target: introduce Abi, Env, Os
Improve type safety by using an enum rather than strings.
I'm not really sure this is better since only a few vendors have special semantics. r? ``@nnethercote``
Adjust spans into the `for` loops context before creating the new desugaring spans.
When lowering `for` loops, the spans for the `into_iter` call and the `Some` pattern used the span of the provided pattern and head expression. If either of those came from a different `SyntaxContext` this would result in some very strange contexts. e.g.:
```rust
macro_rules! m { ($e:expr) => { { $e } } }
for _ in m!(expr) {}
```
This would result in the `into_iter` call have a context chain of `desugar => m!() => root` which is completely nonsensical; `m!()` does not have a `for` loop. The `into_iter` call also ends up located at `{ $e }` rather than inside the `for _ in _` part.
This fixes that by walking the spans up to the `for` loop's context first. This will not handle adjusting the location of macro variable expansions (e.g. `for _ in $e`), but this does adjust the context to match the `for` loops.
---
This ended up causing rust-lang/rust-clippy#16008. Clippy should be using a `debug_assert` rather than `unreachable`, but it still results in a bug either way.
Improve diagnostics for buffer reuse with borrowed references
Addresses rust-lang/rust#147694
I'm not sure the current note wording is the best so I appreciate any feedback.
Simplify `jemalloc` setup
In the past, `#[used]` had to appear in the top-level crate to have a consistent effect on the linker. This has been fixed a while ago for ELF with the introduction of the `symbols.o` file in https://github.com/rust-lang/rust/pull/95604, and more recently for Mach-O in https://github.com/rust-lang/rust/pull/133832, which means that libraries can now implement the required workarounds themselves. This allows moving these `#[used]` declarations out of our `main.rs`.
Specifically, I have moved them into `tikv-jemalloc-sys` where they belong in https://github.com/tikv/jemallocator/pull/109 and done the same for `mimalloc` in https://github.com/purpleprotocol/mimalloc_rust/pull/146 (in case we want to experiment with switching to that one day).
Test with:
```sh
./x build library src/tools/rustdoc src/tools/clippy --set rust.jemalloc=true
# macOS
lldb -- ./build/host/stage1/bin/rustc -vV
(lldb) b _rjem_je_zone_register
(lldb) run
# Should breakpoint, this means that the allocator was properly linked
# Linux
lldb -- ./build/host/stage1/bin/rustc -vV
(lldb) b malloc
(lldb) run
# Should breakpoint, inspect that the `malloc` symbol comes from the `rustc` binary and not from `libc`
```
try-job: `aarch64-gnu`
try-job: `dist-aarch64-linux`
try-job: `dist-x86_64-musl`
try-job: `dist-x86_64-apple`
try-job: `dist-aarch64-apple`
Prepare for additional enums like Vendor and Os which have true
`Unknown` variants. We want to use the same name for the escape hatch
for all of these, thus rename this one.
cleanup: merge `RvalueScopes` into `ScopeTree`
This gets rid of `RvalueCandidate`, inlines the definition of `RvalueScopes` into `ScopeTree`, and removes two `RvalueScopes`-specific modules, consolidating the scoping logic a bit. Removing the extra step of going from `RvalueCandidate`s to `RvalueScopes` and removing the duplication between them should also hopefully improve perf.
I've also taken the liberty of doing a bit of renaming and comment updates, changing some "rvalue scope"s to "extended temporary scope"s. This is a bit closer to the Reference's terminology and makes it clearer that it's specific to temporary lifetime extension. This isn't comprehensive. In particular, I've left `record_rvalue_scope_if_borrow_expr` untouched since rust-lang/rust#146098 gets rid of it.
Pulled out from rust-lang/rust#146098.
r? BoxyUwU as the reviewer of rust-lang/rust#146098 (though feel free to reassign/claim! this is just cleanup)
cc `@dingxiangfei2009`
This is useful when you have two dependencies that use different trait for
the same thing and with the same name. The user can accidentally implement
the bad one which might be confusing. This commits refactorizes existing
diagnostics about multiple different crates with the same version and adds
a note when similarly named traits are found. All diagnostics are merged
into a single one.
Document (and test) a problem with `Clone`/`Copy` deriving.
I think this is useful information. I have worked on `derive` impls quite a bit and didn't know about this issue until today.
r? `@saethlin`
Implement DynSend and DynSync for std::panic::Location.
Allows the compiler to build with the `debug_refcell` stdlib cargo feature.
With `rust.std-features = ["debug_refcell"]` in bootstrap.toml, `./x.py build --stage 2` fails before this patch, and succeeds afterwards.
<details> <summary>error for `./x.py build --stage 2` before this patch</summary>
```Rust
error[E0277]: `NonNull<str>` doesn't implement `DynSync`. Add it to `rustc_data_structures::marker` or use `IntoDynSyncSend` if it's already `Sync`
--> compiler/rustc_query_system/src/dep_graph/serialized.rs:719:33
|
719 | let results = broadcast(|_| {
| _______________________---------_^
| | |
| | required by a bound introduced by this call
720 | | let mut local = self.local.borrow_mut();
... |
734 | | });
| |_________^ within `Location<'static>`, the trait `DynSync` is not implemented for `NonNull<str>`
|
note: required because it appears within the type `Location<'static>`
--> /home/zachary/opt_mount/zachary/Programming/rust-compiler-2/library/core/src/panic/location.rs:39:12
|
39 | pub struct Location<'a> {
| ^^^^^^^^
= note: required for `&'static Location<'static>` to implement `DynSend`
note: required because it appears within the type `std::option::Option<&'static Location<'static>>`
--> /home/zachary/opt_mount/zachary/Programming/rust-compiler-2/library/core/src/option.rs:599:10
|
599 | pub enum Option<T> {
| ^^^^^^
note: required because it appears within the type `std::cell::UnsafeCell<std::option::Option<&'static Location<'static>>>`
--> /home/zachary/opt_mount/zachary/Programming/rust-compiler-2/library/core/src/cell.rs:2289:12
|
2289 | pub struct UnsafeCell<T: ?Sized> {
| ^^^^^^^^^^
note: required because it appears within the type `Cell<std::option::Option<&'static Location<'static>>>`
--> /home/zachary/opt_mount/zachary/Programming/rust-compiler-2/library/core/src/cell.rs:313:12
|
313 | pub struct Cell<T: ?Sized> {
| ^^^^
note: required because it appears within the type `RefCell<LocalEncoderState>`
--> /home/zachary/opt_mount/zachary/Programming/rust-compiler-2/library/core/src/cell.rs:822:12
|
822 | pub struct RefCell<T: ?Sized> {
| ^^^^^^^
= note: required for `rustc_data_structures::sync::WorkerLocal<RefCell<LocalEncoderState>>` to implement `DynSync`
note: required because it appears within the type `EncoderState<D>`
--> compiler/rustc_query_system/src/dep_graph/serialized.rs:546:8
|
546 | struct EncoderState<D: Deps> {
| ^^^^^^^^^^^^
= note: required because it appears within the type `&EncoderState<D>`
note: required because it's used within this closure
--> compiler/rustc_query_system/src/dep_graph/serialized.rs:719:33
|
719 | let results = broadcast(|_| {
| ^^^
note: required by a bound in `rustc_data_structures::sync::broadcast`
--> /home/zachary/opt_mount/zachary/Programming/rust-compiler-2/compiler/rustc_data_structures/src/sync/parallel.rs:239:56
|
239 | pub fn broadcast<R: DynSend>(op: impl Fn(usize) -> R + DynSync) -> Vec<R> {
| ^^^^^^^ required by this bound in `broadcast`
For more information about this error, try `rustc --explain E0277`.
error: could not compile `rustc_query_system` (lib) due to 1 previous error
warning: build failed, waiting for other jobs to finish...
Build completed unsuccessfully in 0:02:04
```
</details>
Port `cfg_select!` to the new attribute parsing system
Best reviewed commit by commit, since it involves some moving around of code
r? `````@jdonszelmann`````