Tests for precise-capture through RPIT and TAIT
- Tests for https://github.com/rust-lang/rust/issues/155151.
These tests succeed under `-Znext-solver`, but incorrectly fail under the old trait solver.
---
The bug can be triggered via return-position `impl Trait` on stable, but requires some rather contrived code. When using type-alias `impl Trait`, it's easier to imagine the issue being triggered by real code.
Test/lexer unicode pattern white space
This PR adds a test for the Rust lexer to verify it correctly accepts vertical tab (`\x0B`) as valid whitespace between tokens. Vertical tab is part of Unicode Pattern_White_Space, which the Rust language specification uses to define whitespace.
Related: Outreachy tracking [Pattern_White_Space](https://www.unicode.org/reports/tr31/#R3a)
explicit-tail-calls: disable two tests on LoongArch
A [recent LLVM change](https://github.com/llvm/llvm-project/pull/191508) broke these on LLVM 23.
I suspect these will eventually be fixed, so maybe it'd be okay/better to just leave this pending so it applies to our CI without merging it? I'm open to opinions.
Fix ICE when Self is used in enum discriminant of a generic enum
Fixesrust-lang/rust#153756
Let discriminant AnonConst inherit parent generics via Node::Variant in generics_of, and emit a proper error instead of span_bug! for the TooGeneric case in wfcheck.
* Fix ICE when Self is used in enum discriminant of a generic enum
Move the validation into the existing `check_param_uses_if_mcg` machinery
in HIR ty lowering instead of adding a new check in wfcheck. After the
`AnonConstKind` refactoring, `ForbidMCGParamUsesFolder` was only gated on
`AnonConstKind::MCG`, causing discriminant anon consts (`NonTypeSystem`) to
bypass it entirely.
Add `anon_const_forbids_generic_params()` which returns the appropriate
`ForbidParamContext` for both MCG and enum discriminant contexts. Wire it
into `check_param_uses_if_mcg` so that `Self` aliasing a generic type is
caught before reaching `const_eval_poly`. Convert the `TooGeneric` span_bug
into a proper diagnostic as a fallback for anything slipping through
type-dependent path resolution.
* Address review comments
- Rename `ForbidMCGParamUsesFolder` to `ForbidParamUsesFolder`
- Rename `MinConstGenerics` variant to `ConstArgument` with updated doc
- Simplify doc comment on `anon_const_forbids_generic_params`
- Make match on `AnonConstKind` exhaustive
- Move `anon_const_def_id` inside the `if let` in `check_param_uses_if_mcg`
- Remove now-unreachable `TooGeneric` span_err in wfcheck
* Revert TooGeneric arm back to span_bug! as requested by reviewer
* Use generics_of to determine if NonTypeSystem anon consts allow generic params
* Also check InlineConst and Closure defs nested in enum discriminants
* Simplify logic for determining anonymous constant parent in generic contexts
* add test
limit duplicate-profiler-builtins test to targets that can do dynamic linking
this is the error I got for an example of such a target
```
=== STDERR ===
error: extern location for dylib_a does not exist: libdylib_a.so
--> main.rs:2:5
|
2 | dylib_a::something();
| ^^^^^^^
error: extern location for dylib_b does not exist: libdylib_b.so
--> main.rs:3:5
|
3 | dylib_b::something_else();
| ^^^^^^^
coroutines: Skip the closure signature annotation check for tainted bodies
When a coroutine has too many parameters, `check_match` fails and `construct_error` builds a MIR body with only the coroutine's computed arguments (env + resume type). The user-provided signature, however, still reflects all the parameters the user wrote. `check_signature_annotation` then tries to `zip_eq` these two mismatched iterators, causing a panic. Checking `tainted_by_errors` and bailing early avoids this, since `construct_error` bodies cannot meaningfully be compared against user annotations.
Example currently ICEing:
```rust
fn main() {
|(1, 42), ()| yield;
}
```
Closesrust-lang/rust#139570.
Instead of the last segment of the delegation path.
`self` is something that introduced by the whole delegation item, not some specific part of it, and the last segment may need to have a different context for path resolution purposes.
preserve SIMD element type information
Preserve the SIMD element type and provide it to LLVM for better optimization.
This is relevant for AArch64 types like `int16x4x2_t`, see also https://github.com/llvm/llvm-project/issues/181514. Such types are defined like so:
```rust
#[repr(simd)]
struct int16x4_t([i16; 4]);
#[repr(C)]
struct int16x4x2_t(pub int16x4_t, pub int16x4_t);
```
Previously this would be translated to the opaque `[2 x <8 x i8>]`, with this PR it is instead `[2 x <4 x i16>]`. That change is not relevant for the ABI, but using the correct type prevents bitcasts that can (indeed, do) confuse the LLVM pattern matcher.
This change will make it possible to implement the deinterleaving loads on AArch64 in a portable way (without neon-specific intrinsics), which means that e.g. Miri or the cranelift backend can run them without additional support.
discussion at [#t-compiler > loss of vector element type information](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/loss.20of.20vector.20element.20type.20information/with/584483611)
Trait aliases: Also imply default trait bounds on type params other than `Self`
Trait aliases already correctly imply default trait bounds on `Self` type params. However, due to an oversight, they didn't do that for normal type params.
Fixesrust-lang/rust#152687.
Implement `-Z allow-partial-mitigations` (RFC 3855)
This implements `-Z allow-partial-mitigations` as an unstable option, currently with support for control-flow-guard and stack-protector.
As a difference from the RFC, we have `-Z allow-partial-mitigations=!foo` rather than `-Z deny-partial-mitigations=foo`, since I couldn't find an easy way to have an allow/deny pair of flags where the latter flag wins.
To allow for stabilization, this is only enabled starting from the next edition. Maybe a better policy is possible (bikeshed).
r? @rcvalle
Start using pattern types in libcore
cc rust-lang/rust#135996
Replaces the innards of `NonNull` with `*const T is !null`.
This does affect LLVM's optimizations, as now reading the field preserves the metadata that the field is not null, and transmuting to another type (e.g. just a raw pointer), will also preserve that information for optimizations. This can cause LLVM opts to do more work, but it's not guaranteed to produce better machine code.
Once we also remove all uses of rustc_layout_scalar_range_start from rustc itself, we can remove the support for that attribute entirely and handle all such needs via pattern types
Improve emission of `UnknownDiagnosticAttribute` lint
This checks features much less than the current implementation. See https://github.com/rust-lang/rust/pull/155155 for context. Minor fixes and comments are added in the second and third commit.
Move tests from `tests/ui/issues/` to appropriate directories
In this PR, I am moving the following test from `tests/ui/issues` directory to the appropriate directories, followed by the addition of issue links at the top and reblessing of the stderr files:
| old-name | new-sub-dir | new-name |
|-|-|-|
| `issue-29516.rs` | `auto-traits/` | `distinct-type-tuple-by-negative-impl.rs` |
| `issue-3874.rs` | `binding/` | `ref-in-let-lhs-in-field.rs` |
| `issue-32782.rs` | `feature-gates/` | `feature-gate-check-nested-macro-invocation.rs` |
| `issue-32782.stderr` | `feature-gates/` | `feature-gate-check-nested-macro-invocation.stderr` |
| `issue-5100.rs` | `pattern/` | `match-errors-derived-error-suppression.rs` |
| `issue-5100.stderr` | `pattern/` | `match-errors-derived-error-suppression.stderr` |
| `issue-21033.rs` | `pattern/` | `match-struct-var-having-boxed-field.rs` |
r? Kivooeo
r? Teapot4195
UI automation
# To move issue-3154 and issue-16774 to functional subdirectories:
I have moved 2 tests from tests/ui/issues to their appropriate directories using "test-manager" tool.
## Changes:
- Moved tests/ui/issues/issue-3154.rs to tests/ui/borrowck/missing-lifetime-in-return.rs
- Moved tests/ui/issues/issue-16774.rs to tests/ui/deref/derefmut-closure-drop-order.rs
These moves where performed using the test-manager automation tool.
cg_ssa: transmute between scalable vectors
Like regular SIMD vectors, we can support casting between scalable vectors of integral or floating-point types without needing a temporary.
r? @Amanieu
Normalize individual predicate of `InstantiatedPredicates` inside `predicates_for_generics`
This is a cleanup to better land rust-lang/rust#155083. It allows us to wrap individual clause in `Unnormalized` wrapper. See [this comment](https://github.com/rust-lang/rust/pull/155083#discussion_r3072219035)
Besides that, this PR also adds missing normalization in some cases.
r? @lcnr
Add more robust handling of nested query cycles
This adds more robust handling of query cycle that occur while we are already printing a query cycle error. Such nested query cycle are compiler bugs and this adds special handling so that both the nested query cycle and the outer query cycle are printed. Doubly nested query cycle errors are ignored to prevent infinite recursion.
Implement EII for statics
This PR implements EII for statics. I've tried to mirror the implementation for functions in a few places, this causes some duplicate code but I'm also not really sure whether there's a clean way to merge the implementations.
This does not implement defaults for static EIIs yet, I will do that in a followup PR
Change codegen of LLVM intrinsics to be name-based, and add llvm linkage support for `bf16(xN)` and `i1xN`
*[View all comments](https://triagebot.infra.rust-lang.org/gh-comments/rust-lang/rust/pull/140763)*
This PR changes how LLVM intrinsics are codegen
# Explanation of the changes
## Current procedure
This is the same for all functions, LLVM intrinsics are _not_ treated specially
- We get the LLVM Type of a function simply using the argument types. For example, the following function
```rust
#[link_name = "llvm.sqrt.f32"]
fn sqrtf32(a: f32) -> f32;
```
will have LLVM type simply `f32 (f32)` due to the Rust signature
### Pros
- Simpler to implement, no extra complexity involved due to LLVM intrinsics
### Cons
- LLVM intrinsics have a well-defined signature, completely defined by their name (and if it is overloaded, the type parameters). So, this process of converting Rust signatures to LLVM signatures may not work, for example the following code generates LLVM IR without any problem
```rust
#[link_name = "llvm.sqrt.f32"]
fn sqrtf32(a: i32) -> f32;
```
but the generated LLVM IR is invalid, because it has wrong signature for the intrinsic ([Godbolt](https://godbolt.org/z/6ff9hrcd5), adding `-Zverify-llvm-ir` to it will fail compilation). I would expect this code to not compile at all instead of generating invalid IR.
- LLVM intrinsics that have types in their signature that can't be accessed from Rust (notable examples are the AMX intrinsics that have the `x86amx` type, and (almost) all intrinsics that have vectors of `i1` types) can't be linked to at all. This is a (major?) roadblock in the AMX and AVX512 support in stdarch.
- If code uses an non-existing LLVM intrinsic, even `-Zverify-llvm-ir` won't complain. Eventually it will error out due to the non-existing function (courtesy of the linker). I don't think this is a behavior we want.
## What this PR does
- When linking to **non-overloaded** intrinsics, we use the function `LLVMIntrinsicGetType` to directly get the function type of the intrinsic from LLVM.
- We then use this LLVM definition to _verify_ the Rust signature, and emit a proper error if it doesn't match, instead of silently emitting invalid IR.
- Lint if linking to deprecated or invalid LLVM intrinsics
> [!NOTE]
> This PR only focuses on non-overloaded intrinsics, overloaded can be done in a future PR
Regardless, the undermentioned functionalities work for **all** intrinsics
- If we can't find the intrinsic, we check if it has been `AutoUpgrade`d by LLVM. If not, that means it is an invalid intrinsic, and we error out.
- Don't allow intrinsics from other archs to be declared, e.g. error out if an AArch64 intrinsic is declared when we are compiling for x86
### Pros
- It is now not possible (or at least, it would require _significantly_ more leaps and bounds) to introduce invalid IR using **non-overloaded** LLVM intrinsics.
- As we are now doing the matching of Rust signatures to LLVM intrinsics ourselves, we can now add bypasses to enable linking to such non-Rust types (e.g. matching 8192-bit vectors to `x86amx` and injecting `llvm.x86.cast.vector.to.tile` and `llvm.x86.cast.tile.to.vector`s in callsite)
> [!NOTE]
> I don't intend for these bypasses to be permanent. A better approach will be introducing a `bf16` type in Rust, and allowing `repr(simd)` with `bool`s to get Rust-native `i1xN`s. These are meant to be short-time, as I mentioned, "bypass"es. They shouldn't cause any major breakage even if removed, as `link_llvm_intrinsics` is perma-unstable.
This PR adds bypasses for `bf16` (via `i16`), `bf16xN` (via `i16xN`) and `i1xN` (via `iM`, where `M` is the smallest power of 2 s.t. `M >= N`, unless `N <= 4`, where we use `M = 8`). This will unblock AVX512-VP2INTERSECT and a lot of bf16 intrinsics in stdarch. This PR also automatically destructures structs if the types don't exactly match (this is required for us to start emitting hard errors on mismmatches).
### Cons
- This only works for non-overloaded intrinsics (at least for now). Improving this to work with overloaded intrinsics too will involve significantly more work.
# Possible ways to extend this to overloaded intrinsics (future)
## Parse the mangled intrinsic name to get the type parameters
LLVM has a stable mangling of intrinsic names with type parameters (in `LLVMIntrinsicCopyOverloadedName2`), so we can parse the name to get the type parameters, and then just do the same thing.
### Pros
- For _most_ intrinsics, this will work perfectly, and is a easy way to do this.
### Cons
- The LLVM mangling is not perfectly reversible. When we have `TargetExt` types or identified structs, their name is a part of the mangling, making it impossible to reverse. Even more complexities arise when there are unnamed identified structs, as LLVM adds more mangling to the names.
- @nikic's work on LLVM intrinsics will remove the name mangling, making this approach impossible
## Use the `IITDescriptor` table and the Rust function signature
We can use the base name to get the `IITDescriptor`s of the corresponding intrinsic, and then manually implement the _matching_ logic based on the Rust signature.
### Pros
- Doesn't have the above mentioned limitation of the parsing approach, has correct behavior even when there are identified structs and `TargetExt` types. Also, fun fact, Rust exports all struct types as literal structs (unless it is emitting LLVM IR, then it always uses named identified structs, with mangled names)
### Cons
- **Doesn't** actually use the type parameters in the name, only uses the base name and the Rust signature to get the llvm signature (although we _can_ check that it is the correct name). It means there would be no way to (for example) link against `llvm.sqrt.bf16` until we have `bf16` types in Rust. Because if we are using `u16`s (or any other type) as `bf16`s, then the matcher will deduce that the signature is `u16 (u16)` not `bf16 (bf16)` (which would lead to an error because `u16` is not a valid type parameter for `llvm.sqrt`), even though the intended type parameter is specified in the name.
- Much more complex, and hard to maintain as LLVM gets new `IITDescriptorKind`s
These 2 approaches might give different results for same function. Let's take
```rust
#[link_name = "llvm.is.constant.bf16"]
fn foo(a: u16) -> bool
```
The name-based approach will decide that the type parameter is `bf16`, and the LLVM signature is `i1 (bf16)` and will inject some bitcasts at callsite.
The `IITDescriptor`-based approach will decide that the LLVM signature is `i1 (u16)`, and will see that the name given doesn't match the expected name (`llvm.is.constant.u16`), and will error out.
Reviews are welcome, as this is my first time _actually_ contributing to `rustc`
@rustbot label T-compiler A-codegen A-LLVM
r? codegen