Skip to content

Update InterpCx::project_field to take FieldIdx - #142103

Merged
bors merged 2 commits into
rust-lang:masterfrom
scottmcm:fieldidx-in-interp
Jun 7, 2025
Merged

Update InterpCx::project_field to take FieldIdx#142103
bors merged 2 commits into
rust-lang:masterfrom
scottmcm:fieldidx-in-interp

Conversation

@scottmcm

@scottmcmscottmcm commented Jun 6, 2025

Copy link
Copy Markdown
Member

As suggested by Ralf in #142005 (comment)

@rustbot

Copy link
Copy Markdown
Collaborator

r? @oli-obk

rustbot has assigned @oli-obk.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbotrustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 6, 2025
@rustbot

Copy link
Copy Markdown
Collaborator

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

Some changes occurred in compiler/rustc_codegen_ssa

cc @WaffleLapkin

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

The Miri subtree was changed

cc @rust-lang/miri

@rust-log-analyzer

This comment has been minimized.

As suggested by Ralf in 142005.
@scottmcm
scottmcmforce-pushed the fieldidx-in-interp branch from 74c269e to 8bce225CompareJune 6, 2025 02:16

@oli-obkoli-obk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR highlights several situations where we can do improvements, but let's land this on its own and investigate from_usize and as_usize calls later

return None;
}
found = Some((field_idx, field));
found = Some((FieldIdx::from_usize(field_idx), field));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it may be worth adding an iter and an iter_enumerated method to FieldsShape

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, most of the layout-related usizes in ABI are sketchy. I've tried pulling on the tendrils before, but usually ended up giving up because of just how far that goes and -- as I mentioned in the other PR -- that the ones related to arrays sometimes need more than FieldIdx, and figuring out which those are can be hard.

(Conveniently this one was obvious because a over-4-billion-length array clearly can't have exactly one non-ZST.)

@oli-obk

Copy link
Copy Markdown
Contributor

@bors r+ rollup

@bors

bors commented Jun 6, 2025

Copy link
Copy Markdown
Collaborator

📌 Commit 8bce225 has been approved by oli-obk

It is now in the queue for this repository.

@borsbors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 6, 2025
Comment threadcompiler/rustc_abi/src/layout/ty.rs Outdated
impl FieldIdx {
/// The second field.
///
/// For use alongside [`FieldIdx::ZERO`], particularly with scalar pairs.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this not defined near FieldIdx::ZERO?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because all rustc_newtype_index! types get a ZERO; it's not something special for FieldIdx.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can add a const ONE = 1; in the macro to get it generated.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That generates it as a non-associated constant, though -- like the START_BLOCK mentioned -- not an associated one. And because ZERO is associated, I wanted ONE to be associated as well.

let fields_iter = (0..field_count)
.map(|i| {
let field_op = ecx.project_field(&down, i).discard_err()?;
let field_op = ecx.project_field(&down, FieldIdx::from_usize(i)).discard_err()?;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could also use a typed field iterator


for i in 0..field_count {
let field = ecx.project_field(&place, i).unwrap();
let field = ecx.project_field(&place, FieldIdx::from_usize(i)).unwrap();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And more here

(probably not worth pointing them all out)

// Computing the layout does normalization, so we get a normalized type out of this
// even if the field type is non-normalized (possible e.g. via associated types).
let field_layout = base.layout().field(self, field);
let field_layout = base.layout().field(self, field.as_usize());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does field not take FieldIdx...?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Co-authored-by: Ralf Jung <post@ralfj.de>
@scottmcm

Copy link
Copy Markdown
MemberAuthor

@bors r=oli-obk

@bors

bors commented Jun 6, 2025

Copy link
Copy Markdown
Collaborator

📌 Commit f9cf096 has been approved by oli-obk

It is now in the queue for this repository.

@RalfJung

RalfJung commented Jun 6, 2025 via email

Copy link
Copy Markdown
Member

@scottmcm

Copy link
Copy Markdown
MemberAuthor

I think "project" overstates at least how I've been handling this. I had rust-lang/compiler-team#606 to add FieldIdx originally, then @WaffleLapkin's rust-lang/compiler-team#639 is explicitly about using it in more places.

There's never been a tracking issue for it, or a list of all the things that should happen, or anything. Just a bunch of "spots I saw in passing" PRs.

bors added a commit that referenced this pull request Jun 7, 2025
Rollup of 11 pull requests
Successful merges:
- #140418 (Reexport types from `c_size_t` in `std`)
- #141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- #141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- #142043 (Verbose suggestion to make param `const`)
- #142086 (duduplicate more AST visitor methods)
- #142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- #142105 (remove extraneous text)
- #142112 (fix typo)
- #142113 (Reduce confusion of some drop order tests)
- #142114 (Compute number of digits instead of relying on constant value for u128 display code)
- #142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
@bors
bors merged commit 3a6f1b0 into rust-lang:masterJun 7, 2025
@rustbotrustbot added this to the 1.89.0 milestone Jun 7, 2025
rust-timer added a commit that referenced this pull request Jun 7, 2025
Rollup merge of #142103 - scottmcm:fieldidx-in-interp, r=oli-obk
Update `InterpCx::project_field` to take `FieldIdx`
As suggested by Ralf in #142005 (comment)
github-actionsBot pushed a commit to rust-lang/miri that referenced this pull request Jun 7, 2025
Rollup of 11 pull requests
Successful merges:
- rust-lang/rust#140418 (Reexport types from `c_size_t` in `std`)
- rust-lang/rust#141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- rust-lang/rust#141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- rust-lang/rust#142043 (Verbose suggestion to make param `const`)
- rust-lang/rust#142086 (duduplicate more AST visitor methods)
- rust-lang/rust#142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- rust-lang/rust#142105 (remove extraneous text)
- rust-lang/rust#142112 (fix typo)
- rust-lang/rust#142113 (Reduce confusion of some drop order tests)
- rust-lang/rust#142114 (Compute number of digits instead of relying on constant value for u128 display code)
- rust-lang/rust#142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
@scottmcm
scottmcm deleted the fieldidx-in-interp branch June 7, 2025 22:58
@WaffleLapkin

Copy link
Copy Markdown
Member

@WaffleLapkin's rust-lang/compiler-team#639 is explicitly about using it in more places.

Oh. Did I mean to work on it and then forgot? 😓

bors added a commit that referenced this pull request Jun 19, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
bjorn3 pushed a commit to bjorn3/rust that referenced this pull request Jun 24, 2025
…-obk
Update `InterpCx::project_field` to take `FieldIdx`
As suggested by Ralf in rust-lang#142005 (comment)
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 5, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
github-actionsBot pushed a commit to rust-lang/rustc-dev-guide that referenced this pull request Jul 7, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like rust-lang/rust#123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- rust-lang/rust#142005
- rust-lang/rust#142103
- rust-lang/rust#142324
- rust-lang/rust#142383
---
try-job: aarch64-gnu
Kobzol pushed a commit to Kobzol/rustc_codegen_gcc that referenced this pull request Dec 21, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like rust-lang/rust#123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- rust-lang/rust#142005
- rust-lang/rust#142103
- rust-lang/rust#142324
- rust-lang/rust#142383
---
try-job: aarch64-gnu
Kobzol pushed a commit to Kobzol/rustc_codegen_cranelift that referenced this pull request Dec 29, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like rust-lang/rust#123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- rust-lang/rust#142005
- rust-lang/rust#142103
- rust-lang/rust#142324
- rust-lang/rust#142383
---
try-job: aarch64-gnu
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
Rollup of 11 pull requests
Successful merges:
- rust-lang/rust#140418 (Reexport types from `c_size_t` in `std`)
- rust-lang/rust#141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- rust-lang/rust#141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- rust-lang/rust#142043 (Verbose suggestion to make param `const`)
- rust-lang/rust#142086 (duduplicate more AST visitor methods)
- rust-lang/rust#142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- rust-lang/rust#142105 (remove extraneous text)
- rust-lang/rust#142112 (fix typo)
- rust-lang/rust#142113 (Reduce confusion of some drop order tests)
- rust-lang/rust#142114 (Compute number of digits instead of relying on constant value for u128 display code)
- rust-lang/rust#142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
Rollup of 11 pull requests
Successful merges:
- rust-lang/rust#140418 (Reexport types from `c_size_t` in `std`)
- rust-lang/rust#141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- rust-lang/rust#141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- rust-lang/rust#142043 (Verbose suggestion to make param `const`)
- rust-lang/rust#142086 (duduplicate more AST visitor methods)
- rust-lang/rust#142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- rust-lang/rust#142105 (remove extraneous text)
- rust-lang/rust#142112 (fix typo)
- rust-lang/rust#142113 (Reduce confusion of some drop order tests)
- rust-lang/rust#142114 (Compute number of digits instead of relying on constant value for u128 display code)
- rust-lang/rust#142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-borsStatus: Waiting on bors to run and complete tests. Bors will change the label on completion.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants

@scottmcm@rustbot@rust-log-analyzer@oli-obk@bors@RalfJung@WaffleLapkin@cjgillot
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Update `InterpCx::project_field` to take `FieldIdx` by scottmcm · Pull Request #142103 · rust-lang/rust · GitHub
Skip to content

Update InterpCx::project_field to take FieldIdx - #142103

Merged
bors merged 2 commits into
rust-lang:masterfrom
scottmcm:fieldidx-in-interp
Jun 7, 2025
Merged

Update InterpCx::project_field to take FieldIdx#142103
bors merged 2 commits into
rust-lang:masterfrom
scottmcm:fieldidx-in-interp

Conversation

@scottmcm

@scottmcmscottmcm commented Jun 6, 2025

Copy link
Copy Markdown
Member

As suggested by Ralf in #142005 (comment)

@rustbot

Copy link
Copy Markdown
Collaborator

r? @oli-obk

rustbot has assigned @oli-obk.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbotrustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 6, 2025
@rustbot

Copy link
Copy Markdown
Collaborator

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

Some changes occurred in compiler/rustc_codegen_ssa

cc @WaffleLapkin

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

The Miri subtree was changed

cc @rust-lang/miri

@rust-log-analyzer

This comment has been minimized.

As suggested by Ralf in 142005.
@scottmcm
scottmcmforce-pushed the fieldidx-in-interp branch from 74c269e to 8bce225CompareJune 6, 2025 02:16

@oli-obkoli-obk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR highlights several situations where we can do improvements, but let's land this on its own and investigate from_usize and as_usize calls later

return None;
}
found = Some((field_idx, field));
found = Some((FieldIdx::from_usize(field_idx), field));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it may be worth adding an iter and an iter_enumerated method to FieldsShape

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, most of the layout-related usizes in ABI are sketchy. I've tried pulling on the tendrils before, but usually ended up giving up because of just how far that goes and -- as I mentioned in the other PR -- that the ones related to arrays sometimes need more than FieldIdx, and figuring out which those are can be hard.

(Conveniently this one was obvious because a over-4-billion-length array clearly can't have exactly one non-ZST.)

@oli-obk

Copy link
Copy Markdown
Contributor

@bors r+ rollup

@bors

bors commented Jun 6, 2025

Copy link
Copy Markdown
Collaborator

📌 Commit 8bce225 has been approved by oli-obk

It is now in the queue for this repository.

@borsbors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 6, 2025
Comment threadcompiler/rustc_abi/src/layout/ty.rs Outdated
impl FieldIdx {
/// The second field.
///
/// For use alongside [`FieldIdx::ZERO`], particularly with scalar pairs.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this not defined near FieldIdx::ZERO?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because all rustc_newtype_index! types get a ZERO; it's not something special for FieldIdx.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can add a const ONE = 1; in the macro to get it generated.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That generates it as a non-associated constant, though -- like the START_BLOCK mentioned -- not an associated one. And because ZERO is associated, I wanted ONE to be associated as well.

let fields_iter = (0..field_count)
.map(|i| {
let field_op = ecx.project_field(&down, i).discard_err()?;
let field_op = ecx.project_field(&down, FieldIdx::from_usize(i)).discard_err()?;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could also use a typed field iterator


for i in 0..field_count {
let field = ecx.project_field(&place, i).unwrap();
let field = ecx.project_field(&place, FieldIdx::from_usize(i)).unwrap();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And more here

(probably not worth pointing them all out)

// Computing the layout does normalization, so we get a normalized type out of this
// even if the field type is non-normalized (possible e.g. via associated types).
let field_layout = base.layout().field(self, field);
let field_layout = base.layout().field(self, field.as_usize());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does field not take FieldIdx...?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Co-authored-by: Ralf Jung <post@ralfj.de>
@scottmcm

Copy link
Copy Markdown
MemberAuthor

@bors r=oli-obk

@bors

bors commented Jun 6, 2025

Copy link
Copy Markdown
Collaborator

📌 Commit f9cf096 has been approved by oli-obk

It is now in the queue for this repository.

@RalfJung

RalfJung commented Jun 6, 2025 via email

Copy link
Copy Markdown
Member

@scottmcm

Copy link
Copy Markdown
MemberAuthor

I think "project" overstates at least how I've been handling this. I had rust-lang/compiler-team#606 to add FieldIdx originally, then @WaffleLapkin's rust-lang/compiler-team#639 is explicitly about using it in more places.

There's never been a tracking issue for it, or a list of all the things that should happen, or anything. Just a bunch of "spots I saw in passing" PRs.

bors added a commit that referenced this pull request Jun 7, 2025
Rollup of 11 pull requests
Successful merges:
- #140418 (Reexport types from `c_size_t` in `std`)
- #141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- #141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- #142043 (Verbose suggestion to make param `const`)
- #142086 (duduplicate more AST visitor methods)
- #142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- #142105 (remove extraneous text)
- #142112 (fix typo)
- #142113 (Reduce confusion of some drop order tests)
- #142114 (Compute number of digits instead of relying on constant value for u128 display code)
- #142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
@bors
bors merged commit 3a6f1b0 into rust-lang:masterJun 7, 2025
@rustbotrustbot added this to the 1.89.0 milestone Jun 7, 2025
rust-timer added a commit that referenced this pull request Jun 7, 2025
Rollup merge of #142103 - scottmcm:fieldidx-in-interp, r=oli-obk
Update `InterpCx::project_field` to take `FieldIdx`
As suggested by Ralf in #142005 (comment)
github-actionsBot pushed a commit to rust-lang/miri that referenced this pull request Jun 7, 2025
Rollup of 11 pull requests
Successful merges:
- rust-lang/rust#140418 (Reexport types from `c_size_t` in `std`)
- rust-lang/rust#141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- rust-lang/rust#141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- rust-lang/rust#142043 (Verbose suggestion to make param `const`)
- rust-lang/rust#142086 (duduplicate more AST visitor methods)
- rust-lang/rust#142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- rust-lang/rust#142105 (remove extraneous text)
- rust-lang/rust#142112 (fix typo)
- rust-lang/rust#142113 (Reduce confusion of some drop order tests)
- rust-lang/rust#142114 (Compute number of digits instead of relying on constant value for u128 display code)
- rust-lang/rust#142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
@scottmcm
scottmcm deleted the fieldidx-in-interp branch June 7, 2025 22:58
@WaffleLapkin

Copy link
Copy Markdown
Member

@WaffleLapkin's rust-lang/compiler-team#639 is explicitly about using it in more places.

Oh. Did I mean to work on it and then forgot? 😓

bors added a commit that referenced this pull request Jun 19, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
bjorn3 pushed a commit to bjorn3/rust that referenced this pull request Jun 24, 2025
…-obk
Update `InterpCx::project_field` to take `FieldIdx`
As suggested by Ralf in rust-lang#142005 (comment)
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 5, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
github-actionsBot pushed a commit to rust-lang/rustc-dev-guide that referenced this pull request Jul 7, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like rust-lang/rust#123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- rust-lang/rust#142005
- rust-lang/rust#142103
- rust-lang/rust#142324
- rust-lang/rust#142383
---
try-job: aarch64-gnu
Kobzol pushed a commit to Kobzol/rustc_codegen_gcc that referenced this pull request Dec 21, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like rust-lang/rust#123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- rust-lang/rust#142005
- rust-lang/rust#142103
- rust-lang/rust#142324
- rust-lang/rust#142383
---
try-job: aarch64-gnu
Kobzol pushed a commit to Kobzol/rustc_codegen_cranelift that referenced this pull request Dec 29, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like rust-lang/rust#123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- rust-lang/rust#142005
- rust-lang/rust#142103
- rust-lang/rust#142324
- rust-lang/rust#142383
---
try-job: aarch64-gnu
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
Rollup of 11 pull requests
Successful merges:
- rust-lang/rust#140418 (Reexport types from `c_size_t` in `std`)
- rust-lang/rust#141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- rust-lang/rust#141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- rust-lang/rust#142043 (Verbose suggestion to make param `const`)
- rust-lang/rust#142086 (duduplicate more AST visitor methods)
- rust-lang/rust#142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- rust-lang/rust#142105 (remove extraneous text)
- rust-lang/rust#142112 (fix typo)
- rust-lang/rust#142113 (Reduce confusion of some drop order tests)
- rust-lang/rust#142114 (Compute number of digits instead of relying on constant value for u128 display code)
- rust-lang/rust#142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
Rollup of 11 pull requests
Successful merges:
- rust-lang/rust#140418 (Reexport types from `c_size_t` in `std`)
- rust-lang/rust#141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- rust-lang/rust#141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- rust-lang/rust#142043 (Verbose suggestion to make param `const`)
- rust-lang/rust#142086 (duduplicate more AST visitor methods)
- rust-lang/rust#142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- rust-lang/rust#142105 (remove extraneous text)
- rust-lang/rust#142112 (fix typo)
- rust-lang/rust#142113 (Reduce confusion of some drop order tests)
- rust-lang/rust#142114 (Compute number of digits instead of relying on constant value for u128 display code)
- rust-lang/rust#142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-borsStatus: Waiting on bors to run and complete tests. Bors will change the label on completion.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants

@scottmcm@rustbot@rust-log-analyzer@oli-obk@bors@RalfJung@WaffleLapkin@cjgillot
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Update `InterpCx::project_field` to take `FieldIdx` by scottmcm · Pull Request #142103 · rust-lang/rust · GitHub
Skip to content

Update InterpCx::project_field to take FieldIdx - #142103

Merged
bors merged 2 commits into
rust-lang:masterfrom
scottmcm:fieldidx-in-interp
Jun 7, 2025
Merged

Update InterpCx::project_field to take FieldIdx#142103
bors merged 2 commits into
rust-lang:masterfrom
scottmcm:fieldidx-in-interp

Conversation

@scottmcm

@scottmcmscottmcm commented Jun 6, 2025

Copy link
Copy Markdown
Member

As suggested by Ralf in #142005 (comment)

@rustbot

Copy link
Copy Markdown
Collaborator

r? @oli-obk

rustbot has assigned @oli-obk.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbotrustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 6, 2025
@rustbot

Copy link
Copy Markdown
Collaborator

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

Some changes occurred in compiler/rustc_codegen_ssa

cc @WaffleLapkin

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

The Miri subtree was changed

cc @rust-lang/miri

@rust-log-analyzer

This comment has been minimized.

As suggested by Ralf in 142005.
@scottmcm
scottmcmforce-pushed the fieldidx-in-interp branch from 74c269e to 8bce225CompareJune 6, 2025 02:16

@oli-obkoli-obk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR highlights several situations where we can do improvements, but let's land this on its own and investigate from_usize and as_usize calls later

return None;
}
found = Some((field_idx, field));
found = Some((FieldIdx::from_usize(field_idx), field));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it may be worth adding an iter and an iter_enumerated method to FieldsShape

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, most of the layout-related usizes in ABI are sketchy. I've tried pulling on the tendrils before, but usually ended up giving up because of just how far that goes and -- as I mentioned in the other PR -- that the ones related to arrays sometimes need more than FieldIdx, and figuring out which those are can be hard.

(Conveniently this one was obvious because a over-4-billion-length array clearly can't have exactly one non-ZST.)

@oli-obk

Copy link
Copy Markdown
Contributor

@bors r+ rollup

@bors

bors commented Jun 6, 2025

Copy link
Copy Markdown
Collaborator

📌 Commit 8bce225 has been approved by oli-obk

It is now in the queue for this repository.

@borsbors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 6, 2025
Comment threadcompiler/rustc_abi/src/layout/ty.rs Outdated
impl FieldIdx {
/// The second field.
///
/// For use alongside [`FieldIdx::ZERO`], particularly with scalar pairs.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this not defined near FieldIdx::ZERO?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because all rustc_newtype_index! types get a ZERO; it's not something special for FieldIdx.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can add a const ONE = 1; in the macro to get it generated.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That generates it as a non-associated constant, though -- like the START_BLOCK mentioned -- not an associated one. And because ZERO is associated, I wanted ONE to be associated as well.

let fields_iter = (0..field_count)
.map(|i| {
let field_op = ecx.project_field(&down, i).discard_err()?;
let field_op = ecx.project_field(&down, FieldIdx::from_usize(i)).discard_err()?;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could also use a typed field iterator


for i in 0..field_count {
let field = ecx.project_field(&place, i).unwrap();
let field = ecx.project_field(&place, FieldIdx::from_usize(i)).unwrap();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And more here

(probably not worth pointing them all out)

// Computing the layout does normalization, so we get a normalized type out of this
// even if the field type is non-normalized (possible e.g. via associated types).
let field_layout = base.layout().field(self, field);
let field_layout = base.layout().field(self, field.as_usize());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does field not take FieldIdx...?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Co-authored-by: Ralf Jung <post@ralfj.de>
@scottmcm

Copy link
Copy Markdown
MemberAuthor

@bors r=oli-obk

@bors

bors commented Jun 6, 2025

Copy link
Copy Markdown
Collaborator

📌 Commit f9cf096 has been approved by oli-obk

It is now in the queue for this repository.

@RalfJung

RalfJung commented Jun 6, 2025 via email

Copy link
Copy Markdown
Member

@scottmcm

Copy link
Copy Markdown
MemberAuthor

I think "project" overstates at least how I've been handling this. I had rust-lang/compiler-team#606 to add FieldIdx originally, then @WaffleLapkin's rust-lang/compiler-team#639 is explicitly about using it in more places.

There's never been a tracking issue for it, or a list of all the things that should happen, or anything. Just a bunch of "spots I saw in passing" PRs.

bors added a commit that referenced this pull request Jun 7, 2025
Rollup of 11 pull requests
Successful merges:
- #140418 (Reexport types from `c_size_t` in `std`)
- #141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- #141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- #142043 (Verbose suggestion to make param `const`)
- #142086 (duduplicate more AST visitor methods)
- #142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- #142105 (remove extraneous text)
- #142112 (fix typo)
- #142113 (Reduce confusion of some drop order tests)
- #142114 (Compute number of digits instead of relying on constant value for u128 display code)
- #142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
@bors
bors merged commit 3a6f1b0 into rust-lang:masterJun 7, 2025
@rustbotrustbot added this to the 1.89.0 milestone Jun 7, 2025
rust-timer added a commit that referenced this pull request Jun 7, 2025
Rollup merge of #142103 - scottmcm:fieldidx-in-interp, r=oli-obk
Update `InterpCx::project_field` to take `FieldIdx`
As suggested by Ralf in #142005 (comment)
github-actionsBot pushed a commit to rust-lang/miri that referenced this pull request Jun 7, 2025
Rollup of 11 pull requests
Successful merges:
- rust-lang/rust#140418 (Reexport types from `c_size_t` in `std`)
- rust-lang/rust#141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- rust-lang/rust#141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- rust-lang/rust#142043 (Verbose suggestion to make param `const`)
- rust-lang/rust#142086 (duduplicate more AST visitor methods)
- rust-lang/rust#142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- rust-lang/rust#142105 (remove extraneous text)
- rust-lang/rust#142112 (fix typo)
- rust-lang/rust#142113 (Reduce confusion of some drop order tests)
- rust-lang/rust#142114 (Compute number of digits instead of relying on constant value for u128 display code)
- rust-lang/rust#142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
@scottmcm
scottmcm deleted the fieldidx-in-interp branch June 7, 2025 22:58
@WaffleLapkin

Copy link
Copy Markdown
Member

@WaffleLapkin's rust-lang/compiler-team#639 is explicitly about using it in more places.

Oh. Did I mean to work on it and then forgot? 😓

bors added a commit that referenced this pull request Jun 19, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
bjorn3 pushed a commit to bjorn3/rust that referenced this pull request Jun 24, 2025
…-obk
Update `InterpCx::project_field` to take `FieldIdx`
As suggested by Ralf in rust-lang#142005 (comment)
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 5, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
github-actionsBot pushed a commit to rust-lang/rustc-dev-guide that referenced this pull request Jul 7, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like rust-lang/rust#123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- rust-lang/rust#142005
- rust-lang/rust#142103
- rust-lang/rust#142324
- rust-lang/rust#142383
---
try-job: aarch64-gnu
Kobzol pushed a commit to Kobzol/rustc_codegen_gcc that referenced this pull request Dec 21, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like rust-lang/rust#123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- rust-lang/rust#142005
- rust-lang/rust#142103
- rust-lang/rust#142324
- rust-lang/rust#142383
---
try-job: aarch64-gnu
Kobzol pushed a commit to Kobzol/rustc_codegen_cranelift that referenced this pull request Dec 29, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like rust-lang/rust#123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- rust-lang/rust#142005
- rust-lang/rust#142103
- rust-lang/rust#142324
- rust-lang/rust#142383
---
try-job: aarch64-gnu
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
Rollup of 11 pull requests
Successful merges:
- rust-lang/rust#140418 (Reexport types from `c_size_t` in `std`)
- rust-lang/rust#141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- rust-lang/rust#141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- rust-lang/rust#142043 (Verbose suggestion to make param `const`)
- rust-lang/rust#142086 (duduplicate more AST visitor methods)
- rust-lang/rust#142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- rust-lang/rust#142105 (remove extraneous text)
- rust-lang/rust#142112 (fix typo)
- rust-lang/rust#142113 (Reduce confusion of some drop order tests)
- rust-lang/rust#142114 (Compute number of digits instead of relying on constant value for u128 display code)
- rust-lang/rust#142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
Rollup of 11 pull requests
Successful merges:
- rust-lang/rust#140418 (Reexport types from `c_size_t` in `std`)
- rust-lang/rust#141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- rust-lang/rust#141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- rust-lang/rust#142043 (Verbose suggestion to make param `const`)
- rust-lang/rust#142086 (duduplicate more AST visitor methods)
- rust-lang/rust#142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- rust-lang/rust#142105 (remove extraneous text)
- rust-lang/rust#142112 (fix typo)
- rust-lang/rust#142113 (Reduce confusion of some drop order tests)
- rust-lang/rust#142114 (Compute number of digits instead of relying on constant value for u128 display code)
- rust-lang/rust#142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-borsStatus: Waiting on bors to run and complete tests. Bors will change the label on completion.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants

@scottmcm@rustbot@rust-log-analyzer@oli-obk@bors@RalfJung@WaffleLapkin@cjgillot
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Update `InterpCx::project_field` to take `FieldIdx` by scottmcm · Pull Request #142103 · rust-lang/rust · GitHub
Skip to content

Update InterpCx::project_field to take FieldIdx - #142103

Merged
bors merged 2 commits into
rust-lang:masterfrom
scottmcm:fieldidx-in-interp
Jun 7, 2025
Merged

Update InterpCx::project_field to take FieldIdx#142103
bors merged 2 commits into
rust-lang:masterfrom
scottmcm:fieldidx-in-interp

Conversation

@scottmcm

@scottmcmscottmcm commented Jun 6, 2025

Copy link
Copy Markdown
Member

As suggested by Ralf in #142005 (comment)

@rustbot

Copy link
Copy Markdown
Collaborator

r? @oli-obk

rustbot has assigned @oli-obk.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbotrustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 6, 2025
@rustbot

Copy link
Copy Markdown
Collaborator

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

Some changes occurred in compiler/rustc_codegen_ssa

cc @WaffleLapkin

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

The Miri subtree was changed

cc @rust-lang/miri

@rust-log-analyzer

This comment has been minimized.

As suggested by Ralf in 142005.
@scottmcm
scottmcmforce-pushed the fieldidx-in-interp branch from 74c269e to 8bce225CompareJune 6, 2025 02:16

@oli-obkoli-obk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR highlights several situations where we can do improvements, but let's land this on its own and investigate from_usize and as_usize calls later

return None;
}
found = Some((field_idx, field));
found = Some((FieldIdx::from_usize(field_idx), field));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it may be worth adding an iter and an iter_enumerated method to FieldsShape

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, most of the layout-related usizes in ABI are sketchy. I've tried pulling on the tendrils before, but usually ended up giving up because of just how far that goes and -- as I mentioned in the other PR -- that the ones related to arrays sometimes need more than FieldIdx, and figuring out which those are can be hard.

(Conveniently this one was obvious because a over-4-billion-length array clearly can't have exactly one non-ZST.)

@oli-obk

Copy link
Copy Markdown
Contributor

@bors r+ rollup

@bors

bors commented Jun 6, 2025

Copy link
Copy Markdown
Collaborator

📌 Commit 8bce225 has been approved by oli-obk

It is now in the queue for this repository.

@borsbors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 6, 2025
Comment threadcompiler/rustc_abi/src/layout/ty.rs Outdated
impl FieldIdx {
/// The second field.
///
/// For use alongside [`FieldIdx::ZERO`], particularly with scalar pairs.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this not defined near FieldIdx::ZERO?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because all rustc_newtype_index! types get a ZERO; it's not something special for FieldIdx.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can add a const ONE = 1; in the macro to get it generated.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That generates it as a non-associated constant, though -- like the START_BLOCK mentioned -- not an associated one. And because ZERO is associated, I wanted ONE to be associated as well.

let fields_iter = (0..field_count)
.map(|i| {
let field_op = ecx.project_field(&down, i).discard_err()?;
let field_op = ecx.project_field(&down, FieldIdx::from_usize(i)).discard_err()?;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could also use a typed field iterator


for i in 0..field_count {
let field = ecx.project_field(&place, i).unwrap();
let field = ecx.project_field(&place, FieldIdx::from_usize(i)).unwrap();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And more here

(probably not worth pointing them all out)

// Computing the layout does normalization, so we get a normalized type out of this
// even if the field type is non-normalized (possible e.g. via associated types).
let field_layout = base.layout().field(self, field);
let field_layout = base.layout().field(self, field.as_usize());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does field not take FieldIdx...?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Co-authored-by: Ralf Jung <post@ralfj.de>
@scottmcm

Copy link
Copy Markdown
MemberAuthor

@bors r=oli-obk

@bors

bors commented Jun 6, 2025

Copy link
Copy Markdown
Collaborator

📌 Commit f9cf096 has been approved by oli-obk

It is now in the queue for this repository.

@RalfJung

RalfJung commented Jun 6, 2025 via email

Copy link
Copy Markdown
Member

@scottmcm

Copy link
Copy Markdown
MemberAuthor

I think "project" overstates at least how I've been handling this. I had rust-lang/compiler-team#606 to add FieldIdx originally, then @WaffleLapkin's rust-lang/compiler-team#639 is explicitly about using it in more places.

There's never been a tracking issue for it, or a list of all the things that should happen, or anything. Just a bunch of "spots I saw in passing" PRs.

bors added a commit that referenced this pull request Jun 7, 2025
Rollup of 11 pull requests
Successful merges:
- #140418 (Reexport types from `c_size_t` in `std`)
- #141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- #141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- #142043 (Verbose suggestion to make param `const`)
- #142086 (duduplicate more AST visitor methods)
- #142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- #142105 (remove extraneous text)
- #142112 (fix typo)
- #142113 (Reduce confusion of some drop order tests)
- #142114 (Compute number of digits instead of relying on constant value for u128 display code)
- #142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
@bors
bors merged commit 3a6f1b0 into rust-lang:masterJun 7, 2025
@rustbotrustbot added this to the 1.89.0 milestone Jun 7, 2025
rust-timer added a commit that referenced this pull request Jun 7, 2025
Rollup merge of #142103 - scottmcm:fieldidx-in-interp, r=oli-obk
Update `InterpCx::project_field` to take `FieldIdx`
As suggested by Ralf in #142005 (comment)
github-actionsBot pushed a commit to rust-lang/miri that referenced this pull request Jun 7, 2025
Rollup of 11 pull requests
Successful merges:
- rust-lang/rust#140418 (Reexport types from `c_size_t` in `std`)
- rust-lang/rust#141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- rust-lang/rust#141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- rust-lang/rust#142043 (Verbose suggestion to make param `const`)
- rust-lang/rust#142086 (duduplicate more AST visitor methods)
- rust-lang/rust#142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- rust-lang/rust#142105 (remove extraneous text)
- rust-lang/rust#142112 (fix typo)
- rust-lang/rust#142113 (Reduce confusion of some drop order tests)
- rust-lang/rust#142114 (Compute number of digits instead of relying on constant value for u128 display code)
- rust-lang/rust#142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
@scottmcm
scottmcm deleted the fieldidx-in-interp branch June 7, 2025 22:58
@WaffleLapkin

Copy link
Copy Markdown
Member

@WaffleLapkin's rust-lang/compiler-team#639 is explicitly about using it in more places.

Oh. Did I mean to work on it and then forgot? 😓

bors added a commit that referenced this pull request Jun 19, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
bjorn3 pushed a commit to bjorn3/rust that referenced this pull request Jun 24, 2025
…-obk
Update `InterpCx::project_field` to take `FieldIdx`
As suggested by Ralf in rust-lang#142005 (comment)
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 5, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
github-actionsBot pushed a commit to rust-lang/rustc-dev-guide that referenced this pull request Jul 7, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like rust-lang/rust#123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- rust-lang/rust#142005
- rust-lang/rust#142103
- rust-lang/rust#142324
- rust-lang/rust#142383
---
try-job: aarch64-gnu
Kobzol pushed a commit to Kobzol/rustc_codegen_gcc that referenced this pull request Dec 21, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like rust-lang/rust#123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- rust-lang/rust#142005
- rust-lang/rust#142103
- rust-lang/rust#142324
- rust-lang/rust#142383
---
try-job: aarch64-gnu
Kobzol pushed a commit to Kobzol/rustc_codegen_cranelift that referenced this pull request Dec 29, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like rust-lang/rust#123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- rust-lang/rust#142005
- rust-lang/rust#142103
- rust-lang/rust#142324
- rust-lang/rust#142383
---
try-job: aarch64-gnu
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
Rollup of 11 pull requests
Successful merges:
- rust-lang/rust#140418 (Reexport types from `c_size_t` in `std`)
- rust-lang/rust#141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- rust-lang/rust#141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- rust-lang/rust#142043 (Verbose suggestion to make param `const`)
- rust-lang/rust#142086 (duduplicate more AST visitor methods)
- rust-lang/rust#142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- rust-lang/rust#142105 (remove extraneous text)
- rust-lang/rust#142112 (fix typo)
- rust-lang/rust#142113 (Reduce confusion of some drop order tests)
- rust-lang/rust#142114 (Compute number of digits instead of relying on constant value for u128 display code)
- rust-lang/rust#142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
Rollup of 11 pull requests
Successful merges:
- rust-lang/rust#140418 (Reexport types from `c_size_t` in `std`)
- rust-lang/rust#141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- rust-lang/rust#141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- rust-lang/rust#142043 (Verbose suggestion to make param `const`)
- rust-lang/rust#142086 (duduplicate more AST visitor methods)
- rust-lang/rust#142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- rust-lang/rust#142105 (remove extraneous text)
- rust-lang/rust#142112 (fix typo)
- rust-lang/rust#142113 (Reduce confusion of some drop order tests)
- rust-lang/rust#142114 (Compute number of digits instead of relying on constant value for u128 display code)
- rust-lang/rust#142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-borsStatus: Waiting on bors to run and complete tests. Bors will change the label on completion.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants

@scottmcm@rustbot@rust-log-analyzer@oli-obk@bors@RalfJung@WaffleLapkin@cjgillot
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Update `InterpCx::project_field` to take `FieldIdx` by scottmcm · Pull Request #142103 · rust-lang/rust · GitHub
Skip to content

Update InterpCx::project_field to take FieldIdx - #142103

Merged
bors merged 2 commits into
rust-lang:masterfrom
scottmcm:fieldidx-in-interp
Jun 7, 2025
Merged

Update InterpCx::project_field to take FieldIdx#142103
bors merged 2 commits into
rust-lang:masterfrom
scottmcm:fieldidx-in-interp

Conversation

@scottmcm

@scottmcmscottmcm commented Jun 6, 2025

Copy link
Copy Markdown
Member

As suggested by Ralf in #142005 (comment)

@rustbot

Copy link
Copy Markdown
Collaborator

r? @oli-obk

rustbot has assigned @oli-obk.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbotrustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 6, 2025
@rustbot

Copy link
Copy Markdown
Collaborator

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

Some changes occurred in compiler/rustc_codegen_ssa

cc @WaffleLapkin

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

The Miri subtree was changed

cc @rust-lang/miri

@rust-log-analyzer

This comment has been minimized.

As suggested by Ralf in 142005.
@scottmcm
scottmcmforce-pushed the fieldidx-in-interp branch from 74c269e to 8bce225CompareJune 6, 2025 02:16

@oli-obkoli-obk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR highlights several situations where we can do improvements, but let's land this on its own and investigate from_usize and as_usize calls later

return None;
}
found = Some((field_idx, field));
found = Some((FieldIdx::from_usize(field_idx), field));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it may be worth adding an iter and an iter_enumerated method to FieldsShape

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, most of the layout-related usizes in ABI are sketchy. I've tried pulling on the tendrils before, but usually ended up giving up because of just how far that goes and -- as I mentioned in the other PR -- that the ones related to arrays sometimes need more than FieldIdx, and figuring out which those are can be hard.

(Conveniently this one was obvious because a over-4-billion-length array clearly can't have exactly one non-ZST.)

@oli-obk

Copy link
Copy Markdown
Contributor

@bors r+ rollup

@bors

bors commented Jun 6, 2025

Copy link
Copy Markdown
Collaborator

📌 Commit 8bce225 has been approved by oli-obk

It is now in the queue for this repository.

@borsbors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 6, 2025
Comment threadcompiler/rustc_abi/src/layout/ty.rs Outdated
impl FieldIdx {
/// The second field.
///
/// For use alongside [`FieldIdx::ZERO`], particularly with scalar pairs.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this not defined near FieldIdx::ZERO?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because all rustc_newtype_index! types get a ZERO; it's not something special for FieldIdx.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can add a const ONE = 1; in the macro to get it generated.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That generates it as a non-associated constant, though -- like the START_BLOCK mentioned -- not an associated one. And because ZERO is associated, I wanted ONE to be associated as well.

let fields_iter = (0..field_count)
.map(|i| {
let field_op = ecx.project_field(&down, i).discard_err()?;
let field_op = ecx.project_field(&down, FieldIdx::from_usize(i)).discard_err()?;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could also use a typed field iterator


for i in 0..field_count {
let field = ecx.project_field(&place, i).unwrap();
let field = ecx.project_field(&place, FieldIdx::from_usize(i)).unwrap();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And more here

(probably not worth pointing them all out)

// Computing the layout does normalization, so we get a normalized type out of this
// even if the field type is non-normalized (possible e.g. via associated types).
let field_layout = base.layout().field(self, field);
let field_layout = base.layout().field(self, field.as_usize());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does field not take FieldIdx...?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Co-authored-by: Ralf Jung <post@ralfj.de>
@scottmcm

Copy link
Copy Markdown
MemberAuthor

@bors r=oli-obk

@bors

bors commented Jun 6, 2025

Copy link
Copy Markdown
Collaborator

📌 Commit f9cf096 has been approved by oli-obk

It is now in the queue for this repository.

@RalfJung

RalfJung commented Jun 6, 2025 via email

Copy link
Copy Markdown
Member

@scottmcm

Copy link
Copy Markdown
MemberAuthor

I think "project" overstates at least how I've been handling this. I had rust-lang/compiler-team#606 to add FieldIdx originally, then @WaffleLapkin's rust-lang/compiler-team#639 is explicitly about using it in more places.

There's never been a tracking issue for it, or a list of all the things that should happen, or anything. Just a bunch of "spots I saw in passing" PRs.

bors added a commit that referenced this pull request Jun 7, 2025
Rollup of 11 pull requests
Successful merges:
- #140418 (Reexport types from `c_size_t` in `std`)
- #141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- #141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- #142043 (Verbose suggestion to make param `const`)
- #142086 (duduplicate more AST visitor methods)
- #142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- #142105 (remove extraneous text)
- #142112 (fix typo)
- #142113 (Reduce confusion of some drop order tests)
- #142114 (Compute number of digits instead of relying on constant value for u128 display code)
- #142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
@bors
bors merged commit 3a6f1b0 into rust-lang:masterJun 7, 2025
@rustbotrustbot added this to the 1.89.0 milestone Jun 7, 2025
rust-timer added a commit that referenced this pull request Jun 7, 2025
Rollup merge of #142103 - scottmcm:fieldidx-in-interp, r=oli-obk
Update `InterpCx::project_field` to take `FieldIdx`
As suggested by Ralf in #142005 (comment)
github-actionsBot pushed a commit to rust-lang/miri that referenced this pull request Jun 7, 2025
Rollup of 11 pull requests
Successful merges:
- rust-lang/rust#140418 (Reexport types from `c_size_t` in `std`)
- rust-lang/rust#141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- rust-lang/rust#141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- rust-lang/rust#142043 (Verbose suggestion to make param `const`)
- rust-lang/rust#142086 (duduplicate more AST visitor methods)
- rust-lang/rust#142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- rust-lang/rust#142105 (remove extraneous text)
- rust-lang/rust#142112 (fix typo)
- rust-lang/rust#142113 (Reduce confusion of some drop order tests)
- rust-lang/rust#142114 (Compute number of digits instead of relying on constant value for u128 display code)
- rust-lang/rust#142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
@scottmcm
scottmcm deleted the fieldidx-in-interp branch June 7, 2025 22:58
@WaffleLapkin

Copy link
Copy Markdown
Member

@WaffleLapkin's rust-lang/compiler-team#639 is explicitly about using it in more places.

Oh. Did I mean to work on it and then forgot? 😓

bors added a commit that referenced this pull request Jun 19, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
bjorn3 pushed a commit to bjorn3/rust that referenced this pull request Jun 24, 2025
…-obk
Update `InterpCx::project_field` to take `FieldIdx`
As suggested by Ralf in rust-lang#142005 (comment)
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 5, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
github-actionsBot pushed a commit to rust-lang/rustc-dev-guide that referenced this pull request Jul 7, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like rust-lang/rust#123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- rust-lang/rust#142005
- rust-lang/rust#142103
- rust-lang/rust#142324
- rust-lang/rust#142383
---
try-job: aarch64-gnu
Kobzol pushed a commit to Kobzol/rustc_codegen_gcc that referenced this pull request Dec 21, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like rust-lang/rust#123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- rust-lang/rust#142005
- rust-lang/rust#142103
- rust-lang/rust#142324
- rust-lang/rust#142383
---
try-job: aarch64-gnu
Kobzol pushed a commit to Kobzol/rustc_codegen_cranelift that referenced this pull request Dec 29, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like rust-lang/rust#123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- rust-lang/rust#142005
- rust-lang/rust#142103
- rust-lang/rust#142324
- rust-lang/rust#142383
---
try-job: aarch64-gnu
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
Rollup of 11 pull requests
Successful merges:
- rust-lang/rust#140418 (Reexport types from `c_size_t` in `std`)
- rust-lang/rust#141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- rust-lang/rust#141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- rust-lang/rust#142043 (Verbose suggestion to make param `const`)
- rust-lang/rust#142086 (duduplicate more AST visitor methods)
- rust-lang/rust#142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- rust-lang/rust#142105 (remove extraneous text)
- rust-lang/rust#142112 (fix typo)
- rust-lang/rust#142113 (Reduce confusion of some drop order tests)
- rust-lang/rust#142114 (Compute number of digits instead of relying on constant value for u128 display code)
- rust-lang/rust#142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
Rollup of 11 pull requests
Successful merges:
- rust-lang/rust#140418 (Reexport types from `c_size_t` in `std`)
- rust-lang/rust#141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- rust-lang/rust#141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- rust-lang/rust#142043 (Verbose suggestion to make param `const`)
- rust-lang/rust#142086 (duduplicate more AST visitor methods)
- rust-lang/rust#142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- rust-lang/rust#142105 (remove extraneous text)
- rust-lang/rust#142112 (fix typo)
- rust-lang/rust#142113 (Reduce confusion of some drop order tests)
- rust-lang/rust#142114 (Compute number of digits instead of relying on constant value for u128 display code)
- rust-lang/rust#142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-borsStatus: Waiting on bors to run and complete tests. Bors will change the label on completion.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants

@scottmcm@rustbot@rust-log-analyzer@oli-obk@bors@RalfJung@WaffleLapkin@cjgillot
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Update `InterpCx::project_field` to take `FieldIdx` by scottmcm · Pull Request #142103 · rust-lang/rust · GitHub
Skip to content

Update InterpCx::project_field to take FieldIdx - #142103

Merged
bors merged 2 commits into
rust-lang:masterfrom
scottmcm:fieldidx-in-interp
Jun 7, 2025
Merged

Update InterpCx::project_field to take FieldIdx#142103
bors merged 2 commits into
rust-lang:masterfrom
scottmcm:fieldidx-in-interp

Conversation

@scottmcm

@scottmcmscottmcm commented Jun 6, 2025

Copy link
Copy Markdown
Member

As suggested by Ralf in #142005 (comment)

@rustbot

Copy link
Copy Markdown
Collaborator

r? @oli-obk

rustbot has assigned @oli-obk.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbotrustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 6, 2025
@rustbot

Copy link
Copy Markdown
Collaborator

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

Some changes occurred in compiler/rustc_codegen_ssa

cc @WaffleLapkin

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

The Miri subtree was changed

cc @rust-lang/miri

@rust-log-analyzer

This comment has been minimized.

As suggested by Ralf in 142005.
@scottmcm
scottmcmforce-pushed the fieldidx-in-interp branch from 74c269e to 8bce225CompareJune 6, 2025 02:16

@oli-obkoli-obk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR highlights several situations where we can do improvements, but let's land this on its own and investigate from_usize and as_usize calls later

return None;
}
found = Some((field_idx, field));
found = Some((FieldIdx::from_usize(field_idx), field));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it may be worth adding an iter and an iter_enumerated method to FieldsShape

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, most of the layout-related usizes in ABI are sketchy. I've tried pulling on the tendrils before, but usually ended up giving up because of just how far that goes and -- as I mentioned in the other PR -- that the ones related to arrays sometimes need more than FieldIdx, and figuring out which those are can be hard.

(Conveniently this one was obvious because a over-4-billion-length array clearly can't have exactly one non-ZST.)

@oli-obk

Copy link
Copy Markdown
Contributor

@bors r+ rollup

@bors

bors commented Jun 6, 2025

Copy link
Copy Markdown
Collaborator

📌 Commit 8bce225 has been approved by oli-obk

It is now in the queue for this repository.

@borsbors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 6, 2025
Comment threadcompiler/rustc_abi/src/layout/ty.rs Outdated
impl FieldIdx {
/// The second field.
///
/// For use alongside [`FieldIdx::ZERO`], particularly with scalar pairs.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this not defined near FieldIdx::ZERO?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because all rustc_newtype_index! types get a ZERO; it's not something special for FieldIdx.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can add a const ONE = 1; in the macro to get it generated.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That generates it as a non-associated constant, though -- like the START_BLOCK mentioned -- not an associated one. And because ZERO is associated, I wanted ONE to be associated as well.

let fields_iter = (0..field_count)
.map(|i| {
let field_op = ecx.project_field(&down, i).discard_err()?;
let field_op = ecx.project_field(&down, FieldIdx::from_usize(i)).discard_err()?;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could also use a typed field iterator


for i in 0..field_count {
let field = ecx.project_field(&place, i).unwrap();
let field = ecx.project_field(&place, FieldIdx::from_usize(i)).unwrap();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And more here

(probably not worth pointing them all out)

// Computing the layout does normalization, so we get a normalized type out of this
// even if the field type is non-normalized (possible e.g. via associated types).
let field_layout = base.layout().field(self, field);
let field_layout = base.layout().field(self, field.as_usize());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does field not take FieldIdx...?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Co-authored-by: Ralf Jung <post@ralfj.de>
@scottmcm

Copy link
Copy Markdown
MemberAuthor

@bors r=oli-obk

@bors

bors commented Jun 6, 2025

Copy link
Copy Markdown
Collaborator

📌 Commit f9cf096 has been approved by oli-obk

It is now in the queue for this repository.

@RalfJung

RalfJung commented Jun 6, 2025 via email

Copy link
Copy Markdown
Member

@scottmcm

Copy link
Copy Markdown
MemberAuthor

I think "project" overstates at least how I've been handling this. I had rust-lang/compiler-team#606 to add FieldIdx originally, then @WaffleLapkin's rust-lang/compiler-team#639 is explicitly about using it in more places.

There's never been a tracking issue for it, or a list of all the things that should happen, or anything. Just a bunch of "spots I saw in passing" PRs.

bors added a commit that referenced this pull request Jun 7, 2025
Rollup of 11 pull requests
Successful merges:
- #140418 (Reexport types from `c_size_t` in `std`)
- #141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- #141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- #142043 (Verbose suggestion to make param `const`)
- #142086 (duduplicate more AST visitor methods)
- #142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- #142105 (remove extraneous text)
- #142112 (fix typo)
- #142113 (Reduce confusion of some drop order tests)
- #142114 (Compute number of digits instead of relying on constant value for u128 display code)
- #142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
@bors
bors merged commit 3a6f1b0 into rust-lang:masterJun 7, 2025
@rustbotrustbot added this to the 1.89.0 milestone Jun 7, 2025
rust-timer added a commit that referenced this pull request Jun 7, 2025
Rollup merge of #142103 - scottmcm:fieldidx-in-interp, r=oli-obk
Update `InterpCx::project_field` to take `FieldIdx`
As suggested by Ralf in #142005 (comment)
github-actionsBot pushed a commit to rust-lang/miri that referenced this pull request Jun 7, 2025
Rollup of 11 pull requests
Successful merges:
- rust-lang/rust#140418 (Reexport types from `c_size_t` in `std`)
- rust-lang/rust#141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- rust-lang/rust#141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- rust-lang/rust#142043 (Verbose suggestion to make param `const`)
- rust-lang/rust#142086 (duduplicate more AST visitor methods)
- rust-lang/rust#142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- rust-lang/rust#142105 (remove extraneous text)
- rust-lang/rust#142112 (fix typo)
- rust-lang/rust#142113 (Reduce confusion of some drop order tests)
- rust-lang/rust#142114 (Compute number of digits instead of relying on constant value for u128 display code)
- rust-lang/rust#142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
@scottmcm
scottmcm deleted the fieldidx-in-interp branch June 7, 2025 22:58
@WaffleLapkin

Copy link
Copy Markdown
Member

@WaffleLapkin's rust-lang/compiler-team#639 is explicitly about using it in more places.

Oh. Did I mean to work on it and then forgot? 😓

bors added a commit that referenced this pull request Jun 19, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
bjorn3 pushed a commit to bjorn3/rust that referenced this pull request Jun 24, 2025
…-obk
Update `InterpCx::project_field` to take `FieldIdx`
As suggested by Ralf in rust-lang#142005 (comment)
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 5, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
github-actionsBot pushed a commit to rust-lang/rustc-dev-guide that referenced this pull request Jul 7, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like rust-lang/rust#123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- rust-lang/rust#142005
- rust-lang/rust#142103
- rust-lang/rust#142324
- rust-lang/rust#142383
---
try-job: aarch64-gnu
Kobzol pushed a commit to Kobzol/rustc_codegen_gcc that referenced this pull request Dec 21, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like rust-lang/rust#123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- rust-lang/rust#142005
- rust-lang/rust#142103
- rust-lang/rust#142324
- rust-lang/rust#142383
---
try-job: aarch64-gnu
Kobzol pushed a commit to Kobzol/rustc_codegen_cranelift that referenced this pull request Dec 29, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like rust-lang/rust#123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- rust-lang/rust#142005
- rust-lang/rust#142103
- rust-lang/rust#142324
- rust-lang/rust#142383
---
try-job: aarch64-gnu
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
Rollup of 11 pull requests
Successful merges:
- rust-lang/rust#140418 (Reexport types from `c_size_t` in `std`)
- rust-lang/rust#141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- rust-lang/rust#141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- rust-lang/rust#142043 (Verbose suggestion to make param `const`)
- rust-lang/rust#142086 (duduplicate more AST visitor methods)
- rust-lang/rust#142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- rust-lang/rust#142105 (remove extraneous text)
- rust-lang/rust#142112 (fix typo)
- rust-lang/rust#142113 (Reduce confusion of some drop order tests)
- rust-lang/rust#142114 (Compute number of digits instead of relying on constant value for u128 display code)
- rust-lang/rust#142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
Rollup of 11 pull requests
Successful merges:
- rust-lang/rust#140418 (Reexport types from `c_size_t` in `std`)
- rust-lang/rust#141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- rust-lang/rust#141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- rust-lang/rust#142043 (Verbose suggestion to make param `const`)
- rust-lang/rust#142086 (duduplicate more AST visitor methods)
- rust-lang/rust#142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- rust-lang/rust#142105 (remove extraneous text)
- rust-lang/rust#142112 (fix typo)
- rust-lang/rust#142113 (Reduce confusion of some drop order tests)
- rust-lang/rust#142114 (Compute number of digits instead of relying on constant value for u128 display code)
- rust-lang/rust#142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-borsStatus: Waiting on bors to run and complete tests. Bors will change the label on completion.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants

@scottmcm@rustbot@rust-log-analyzer@oli-obk@bors@RalfJung@WaffleLapkin@cjgillot
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); Update `InterpCx::project_field` to take `FieldIdx` by scottmcm · Pull Request #142103 · rust-lang/rust · GitHub
Skip to content

Update InterpCx::project_field to take FieldIdx - #142103

Merged
bors merged 2 commits into
rust-lang:masterfrom
scottmcm:fieldidx-in-interp
Jun 7, 2025
Merged

Update InterpCx::project_field to take FieldIdx#142103
bors merged 2 commits into
rust-lang:masterfrom
scottmcm:fieldidx-in-interp

Conversation

@scottmcm

@scottmcmscottmcm commented Jun 6, 2025

Copy link
Copy Markdown
Member

As suggested by Ralf in #142005 (comment)

@rustbot

Copy link
Copy Markdown
Collaborator

r? @oli-obk

rustbot has assigned @oli-obk.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbotrustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 6, 2025
@rustbot

Copy link
Copy Markdown
Collaborator

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

Some changes occurred in compiler/rustc_codegen_ssa

cc @WaffleLapkin

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

The Miri subtree was changed

cc @rust-lang/miri

@rust-log-analyzer

This comment has been minimized.

As suggested by Ralf in 142005.
@scottmcm
scottmcmforce-pushed the fieldidx-in-interp branch from 74c269e to 8bce225CompareJune 6, 2025 02:16

@oli-obkoli-obk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR highlights several situations where we can do improvements, but let's land this on its own and investigate from_usize and as_usize calls later

return None;
}
found = Some((field_idx, field));
found = Some((FieldIdx::from_usize(field_idx), field));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it may be worth adding an iter and an iter_enumerated method to FieldsShape

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, most of the layout-related usizes in ABI are sketchy. I've tried pulling on the tendrils before, but usually ended up giving up because of just how far that goes and -- as I mentioned in the other PR -- that the ones related to arrays sometimes need more than FieldIdx, and figuring out which those are can be hard.

(Conveniently this one was obvious because a over-4-billion-length array clearly can't have exactly one non-ZST.)

@oli-obk

Copy link
Copy Markdown
Contributor

@bors r+ rollup

@bors

bors commented Jun 6, 2025

Copy link
Copy Markdown
Collaborator

📌 Commit 8bce225 has been approved by oli-obk

It is now in the queue for this repository.

@borsbors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 6, 2025
Comment threadcompiler/rustc_abi/src/layout/ty.rs Outdated
impl FieldIdx {
/// The second field.
///
/// For use alongside [`FieldIdx::ZERO`], particularly with scalar pairs.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this not defined near FieldIdx::ZERO?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because all rustc_newtype_index! types get a ZERO; it's not something special for FieldIdx.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can add a const ONE = 1; in the macro to get it generated.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That generates it as a non-associated constant, though -- like the START_BLOCK mentioned -- not an associated one. And because ZERO is associated, I wanted ONE to be associated as well.

let fields_iter = (0..field_count)
.map(|i| {
let field_op = ecx.project_field(&down, i).discard_err()?;
let field_op = ecx.project_field(&down, FieldIdx::from_usize(i)).discard_err()?;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could also use a typed field iterator


for i in 0..field_count {
let field = ecx.project_field(&place, i).unwrap();
let field = ecx.project_field(&place, FieldIdx::from_usize(i)).unwrap();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And more here

(probably not worth pointing them all out)

// Computing the layout does normalization, so we get a normalized type out of this
// even if the field type is non-normalized (possible e.g. via associated types).
let field_layout = base.layout().field(self, field);
let field_layout = base.layout().field(self, field.as_usize());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does field not take FieldIdx...?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Co-authored-by: Ralf Jung <post@ralfj.de>
@scottmcm

Copy link
Copy Markdown
MemberAuthor

@bors r=oli-obk

@bors

bors commented Jun 6, 2025

Copy link
Copy Markdown
Collaborator

📌 Commit f9cf096 has been approved by oli-obk

It is now in the queue for this repository.

@RalfJung

RalfJung commented Jun 6, 2025 via email

Copy link
Copy Markdown
Member

@scottmcm

Copy link
Copy Markdown
MemberAuthor

I think "project" overstates at least how I've been handling this. I had rust-lang/compiler-team#606 to add FieldIdx originally, then @WaffleLapkin's rust-lang/compiler-team#639 is explicitly about using it in more places.

There's never been a tracking issue for it, or a list of all the things that should happen, or anything. Just a bunch of "spots I saw in passing" PRs.

bors added a commit that referenced this pull request Jun 7, 2025
Rollup of 11 pull requests
Successful merges:
- #140418 (Reexport types from `c_size_t` in `std`)
- #141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- #141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- #142043 (Verbose suggestion to make param `const`)
- #142086 (duduplicate more AST visitor methods)
- #142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- #142105 (remove extraneous text)
- #142112 (fix typo)
- #142113 (Reduce confusion of some drop order tests)
- #142114 (Compute number of digits instead of relying on constant value for u128 display code)
- #142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
@bors
bors merged commit 3a6f1b0 into rust-lang:masterJun 7, 2025
@rustbotrustbot added this to the 1.89.0 milestone Jun 7, 2025
rust-timer added a commit that referenced this pull request Jun 7, 2025
Rollup merge of #142103 - scottmcm:fieldidx-in-interp, r=oli-obk
Update `InterpCx::project_field` to take `FieldIdx`
As suggested by Ralf in #142005 (comment)
github-actionsBot pushed a commit to rust-lang/miri that referenced this pull request Jun 7, 2025
Rollup of 11 pull requests
Successful merges:
- rust-lang/rust#140418 (Reexport types from `c_size_t` in `std`)
- rust-lang/rust#141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- rust-lang/rust#141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- rust-lang/rust#142043 (Verbose suggestion to make param `const`)
- rust-lang/rust#142086 (duduplicate more AST visitor methods)
- rust-lang/rust#142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- rust-lang/rust#142105 (remove extraneous text)
- rust-lang/rust#142112 (fix typo)
- rust-lang/rust#142113 (Reduce confusion of some drop order tests)
- rust-lang/rust#142114 (Compute number of digits instead of relying on constant value for u128 display code)
- rust-lang/rust#142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
@scottmcm
scottmcm deleted the fieldidx-in-interp branch June 7, 2025 22:58
@WaffleLapkin

Copy link
Copy Markdown
Member

@WaffleLapkin's rust-lang/compiler-team#639 is explicitly about using it in more places.

Oh. Did I mean to work on it and then forgot? 😓

bors added a commit that referenced this pull request Jun 19, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
bjorn3 pushed a commit to bjorn3/rust that referenced this pull request Jun 24, 2025
…-obk
Update `InterpCx::project_field` to take `FieldIdx`
As suggested by Ralf in rust-lang#142005 (comment)
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 4, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
bors added a commit that referenced this pull request Jul 5, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like #123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- #142005
- #142103
- #142324
- #142383
---
try-job: aarch64-gnu
github-actionsBot pushed a commit to rust-lang/rustc-dev-guide that referenced this pull request Jul 7, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like rust-lang/rust#123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- rust-lang/rust#142005
- rust-lang/rust#142103
- rust-lang/rust#142324
- rust-lang/rust#142383
---
try-job: aarch64-gnu
Kobzol pushed a commit to Kobzol/rustc_codegen_gcc that referenced this pull request Dec 21, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like rust-lang/rust#123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- rust-lang/rust#142005
- rust-lang/rust#142103
- rust-lang/rust#142324
- rust-lang/rust#142383
---
try-job: aarch64-gnu
Kobzol pushed a commit to Kobzol/rustc_codegen_cranelift that referenced this pull request Dec 29, 2025
Allow `enum` and `union` literals to also create SSA values
Today, `Some(x)` always goes through an `alloca`, even in trivial cases where the niching means the constructor doesn't even change the value.
For example, <https://rust.godbolt.org/z/6KG6PqoYz>
```rust
pub fn demo(r: &i32) -> Option<&i32> {
Some(r)
}
```
currently emits the IR
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
%_0 = alloca [8 x i8], align 8
store ptr %r, ptr %_0, align 8
%0 = load ptr, ptr %_0, align 8
ret ptr %0
}
```
but with this PR it becomes just
```llvm
define align 4 ptr `@demo(ptr` align 4 %r) unnamed_addr {
start:
ret ptr %r
}
```
(Of course the optimizer can clean that up, but it'd be nice if it didn't have to -- especially in debug where it doesn't run. This is like rust-lang/rust#123886, but that only handled non-simd `struct`s -- this PR generalizes it to all non-simd ADTs.)
Doing this means handing variants other than `FIRST_VARIANT`, handling the active field for unions, refactoring the discriminant code so the Place and Operand parts can share the calculation, etc.
Other PRs that led up to this one:
- rust-lang/rust#142005
- rust-lang/rust#142103
- rust-lang/rust#142324
- rust-lang/rust#142383
---
try-job: aarch64-gnu
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
Rollup of 11 pull requests
Successful merges:
- rust-lang/rust#140418 (Reexport types from `c_size_t` in `std`)
- rust-lang/rust#141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- rust-lang/rust#141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- rust-lang/rust#142043 (Verbose suggestion to make param `const`)
- rust-lang/rust#142086 (duduplicate more AST visitor methods)
- rust-lang/rust#142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- rust-lang/rust#142105 (remove extraneous text)
- rust-lang/rust#142112 (fix typo)
- rust-lang/rust#142113 (Reduce confusion of some drop order tests)
- rust-lang/rust#142114 (Compute number of digits instead of relying on constant value for u128 display code)
- rust-lang/rust#142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
Rollup of 11 pull requests
Successful merges:
- rust-lang/rust#140418 (Reexport types from `c_size_t` in `std`)
- rust-lang/rust#141471 (unsafe keyword docs: emphasize that an unsafe fn in a trait does not get to choose its safety contract)
- rust-lang/rust#141603 (Reduce `ast::ptr::P` to a typedef of `Box`)
- rust-lang/rust#142043 (Verbose suggestion to make param `const`)
- rust-lang/rust#142086 (duduplicate more AST visitor methods)
- rust-lang/rust#142103 (Update `InterpCx::project_field` to take `FieldIdx`)
- rust-lang/rust#142105 (remove extraneous text)
- rust-lang/rust#142112 (fix typo)
- rust-lang/rust#142113 (Reduce confusion of some drop order tests)
- rust-lang/rust#142114 (Compute number of digits instead of relying on constant value for u128 display code)
- rust-lang/rust#142118 (rustc_lexer: typo fix + small cleanups)
r? `@ghost`
`@rustbot` modify labels: rollup
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-borsStatus: Waiting on bors to run and complete tests. Bors will change the label on completion.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants

@scottmcm@rustbot@rust-log-analyzer@oli-obk@bors@RalfJung@WaffleLapkin@cjgillot