Rollup of 7 pull requests
Successful merges:
- #113565 (Make SIGSEGV handler emit nicer backtraces)
- #114704 (parser: not insert dummy field in struct)
- #115272 (miri/diagnostics: don't forget to print_backtrace when ICEing on unexpected errors)
- #115313 (Make `get_return_block()` return `Some` only for HIR nodes in body)
- #115347 (suggest removing `impl` in generic trait bound position)
- #115355 (new solver: handle edge case of a recursion limit of 0)
- #115363 (Don't suggest adding parentheses to call an inaccessible method.)
r? `@ghost`
`@rustbot` modify labels: rollup
Don't suggest adding parentheses to call an inaccessible method.
Previously, code of this form would emit E0615 (attempt to use a method as a field), thus emphasizing the existence of private methods that the programmer probably does not care about. Now it ignores their existence instead, producing error E0609 (no field). The motivating example is:
```rust
let x = std::rc::Rc::new(());
x.inner;
```
which would previously mention the private method `Rc::inner()`, even though `Rc<T>` intentionally has no public methods so that it can be a transparent smart pointer for any `T`.
```rust
error[E0615]: attempted to take value of method `inner` on type `Rc<()>`
--> src/main.rs:3:3
|
3 | x.inner;
| ^^^^^ method, not a field
|
help: use parentheses to call the method
|
3 | x.inner();
| ++
```
With this change, it emits E0609 and no suggestion.
new solver: handle edge case of a recursion limit of 0
Apparently a recursion limit of 0 is possible/valid/useful/used/cute, the more you know 🌟 .
(It's somewhat interesting to me that the old solver seemingly handles this, and that the new solver currently requires a recursion limit of 2 here)
r? `@compiler-errors.`
Fixes#115351.
suggest removing `impl` in generic trait bound position
rustc already does this recovery in type param position (`<T: impl Trait>` -> `<T: Trait>`).
This PR also adds that suggestion in trait bound position (e.g. `where T: impl Trait` or `trait Trait { type Assoc: impl Trait; }`)
Make `get_return_block()` return `Some` only for HIR nodes in body
Fixes#114918
The issue occurred while compiling the following input:
```rust
fn uwu() -> [(); { () }] {
loop {}
}
```
It was caused by the code below trying to suggest a missing return type which resulted in a const eval cycle: 1bd043098e/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs (L68-L75)
The root cause was `get_return_block()` returning an `Fn` node for a node in the return type (i.e. the second `()` in the return type `[(); { () }]` of the input) although it is supposed to do so only for nodes that lie in the body of the function and return `None` otherwise (at least as per my understanding).
The PR fixes the issue by fixing this behaviour of `get_return_block()`.
parser: not insert dummy field in struct
Fixes#114636
This PR eliminates the dummy field, initially introduced in #113999, thereby enabling unrestricted use of `ident.unwrap()`. A side effect of this action is that we can only report the error of the first macro invocation field within the struct node.
An alternative solution might be giving a virtual name to the macro, but it appears more complex.(https://github.com/rust-lang/rust/issues/114636#issuecomment-1670228715). Furthermore, if you think https://github.com/rust-lang/rust/issues/114636#issuecomment-1670228715 is a better solution, feel free to close this PR.
Make SIGSEGV handler emit nicer backtraces
This annotates the code heavily with comments to explain what is going on, for the benefit of other compiler contributors. The backtrace also emits appropriate comments to clarify, to a programmer who may not know why a bunch of file paths and hexadecimal blather was just dumped into stderr, what is going on. Finally, it detects cycles and uses their regularity to avoid repeating a bunch of text. The previous backtraces we were emitting was extremely unfriendly, potentially confusing, and often alarming, and this makes things almost "nice".
We can't necessarily make them much nicer than this, because a signal handler must use "signal-safe" functions. This precludes conveniences like dynamic allocations. Fortunately, Rust's stdlib has allocation-free formatting, but it may hinder integrating this error with our localization middleware, as I wasn't able to clearly ascertain, at a glance, whether there was a zero-alloc path through it.
r? `@Nilstrieb`
Adapt table sizes to the contents
This is an implementation of https://github.com/rust-lang/compiler-team/issues/666
The objective of this PR is to permit the rmeta format to accommodate larger crates that need offsets larger than a `u32` can store without compromising performance for crates that do not need such range. The second commit is a number of tiny optimization opportunities I noticed while looking at perf recordings of the first commit.
The rmeta tables need to have fixed-size elements to permit lazy random access. But the size only needs to be fixed _per table_, not per element type. This PR adds another `usize` to the table header which indicates the table element size. As each element of a table is set, we keep track of the widest encoded table value, then don't bother encoding all the unused trailing bytes on each value. When decoding table elements, we copy them to a full-width array if they are not already full-width.
`LazyArray` needs some special treatment. Most other values that are encoded in tables are indexes or offsets, and those tend to be small so we get to drop a lot of zero bytes off the end. But `LazyArray` encodes _two_ small values in a fixed-width table element: A position of the table and the length of the table. The treatment described above could trim zero bytes off the table length, but any nonzero length shields the position bytes from the optimization. To improve this, we interleave the bytes of position and length. This change is responsible for about half of the crate metadata win on many crates.
Fixes https://github.com/rust-lang/rust/issues/112934 (probably)
Fixes https://github.com/rust-lang/rust/issues/103607
Previously, the test code would emit E0615, thus revealing the existence
of private methods that the programmer probably does not care about.
Now it ignores their existence instead, producing error E0609 (no field).
The motivating example is:
```rust
let x = std::rc::Rc::new(());
x.inner;
```
which would previously mention the private method `Rc::inner()`, even
though `Rc<T>` intentionally has no public methods so that it can be a
transparent smart pointer for any `T`.
Always add LC_BUILD_VERSION for metadata object files
As of Xcode 15 Apple's linker has become a bit more strict about the warnings it produces. One of those new warnings requires all valid Mach-O object files in an archive to have a LC_BUILD_VERSION load command:
```
ld: warning: no platform load command found in 'ARCHIVE[arm64][2106](lib.rmeta)', assuming: iOS-simulator
```
This was already being done for Mac Catalyst so this change expands this logic to include it for all Apple platforms. I filed this behavior change as FB12546320 and was told it was the new intentional behavior.
Tweaks and improvements on SMIR around generics_of and predicates_of
r? `@oli-obk`
This allows an API like the following ...
```rust
let trait_decls = stable_mir::all_trait_decls().iter().map(|trait_def| {
let trait_decl = stable_mir::trait_decl(trait_def);
let generics = trait_decl.generics_of();
let predicates = trait_decl.predicates_of().predicates;
```
I didn't like that much `trait_def.trait_decl()` which is it possible but adding a method to a def_id that loads up a whole trait definition looks backwards to me.
Remove conditional use of `Sharded` from query state
`Sharded` is already a zero cost abstraction, so it shouldn't affect the performance of the single thread compiler if LLVM does its job.
r? `@cjgillot`
Use `preserve_mostcc` for `extern "rust-cold"`
As experimentation in #115242 has shown looks better than `coldcc`. Notably, clang exposes `preserve_most` (https://clang.llvm.org/docs/AttributeReference.html#preserve-most) but not `cold`, so this change should put us on a better-supported path.
And *don't* use a different convention for cold on Windows, because that actually ends up making things worse. (See comment in the code.)
cc tracking issue #97544
miri ABI compatibility check: accept u32 and i32
If only the sign differs, then surely these types are compatible. (We do still check that `arg_ext` is the same, just in case.)
Also I made it so that the ABI check must *imply* that size and alignment are the same, but it doesn't actively check that itself. With how crazy ABI constraints get, having equal size and align really shouldn't be used as a signal for anything I think...
Make RPITITs capture all in-scope lifetimes
Much like #114616, this implements the lang team decision from this T-lang meeting on [opaque captures strategy moving forward](https://hackmd.io/sFaSIMJOQcuwCdnUvCxtuQ?view). This will be RFC'd soon, but given that RPITITs are a nightly feature, this shouldn't necessarily be blocked on that.
We unconditionally capture all lifetimes in RPITITs -- impl is not as simple as #114616, since we still need to duplicate RPIT lifetimes to make sure we reify any late-bound lifetimes in scope.
Closes#112194
don't use SnapshotVec in Graph implementation, as it looks unused; use Vec instead
`Graph` don't use `SnapshotVec` methods, so use simple `Vec` instead?
More precisely detect cycle errors from type_of on opaque
Not sure if this still needs work. Just putting it up for initial impressions, since it seems that a few people are frustrated with the increased error verbosity due to #113320.
Essentially we introduce a new sub-query for `type_of` specifically for opaques which returns a value that is able to distinguish "has errors" from "due to cycle recovery".
Fixes#115188
r? `@oli-obk`
codegen_llvm/llvm_type: avoid matching on the Rust type
This `match` is highly suspicious. Looking at `scalar_llvm_type_at` I think it makes no difference. But if it were to make a difference that would be a huge problem, since it doesn't look through `repr(transparent)`!
Cc `@eddyb` `@bjorn3`
Avoid duplicate `large_assignments` lints
By checking for overlapping spans.
This PR does the "reduce noisiness" task in #83518.
r? `@oli-obk` who added E-mentor and E-help-wanted and wrote the initial code.
(The fix itself is in dc82736677. The two commits before that are just small refactorings.)
Rollup of 6 pull requests
Successful merges:
- #109660 (Document that SystemTime does not count leap seconds)
- #114238 (Fix implementation of `Duration::checked_div`)
- #114512 (std/tests: disable ancillary tests on freebsd since the feature itsel…)
- #114919 (style-guide: Add guidance for defining formatting for specific macros)
- #115278 (tell people what to do when removing an error code)
- #115280 (avoid triple-backtrace due to panic-during-cleanup)
r? `@ghost`
`@rustbot` modify labels: rollup
tell people what to do when removing an error code
Currently tidy and CI send developers on a wild goose chase:
- you edit the code
- CI/tidy tells you that an error code is gone, so you remove it from the list
- CI/tidy tells you that the markdown file is stale, so you remove that as well
- CI (but not tidy) tells you not to remove an error description and copy what E0001 does
Let's be nice to people and directly tell them what to do rather than making them follow misleading breadcrumbs.
r? ``@GuillaumeGomez``
Load include_bytes! directly into an Lrc
This PR deletes an innocent-looking `.into()` that was converting from a `Vec<u8>` to `Lrc<[u8]>`. This has significant runtime and memory overhead when using `include_bytes!` to pull in a large binary file.
Add a specialization for encoding byte arrays in rmeta
This specialization already exists for FileEncoder, but since EncodeContext is implemented by forwarding down to FileEncoder, using EncodeContext used to bypass the specialization.
Only inline functions that are considered eligible for inlining
by the reachability pass.
This constraint was previously indirectly enforced by only exporting MIR
of eligible functions, but that approach doesn't work with
-Zalways-encode-mir enabled.
Add an (perma-)unstable option to disable vtable vptr
This flag is intended for evaluation of trait upcasting space cost for embedded use cases.
Compared to the approach in #112355, this option provides a way to evaluate end-to-end cost of trait upcasting. Rationale: https://github.com/rust-lang/rust/issues/112355#issuecomment-1658207769
## How this flag should be used (after merge)
Build your project with and without `-Zno-trait-vptr` flag. If you are using cargo, set `RUSTFLAGS="-Zno-trait-vptr"` in the environment variable. You probably also want to use `-Zbuild-std` or the binary built may be broken. Save both binaries somewhere.
### Evaluate the space cost
The option has a direct and indirect impact on vtable space usage. Directly, it gets rid of the trait vptr entry needed to store a pointer to a vtable of a supertrait. (IMO) this is a small saving usually. The larger saving usually comes with the indirect saving by eliminating the vtable of the supertrait (and its parent).
Both impacts only affects vtables (notably the number of functions monomorphized should , however where vtable reside can depend on your relocation model. If the relocation model is static, then vtable is rodata (usually stored in Flash/ROM together with text in embedded scenario). If the binary is relocatable, however, the vtable will live in `.data` (more specifically, `.data.rel.ro`), and this will need to reside in RAM (which may be a more scarce resource in some cases), together with dynamic relocation info living in readonly segment.
For evaluation, you should run `size` on both binaries, with and without the flag. `size` would output three columns, `text`, `data`, `bss` and the sum `dec` (and it's hex version). As explained above, both `text` and `data` may change. `bss` shouldn't usually change. It'll be useful to see:
* Percentage change in text + data (indicating required flash/ROM size)
* Percentage change in data + bss (indicating required RAM size)
Move a local to the `#if` block where it is used
For other cases (LLVM < 17), this was complaining under `-Wall`:
```
warning: llvm-wrapper/PassWrapper.cpp: In function ‘void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef, const char*)’:
warning: llvm-wrapper/PassWrapper.cpp:311:26: warning: unused variable ‘MCInfo’ [-Wunused-variable]
warning: 311 | const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
warning: | ^~~~~~
```
This reverts commit 4410868798, reversing
changes made to 249595b752.
This causes linker failures with the binutils version used by
cross (#115239), as well as miscompilations when using the mold
linker.
As experimentation in 115242 has shown looks better than `coldcc`.
And *don't* use a different convention for cold on Windows, because that actually ends up making things worse.
cc tracking issue 97544
Point at type parameter that introduced unmet bound instead of full HIR node
```
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
--> $DIR/issue-87199.rs:18:15
|
LL | ref_arg::<[i32]>(&[5]);
| ^^^^^ doesn't have a size known at compile-time
```
instead of
```
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
--> $DIR/issue-87199.rs:18:22
|
LL | ref_arg::<[i32]>(&[5]);
| ---------------- ^^^^ doesn't have a size known at compile-time
| |
| required by a bound introduced by this call
```
------
```
error[E0277]: the trait bound `String: Copy` is not satisfied
--> $DIR/own-bound-span.rs:14:24
|
LL | let _: <S as D>::P<String>;
| ^^^^^^ the trait `Copy` is not implemented for `String`
|
note: required by a bound in `D::P`
--> $DIR/own-bound-span.rs:4:15
|
LL | type P<T: Copy>;
| ^^^^ required by this bound in `D::P`
```
instead of
```
error[E0277]: the trait bound `String: Copy` is not satisfied
--> $DIR/own-bound-span.rs:14:12
|
LL | let _: <S as D>::P<String>;
| ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
|
note: required by a bound in `D::P`
--> $DIR/own-bound-span.rs:4:15
|
LL | type P<T: Copy>;
| ^^^^ required by this bound in `D::P`
```
Fix#105306.
Remove lub_empty from lexical region resolve
As of my understanding this method made sense when we had `ReEmpty`.
Removed `lub_empty` and made the calling site code equivalent.
r? `@lcnr` `@compiler-errors`
Fix waiting on a query that panicked
This fixes waiting on a query that panicked. The code now looks for `QueryResult::Poisoned` in the query state in addition to the query cache. This fixes https://github.com/rust-lang/rust/issues/111528.
r? `@cjgillot`
Revert "Use the same DISubprogram for each instance of the same inline function within the caller"
This reverts commit 687bffa493.
Reverting to resolve ICEs reported on nightly.
cc `@dpaoliello`
Fixes#115156
Stop emitting non-power-of-two vectors in (non-portable-SIMD) codegen
Fixes#115212
It's unclear what makes this not work sometimes, since it often *does* work, so for now just disable the unusual cases. A future PR can consider doing something smarter, but this is an easy and safe tweak that we can do to resolve the regressions for now.
On the following example, point at `String` instead of the whole type:
```
error[E0277]: the trait bound `String: Copy` is not satisfied
--> $DIR/own-bound-span.rs:14:24
|
LL | let _: <S as D>::P<String>;
| ^^^^^^ the trait `Copy` is not implemented for `String`
|
note: required by a bound in `D::P`
--> $DIR/own-bound-span.rs:4:15
|
LL | type P<T: Copy>;
| ^^^^ required by this bound in `D::P`
```
Add missing high-level stable_mir::generics_of fn
We forgot to add this function in https://github.com/rust-lang/rust/pull/115092, as we have done on https://github.com/rust-lang/rust/pull/115084 and other high level APIs.
At some point I think we should re-organize the structure of the code but this is what we have for now.
r? `@compiler-errors`
Would have assigned `@oli-obk` but he is still on vacations
Walk through full path in `point_at_path_if_possible`
We already had sufficient information to point at the `[u8]` in `Option::<[u8]>::None` (the `fallback_param_to_point_at` parameter), we just were neither using it nor walking through hir paths sufficiently to encounter it.
This should alleviate the need to add additional logic to extract params in a somewhat arbitrary manner of looking at the grandparent def path: https://github.com/rust-lang/rust/pull/115219#discussion_r1305946358
r? `@estebank`
Add stable for Constant in smir
Previously https://github.com/rust-lang/rust/pull/114587 we covered much of the groundwork needed to cover Const in smir, so there is no reason keep `Constant` as String.
r? `@spastorino`