Inherent const impl
Some constifications are annoying because we need to repeat `T: Trait` bounds from an impl block on the individual constified `const fn`s as `T: [const] Trait`. We've brainstormed solutions before, and one would be to have separate `const impl` blocks or sth. However the final syntax will look, I decided to just impl this syntax and either have sth nice on nightly to work with or at least move the discussion along.
Also interacts with the discussion around `impl const Trait for Type` vs `const impl Trait for Type`, as we may want to use the latter to keep inherent and trait impls in sync (unless we come up with even another scheme).
* [ ] rustdoc + tests
* [ ] macro stability /regression tests
r? `@fee1-dead`
cc `@traviscross` `@rust-lang/project-const-traits`
Abi compatibility test cleanup
r? `@jieyouxu`
- moves `NonNull` (and some friends) into `minicore.rs` so it can be re-used.
- tests the abi compatibility of a couple more targets. It's useful to have a comprehensive overview of all ABIs that rust has some amount of support for, e.g. testing for c-variadic or guaranteed tail calls (cc https://github.com/rust-lang/rust/issues/148748)
Error if an autodiff user does not set lto=fat
Based on your feedback, I started to provide a nice error message for a lack of `lto=fat`, instead of us forcing it.
In a next step, we should replace `RUSTFLAGS="-Zautodiff=Enable"` with another Cargo.toml setting, as discussed here: https://github.com/rust-lang/rust/issues/147487#issuecomment-3446558644
As another improvement, we should also figure out why rlib builds do not properly obey the fat=lto setting.
```````@bjorn3```````
add larger test for `proc_macro` `FromStr` implementations
Currently, there are only few tests that check the output of `TokenStream::from_str` and `Literal::from_str` (which is somewhat understandable as the rustc implementation just delegates these calls to the parser). In preparation for both the standalone backend (rust-lang/rust#130856) which will probably need to reimplement this logic as well as for removing panics from these functions (rust-lang/rust#58736), this PR adds a test which shows the various messy ways of how these functions report errors and the return values for successful parses.
Followup PRs such as rust-lang/rust#147859 will change more and more of these "diagnostic + error"s into `LexErrors`.
The test structure with the extra module is used to allow reusing it later easily for the standalone backend.
Add another *ExprWithBlock* test for `try` blocks
Looking to address this open item from rust-lang/rust#31436
> Add a test confirming that it's an `ExprWithBlock`, so works in a match arm without a comma
It turns out that rust-lang/rust#120540 addressed that one, but it made me think of this other case that probably ought to have some kind of test as well.
re-enable wasm abi test
The `wasm32-unknown-unknown` ABI has been fixed for a while now https://github.com/rust-lang/rust/issues/115666, so this test can be re-enabled and the fixme removed.
r? ``@bjorn3``
compute temporary scopes when building MIR, not THIR
This accomplishes two things:
- Makes the THIR slightly smaller by not attaching a full `TempLifetime` to every expression.
- Reduces the number of traversals of the `ScopeTree` by only calling `ScopeTree::temporary_scope` when building MIR for something that needs to be dropped in a temporary scope.
error when ABI does not support guaranteed tail calls
Some ABIs cannot support guaranteed tail calls. There isn't really an exhaustive list, so this is a best effort. Conveniently, we already disallow calling most of these directly anyway. The only exception that I was able to trigger an LLVM assertion with so far was `cmse-nonsecure-entry`.
For that calling convention, LLVM specifically notes that (guaranteed) tail calls cannot be supported:
https://github.com/llvm/llvm-project/blob/28dbbba6c3a4e026e085c48cc022cb97b5d8bc6d/llvm/lib/Target/ARM/ARMISelLowering.cpp#L2331-L2335
---
I have some doubts about the implementation here though. I think it would be nicer to use `CanonAbi`, and move the `become` ABI check into `rustc_hir_typeck`, similar to `check_call_abi`:
https://github.com/rust-lang/rust/blob/d6deffe2debecc66501e50f9573214139ab4d678/compiler/rustc_hir_typeck/src/callee.rs#L157-L194
Both the check for whether an ABI is callable and whether it supports guaranteed tail calls can then be methods (containing exhaustive matches) on `CanonAbi`. I'm however not sure
- if the ABI checks are deliberately only performed when constructing MIR
- what assumptions can be made about the `call` expression in [`check_expr_become`](https://github.com/rust-lang/rust/blob/d6deffe2debecc66501e50f9573214139ab4d678/compiler/rustc_hir_typeck/src/expr.rs#L1126-L1150), it looks like currently the check that the "argument" to `become` is a function call also only occurs later during MIR construction
Are there issues with validating the ABI earlier in `rustc_hir_typeck` that I'm overlooking? I believe that we should already know the call's ABI and whether it is c-variadic at that point.
cc ````@workingjubilee```` for `CanonAbi`, ````@davidtwco```` for cmse
r? ````@WaffleLapkin````
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.
add a test for combining RPIT with explicit tail calls
tracking issue: https://github.com/rust-lang/rust/issues/112788
fixes https://github.com/rust-lang/rust/issues/139305
Combining return position impl trait (RPIT) with guaranteed tail calls does not currently work, but at least it does not ICE any more.
Using RPIT probably should work, see also https://github.com/rust-lang/rust/issues/144953.
The snippet in the issue is not valid for a variety of reasons, and based on the assert that got triggered the ICE was just any `-> impl Trait` at all, so I've made a minimal example using RPIT.
r? `@WaffleLapkin`
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).