Rollup of 18 pull requests#152810
Closed
JonathanBrouwer wants to merge 100 commits intorust-lang:mainfrom
Closed
Conversation
MGCA: Support struct expressions without intermediary anon consts r? oli-obk tracking issue: rust-lang#132980 Fixes rust-lang#127972 Fixes rust-lang#137888 Fixes rust-lang#140275 due to delaying a bug instead of ICEing in HIR ty lowering. ### High level goal Under `feature(min_generic_const_args)` this PR adds another kind of const argument. A struct/variant construction const arg kind. We represent the values of the fields as themselves being const arguments which allows for uses of generic parameters subject to the existing restrictions present in `min_generic_const_args`: ```rust fn foo<const N: Option<u32>>() {} trait Trait { #[type_const] const ASSOC: usize; } fn bar<T: Trait, const N: u32>() { // the initializer of `_0` is a `N` which is a legal const argument // so this is ok. foo::<{ Some::<u32> { 0: N } }>(); // this is allowed as mgca supports uses of assoc consts in the // type system. ie `<T as Trait>::ASSOC` is a legal const argument foo::<{ Some::<u32> { 0: <T as Trait>::ASSOC } }>(); // this on the other hand is not allowed as `N + 1` is not a legal // const argument foo::<{ Some::<u32> { 0: N + 1 } }>(); } ``` This PR does not support uses of const ctors, e.g. `None`. And also does not support tuple constructors, e.g. `Some(N)`. I believe that it would not be difficult to add support for such functionality after this PR lands so have left it out deliberately. We currently require that all generic parameters on the type being constructed be explicitly specified. I haven't really looked into why that is but it doesn't seem desirable to me as it should be legal to write `Some { ... }` in a const argument inside of a body and have that desugar to `Some::<_> { ... }`. Regardless this can definitely be a follow-up PR and I assume this is some underlying consistency with the way that elided args are handled with type paths elsewhere. This PRs implementation of supporting struct expressions is somewhat incomplete. We don't handle `Foo { ..expr }` at all and aren't handling privacy/stability. The printing of `ConstArgKind::Struct` HIR nodes doesn't really exist either :') I've tried to keep the implementation here somewhat deliberately incomplete as I think a number of these issues are actually quite small and self contained after this PR lands and I'm hoping it could be a good set of issues to mentor newer contributors on 🤔 I just wanted the "bare minimum" required to actually demonstrate that the previous changes are "necessary". ### `ValTree` now recurse through `ty::Const` In order to actually represent struct/variant construction in `ty::Const` without going through an anon const we would need to introduce some new `ConstKind` variant. Let's say some hypothetical `ConstKind::ADT(Ty<'tcx>, List<Const<'tcx>>)`. This variant would represent things the same way that `ValTree` does with the first element representing the `VariantIdx` of the enum (if its an enum), and then followed by a list of field values in definition order. This *could* work but there are a few reasons why it's suboptimal. First it would mean we have a second kind of `Const` that can be normalized. Right now we only have `ConstKind::Unevaluated` which possibly needs normalization. Similarly with `TyKind` we *only* have `TyKind::Alias`. If we introduced `ConstKind::ADT` it would need to be normalized to a `ConstKind::Value` eventually. This feels to me like it has the potential to cause bugs in the long run where only `ConstKind::Unevaluated` is handled by some code paths. Secondly it would make type equality/inference be kind of... weird... It's desirable for `Some { 0: ?x } eq Some { 0: 1_u32 }` to result in `?x=1_u32`. I can't see a way for this to work with this `ConstKind::ADT` design under the current architecture for how we represent types/consts and generally do equality operations. We would need to wholly special case these two variants in type equality and have a custom recursive walker separate from the existing architecture for doing type equality. It would also be somewhat unique in that it's a non-rigid `ty::Const` (it can be normalized more later on in type inference) while also having somewhat "structural" equality behaviour. Lastly, it's worth noting that its not *actually* `ConstKind::ADT` that we want. It's desirable to extend this setup to also support tuples and arrays, or even references if we wind up supporting those in const generics. Therefore this isn't really `ConstKind::ADT` but a more general `ConstKind::ShallowValue` or something to that effect. It represents at least one "layer" of a types value :') Instead of doing this implementation choice we instead change `ValTree::Branch`: ```rust enum ValTree<'tcx> { Leaf(ScalarInt), // Before this PR: Branch(Box<[ValTree<'tcx>]>), // After this PR Branch(Box<[Const<'tcx>]>), } ``` The representation for so called "shallow values" is now the same as the representation for the *entire* full value. The desired inference/type equality behaviour just falls right out of this. We also don't wind up with these shallow values actually being non-rigid. And `ValTree` *already* supports references/tuples/arrays so we can handle those just fine. I think in the future it might be worth considering inlining `ValTree` into `ty::ConstKind`. E.g: ```rust enum ConstKind { Scalar(Ty<'tcx>, ScalarInt), ShallowValue(Ty<'tcx>, List<Const<'tcx>>), Unevaluated(UnevaluatedConst<'tcx>), ... } ``` This would imply that the usage of `ValTree`s in patterns would now be using `ty::Const` but they already kind of are anyway and I think that's probably okay in the long run. It also would mean that the set of things we *could* represent in const patterns is greater which may be desirable in the long run for supporting things such as const patterns of const generic parameters. Regardless, this PR doesn't actually inline `ValTree` into `ty::ConstKind`, it only changes `Branch` to recurse through `Const`. This change could be split out of this PR if desired. I'm not sure if there'll be a perf impact from this change. It's somewhat plausible as now all const pattern values that have nesting will be interning a lot more `Ty`s. We shall see :> ### Forbidding generic parameters under mgca Under mgca we now allow all const arguments to resolve paths to generic parameters. We then *later* actually validate that the const arg should be allowed to access generic parameters if it did wind up resolving to any. This winds up just being a lot simpler to implement than trying to make name resolution "keep track" of whether we're inside of a non-anon-const const arg and then encounter a `const { ... }` indicating we should now stop allowing resolving to generic parameters. It's also somewhat in line with what we'll need for a `feature(generic_const_args)` where we'll want to decide whether an anon const should have any generic parameters based off syntactically whether any generic parameters were used. Though that design is entirely hypothetical at this point :) ### Followup Work - Make HIR ty lowering check whether lowering generic parameters is supported and if not lower to an error type/const. Should make the code cleaner, fix some other bugs, and maybe(?) recover perf since we'll be accessing less queries which I think is part of the perf regression of this PR - Make the ValTree setup less scuffed. We should find a new name for `ConstKind::Value` and the `Val` part of `ValTree` and `ty::Value` as they no longer correspond to a fully normalized structure. It may also be worth looking into inlining `ValTreeKind` into `ConstKind` or atleast into `ty::Value` or sth 🤔 - Support tuple constructors and const constructors not just struct expressions. - Reduce code duplication between HIR ty lowering's handling of struct expressions, and HIR typeck's handling of struct expressions - Try fix perf rust-lang#149114 (comment). Maybe this will clear up once we clean up `ValTree` a bit and stop doing double interning and whatnot
For some reason git-subtree incorrectly synced those changes.
…acro_transparency`
The next Cranelift release will support for CallConv::Cold as it was already effectively equivalent to the default calling convention.
This saves about 10MB on the dist size and about 240MB on the build dir size.
…e_diagnostic` throughout the codebase This PR was mostly made by search&replacing
…fJung `c_variadic`: impl `va_copy` and `va_end` as Rust intrinsics tracking issue: rust-lang#44930 Implement `va_copy` as (the rust equivalent of) `memcpy`, which is the behavior of all current LLVM targets. By providing our own implementation, we can guarantee its behavior. These guarantees are important for implementing c-variadics in e.g. const-eval. Discussed in [#t-compiler/const-eval > c-variadics in const-eval](https://rust-lang.zulipchat.com/#narrow/channel/146212-t-compiler.2Fconst-eval/topic/c-variadics.20in.20const-eval/with/565509704). I've also updated the comment for `Drop` a bit. The background here is that the C standard requires that `va_end` is used in the same function (and really, in the same scope) as the corresponding `va_start` or `va_copy`. That is because historically `va_start` would start a scope, which `va_end` would then close. e.g. https://softwarepreservation.computerhistory.org/c_plus_plus/cfront/release_3.0.3/source/incl-master/proto-headers/stdarg.sol ```c #define va_start(ap, parmN) {\ va_buf _va;\ _vastart(ap = (va_list)_va, (char *)&parmN + sizeof parmN) #define va_end(ap) } #define va_arg(ap, mode) *((mode *)_vaarg(ap, sizeof (mode))) ``` The C standard still has to consider such implementations, but for Rust they are irrelevant. Hence we can use `Clone` for `va_copy` and `Drop` for `va_end`.
* Fix CI disk space issue for abi-cafe tests Port disk space cleanup script from rust-lang/rust to free space on GitHub Actions runners before running abi-cafe tests. * ci: update free-disk-space.sh to match rust-lang/rust@d29e478 * ci: set RUNNER_ENVIRONMENT=github-hosted for free-disk-space script * Revert indentation change --------- Co-authored-by: bjorn3 <17426603+bjorn3@users.noreply.github.com>
This is the conceptual opposite of the rust-cold calling convention and
is particularly useful in combination with the new `explicit_tail_calls`
feature.
For relatively tight loops implemented with tail calling (`become`) each
of the function with the regular calling convention is still responsible
for restoring the initial value of the preserved registers. So it is not
unusual to end up with a situation where each step in the tail call loop
is spilling and reloading registers, along the lines of:
foo:
push r12
; do things
pop r12
jmp next_step
This adds up quickly, especially when most of the clobberable registers
are already used to pass arguments or other uses.
I was thinking of making the name of this ABI a little less LLVM-derived
and more like a conceptual inverse of `rust-cold`, but could not come
with a great name (`rust-cold` is itself not a great name: cold in what
context? from which perspective? is it supposed to mean that the
function is rarely called?)
…bilee
add `simd_splat` intrinsic
Add `simd_splat` which lowers to the LLVM canonical splat sequence.
```llvm
insertelement <N x elem> poison, elem %x, i32 0
shufflevector <N x elem> v0, <N x elem> poison, <N x i32> zeroinitializer
```
Right now we try to fake it using one of
```rust
fn splat(x: u32) -> u32x8 {
u32x8::from_array([x; 8])
}
```
or (in `stdarch`)
```rust
fn splat(value: $elem_type) -> $name {
#[derive(Copy, Clone)]
#[repr(simd)]
struct JustOne([$elem_type; 1]);
let one = JustOne([value]);
// SAFETY: 0 is always in-bounds because we're shuffling
// a simd type with exactly one element.
unsafe { simd_shuffle!(one, one, [0; $len]) }
}
```
Both of these can confuse the LLVM optimizer, producing sub-par code. Some examples:
- rust-lang#60637
- rust-lang#137407
- rust-lang#122623
- rust-lang#97804
---
As far as I can tell there is no way to provide a fallback implementation for this intrinsic, because there is no `const` way of evaluating the number of elements (there might be issues beyond that, too). So, I added implementations for all 4 backends.
Both GCC and const-eval appear to have some issues with simd vectors containing pointers. I have a workaround for GCC, but haven't yet been able to make const-eval work. See the comments below.
Currently this just adds the intrinsic, it does not actually use it anywhere yet.
…ochenkov
abi: add a rust-preserve-none calling convention
This is the conceptual opposite of the rust-cold calling convention and is particularly useful in combination with the new `explicit_tail_calls` feature.
For relatively tight loops implemented with tail calling (`become`) each of the function with the regular calling convention is still responsible for restoring the initial value of the preserved registers. So it is not unusual to end up with a situation where each step in the tail call loop is spilling and reloading registers, along the lines of:
foo:
push r12
; do things
pop r12
jmp next_step
This adds up quickly, especially when most of the clobberable registers are already used to pass arguments or other uses.
I was thinking of making the name of this ABI a little less LLVM-derived and more like a conceptual inverse of `rust-cold`, but could not come with a great name (`rust-cold` is itself not a great name: cold in what context? from which perspective? is it supposed to mean that the function is rarely called?)
Contributor
Author
|
@bors r+ rollup=never p=5 |
Contributor
Contributor
Author
|
@bors try jobs=dist-various-2,test-various |
This comment has been minimized.
This comment has been minimized.
rust-bors bot
pushed a commit
that referenced
this pull request
Feb 18, 2026
Rollup of 18 pull requests try-job: dist-various-2 try-job: test-various
Contributor
Author
Contributor
|
Try build cancelled. Cancelled workflows: |
This comment has been minimized.
This comment has been minimized.
rust-bors bot
pushed a commit
that referenced
this pull request
Feb 18, 2026
Rollup of 18 pull requests try-job: x86_64-msvc-1 try-job: i686-msvc-1 try-job: x86_64-mingw-1 try-job: test-various try-job: armhf-gnu try-job: aarch64-apple try-job: x86_64-gnu-llvm-20-3 try-job: dist-various-2
This comment has been minimized.
This comment has been minimized.
rust-bors bot
pushed a commit
that referenced
this pull request
Feb 18, 2026
…uwer Rollup of 18 pull requests Successful merges: - #152799 (Subtree sync for rustc_codegen_cranelift) - #152569 (Stop using rustc_layout_scalar_valid_range_* in rustc) - #151059 (x86: support passing `u128`/`i128` to inline assembly) - #152097 (Suggest local variables for captured format args) - #152734 (Respect the `--ci` flag in more places in bootstrap) - #151703 (Fix ICE in transmutability error reporting when type aliases are normalized) - #152173 (Reflection TypeKind::FnPtr) - #152564 (Remove unnecessary closure.) - #152628 (tests: rustc_public: Check const allocation for all variables (1 of 11 was missing)) - #152658 (compiletest: normalize stderr before SVG rendering) - #152766 (std::r#try! - avoid link to nightly docs) - #152780 (Remove some clones in deriving) - #152787 (Add a mir-opt test for alignment check generation [zero changes outside tests]) - #152790 (Fix incorrect target in aarch64-unknown-linux-gnu docs) - #152792 (Fix an ICE while checking param env shadowing on an erroneous trait impl) - #152793 (Do no add -no-pie on Windows) - #152803 (Avoid delayed-bug ICE for malformed diagnostic attrs) - #152806 (interpret: fix comment typo)
Collaborator
|
The job Click to see the possible cause of the failure (guessed by this bot) |
Contributor
|
💔 Test for 80d8e50 failed: CI. Failed job:
|
Contributor
Author
Contributor
Author
Contributor
|
PR #152569, which is a member of this rollup, was unapproved. |
Contributor
Author
|
Problem is #152569 |
Contributor
|
💔 Test for 7bb7280 failed: CI. Failed job:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Successful merges:
u128/i128to inline assembly #151059 (x86: support passingu128/i128to inline assembly)--ciflag in more places in bootstrap #152734 (Respect the--ciflag in more places in bootstrap)r? @ghost
Create a similar rollup