Replace OffsetOf by an actual sum of calls to intrinsic. - #148151

Merged
bors merged 5 commits into
rust-lang:mainfrom
cjgillot:no-offset-of
Nov 18, 2025
Merged

Replace OffsetOf by an actual sum of calls to intrinsic.#148151
bors merged 5 commits into
rust-lang:mainfrom
cjgillot:no-offset-of

Conversation

@cjgillot

@cjgillotcjgillot commented Oct 26, 2025

Copy link
Copy Markdown
Contributor

This PR changes the way we compute the value of the offset_of! macro in MIR. The current implementation uses a dedicated MIR rvalue.

This PR proposes to replace it by an inline constant which sums calls to a new intrinsic offset_of(variant index, field index). The desugaring is done at THIR building time, easier that doing it on MIR.

The new intrinsic is only meant to be used by const-eval. LLVM codegen will refuse to generate code for it.

We replace:

a = offset_of!(T,Variant1.Field1.Variant2.Field2);

By:

a = const{constant#n};{constant#n}: usize = {
_1 = offset_of::<T>(index of Variant1, index of Field1);
_2 = offset_of::<U>(index of Variant2, index of Field2);// Where T::Variant1::Field1 has type U
_0 = _1 + _2
}

The second commit modifies intrinsic const checking to take allow_internal_unstable into account. The new intrinsic should only be called from stable offset_of! macro. The intrinsic itself is unstable, const-unstable, but rustc_intrinsic_const_stable_indirect.

Fixes#123959
Fixes#125680
Fixes#129425
Fixes#136175

r? @ghost

@rustbotrustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Oct 26, 2025
@rust-log-analyzer

This comment has been minimized.

Comment threadlibrary/core/src/intrinsics/mod.rs Outdated
@cjgillot

Copy link
Copy Markdown
ContributorAuthor

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rust-bors

This comment has been minimized.

rust-borsBot added a commit that referenced this pull request Oct 27, 2025
Replace OffsetOf by an actual sum of calls to intrinsic.
@rustbotrustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Oct 27, 2025
@rust-bors

rust-borsBot commented Oct 27, 2025

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: 7721497 (772149783c4c312fd88b7dfaa68a045b14db3280, parent: f37aa9955f03bb1bc6fe08670cb1ecae534b5815)

@rust-timer

This comment has been minimized.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (7721497): comparison URL.

Overall result: ❌✅ regressions and improvements - no action needed

Benchmarking this pull request means it may be perf-sensitive – we'll automatically label it not fit for rolling up. You can override this, but we strongly advise not to, due to possible changes in compiler perf.

@bors rollup=never
@rustbot label: -S-waiting-on-perf -perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

meanrangecount
Regressions ❌
(primary)
--0
Regressions ❌
(secondary)
0.1%[0.0%, 0.1%]3
Improvements ✅
(primary)
--0
Improvements ✅
(secondary)
-0.1%[-0.1%, -0.1%]3
All ❌✅ (primary)--0

Max RSS (memory usage)

Results (secondary -1.9%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

meanrangecount
Regressions ❌
(primary)
--0
Regressions ❌
(secondary)
2.6%[2.1%, 3.2%]2
Improvements ✅
(primary)
--0
Improvements ✅
(secondary)
-3.7%[-4.9%, -1.5%]5
All ❌✅ (primary)--0

Cycles

Results (secondary -0.8%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

meanrangecount
Regressions ❌
(primary)
--0
Regressions ❌
(secondary)
2.7%[1.6%, 5.0%]3
Improvements ✅
(primary)
--0
Improvements ✅
(secondary)
-6.1%[-7.9%, -4.2%]2
All ❌✅ (primary)--0

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 473.876s -> 473.729s (-0.03%)
Artifact size: 390.50 MiB -> 390.46 MiB (-0.01%)

@rustbotrustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Oct 27, 2025
@bors

bors commented Oct 31, 2025

Copy link
Copy Markdown
Collaborator

☔ The latest upstream changes (presumably #148324) made this pull request unmergeable. Please resolve the merge conflicts.

@cjgillot
cjgillot marked this pull request as ready for review November 1, 2025 23:47
@rustbotrustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 1, 2025
@rustbot

Copy link
Copy Markdown
Collaborator

Some changes occurred in match checking

cc @Nadrieril

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

⚠️#[rustc_intrinsic_const_stable_indirect] controls whether intrinsics can be exposed to stable const
code; adding it needs t-lang approval.

cc @rust-lang/wg-const-eval

Some changes occurred to constck

cc @fee1-dead

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

This PR changes rustc_public

cc @oli-obk, @celinval, @ouz-a

Some changes occurred in rustc_ty_utils::consts.rs

cc @BoxyUwU

Some changes occurred to the intrinsics. Make sure the CTFE / Miri interpreter
gets adapted for the changes, if necessary.

cc @rust-lang/miri, @RalfJung, @oli-obk, @lcnr

This PR changes MIR

cc @oli-obk, @RalfJung, @JakobDegen, @vakaras

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

Some changes occurred in compiler/rustc_codegen_ssa

cc @WaffleLapkin

This PR changes a file inside tests/crashes. If a crash was fixed, please move into the corresponding ui subdir and add 'Fixes #' to the PR description to autoclose the issue upon merge.

@rustbotrustbot removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Nov 1, 2025
@cjgillotcjgillot added the I-lang-nominated Nominated for discussion during a lang team meeting. label Nov 2, 2025
@oli-obkoli-obk self-assigned this Nov 2, 2025
@BoxyUwU

BoxyUwU commented Nov 2, 2025

Copy link
Copy Markdown
Member

What's the justification/benefit for doing this, and what user facing impact does it have (i.e. why does it need a lang nomination)?

@cjgillot

Copy link
Copy Markdown
ContributorAuthor

My justification is simplifying MIR. This feature was implemented as a specific MIR statement, but does not need to, an intrinsic is sufficient.

There should be no user-facing change because of the offset_of manipulation. Maybe some diagnostics, but not more.

However, there are 2 user-facing changes in this PR that t-lang may want to know:

  • const-stability of intrinsics now takes allow_internal_unstable into account;
  • we get an additional intrinsic with rustc_intrinsic_const_stable_indirect.

@WaffleLapkin

This comment was marked as resolved.

@cjgillot

This comment was marked as resolved.

@traviscrosstraviscross added the T-lang Relevant to the language team label Nov 5, 2025
@cjgillot
cjgillot deleted the no-offset-of branch November 18, 2025 21:30
tautschnig added a commit to tautschnig/kani that referenced this pull request Nov 19, 2025
Relevant upstream PR:
- rust-lang/rust#148151 (Replace OffsetOf by an
actual sum of calls to intrinsic.)
Resolves: model-checking#4481
@panstromek

Copy link
Copy Markdown
Contributor

perf triage:

As indicated by the comment above, clap_derive is noise, include-blob is also noise (at least the opt variants, other ones didn't return to previous state, but they are tiny in absolute numbers).

@rustbot label: +perf-regression-triaged

@rustbotrustbot added the perf-regression-triaged The performance regression has been triaged. label Nov 19, 2025
github-merge-queueBot pushed a commit to model-checking/kani that referenced this pull request Nov 19, 2025
Relevant upstream PR:
- rust-lang/rust#148151 (Replace OffsetOf by an
actual sum of calls to intrinsic.)
Resolves: #4481
By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache 2.0 and MIT licenses.
github-actionsBot pushed a commit to model-checking/verify-rust-std that referenced this pull request Nov 30, 2025
Replace OffsetOf by an actual sum of calls to intrinsic.
This PR changes the way we compute the value of the `offset_of!` macro in MIR. The current implementation uses a dedicated MIR rvalue.
This PR proposes to replace it by an inline constant which sums calls to a new intrinsic `offset_of(variant index, field index)`. The desugaring is done at THIR building time, easier that doing it on MIR.
The new intrinsic is only meant to be used by const-eval. LLVM codegen will refuse to generate code for it.
We replace:
```rust
a = offset_of!(T, Variant1.Field1.Variant2.Field2);
```
By:
```rust
a = const {constant#n};
{constant#n}: usize = {
_1 = offset_of::<T>(index of Variant1, index of Field1);
_2 = offset_of::<U>(index of Variant2, index of Field2); // Where T::Variant1::Field1 has type U
_0 = _1 + _2
}
```
The second commit modifies intrinsic const checking to take `allow_internal_unstable` into account. The new intrinsic should only be called from stable `offset_of!` macro. The intrinsic itself is unstable, const-unstable, but `rustc_intrinsic_const_stable_indirect`.
Fixesrust-lang#123959Fixesrust-lang#125680Fixesrust-lang#129425Fixesrust-lang#136175
r? `@ghost`
makai410 pushed a commit to makai410/rust that referenced this pull request Dec 10, 2025
Replace OffsetOf by an actual sum of calls to intrinsic.
This PR changes the way we compute the value of the `offset_of!` macro in MIR. The current implementation uses a dedicated MIR rvalue.
This PR proposes to replace it by an inline constant which sums calls to a new intrinsic `offset_of(variant index, field index)`. The desugaring is done at THIR building time, easier that doing it on MIR.
The new intrinsic is only meant to be used by const-eval. LLVM codegen will refuse to generate code for it.
We replace:
```rust
a = offset_of!(T, Variant1.Field1.Variant2.Field2);
```
By:
```rust
a = const {constant#n};
{constant#n}: usize = {
_1 = offset_of::<T>(index of Variant1, index of Field1);
_2 = offset_of::<U>(index of Variant2, index of Field2); // Where T::Variant1::Field1 has type U
_0 = _1 + _2
}
```
The second commit modifies intrinsic const checking to take `allow_internal_unstable` into account. The new intrinsic should only be called from stable `offset_of!` macro. The intrinsic itself is unstable, const-unstable, but `rustc_intrinsic_const_stable_indirect`.
Fixesrust-lang#123959Fixesrust-lang#125680Fixesrust-lang#129425Fixesrust-lang#136175
r? `@ghost`
bors added a commit that referenced this pull request Dec 22, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on #148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After #148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/miri that referenced this pull request Dec 23, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
bjorn3 pushed a commit to rust-lang/rustc_codegen_cranelift that referenced this pull request Dec 23, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
Kobzol pushed a commit to Kobzol/rustc_codegen_cranelift that referenced this pull request Dec 23, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/rust-analyzer that referenced this pull request Dec 25, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
flip1995 pushed a commit to flip1995/rust-clippy that referenced this pull request Dec 25, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/compiler-builtins that referenced this pull request Dec 28, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/rustc-dev-guide that referenced this pull request Dec 29, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 6, 2026
…ery, r=petrochenkov
Fix ICE in `offset_of!` error recovery
Fixesrust-lang#153236.
`offset_of!` was changed in rust-lang#148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 6, 2026
…ery, r=petrochenkov
Fix ICE in `offset_of!` error recovery
Fixesrust-lang#153236.
`offset_of!` was changed in rust-lang#148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
rust-timer added a commit that referenced this pull request Mar 6, 2026
Rollup merge of #153495 - TaKO8Ki:fix-153236-offset-of-recovery, r=petrochenkov
Fix ICE in `offset_of!` error recovery
Fixes#153236.
`offset_of!` was changed in #148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
github-actionsBot pushed a commit to rust-lang/rust-analyzer that referenced this pull request Mar 9, 2026
…trochenkov
Fix ICE in `offset_of!` error recovery
Fixesrust-lang/rust#153236.
`offset_of!` was changed in rust-lang/rust#148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
makai410 pushed a commit to makai410/rustc_public that referenced this pull request Mar 19, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
makai410 pushed a commit to makai410/rustc_public that referenced this pull request Mar 19, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
makai410 pushed a commit to makai410/rustc_public that referenced this pull request Mar 27, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

disposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.finished-final-comment-periodThe final comment period is finished for this PR / Issue.I-lang-radarItems that are on lang's radar and will need eventual work or consideration.merged-by-borsThis PR was explicitly merged by bors.perf-regressionPerformance regression.perf-regression-triagedThe performance regression has been triaged.S-waiting-on-borsStatus: Waiting on bors to run and complete tests. Bors will change the label on completion.T-clippyRelevant to the Clippy team.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamT-libsRelevant to the library team, which will review and decide on the PR/issue.to-announceAnnounce this issue on triage meeting

Projects

None yet

15 participants

@cjgillot@rust-log-analyzer@rust-timer@bors@rustbot@BoxyUwU@WaffleLapkin@scottmcm@rust-rfcbot@traviscross@nikomatsakis@oli-obk@lqd@panstromek@RalfJung
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n 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;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Replace OffsetOf by an actual sum of calls to intrinsic. - #148151

Merged
bors merged 5 commits into
rust-lang:mainfrom
cjgillot:no-offset-of
Nov 18, 2025
Merged

Replace OffsetOf by an actual sum of calls to intrinsic.#148151
bors merged 5 commits into
rust-lang:mainfrom
cjgillot:no-offset-of

Conversation

@cjgillot

@cjgillotcjgillot commented Oct 26, 2025

Copy link
Copy Markdown
Contributor

This PR changes the way we compute the value of the offset_of! macro in MIR. The current implementation uses a dedicated MIR rvalue.

This PR proposes to replace it by an inline constant which sums calls to a new intrinsic offset_of(variant index, field index). The desugaring is done at THIR building time, easier that doing it on MIR.

The new intrinsic is only meant to be used by const-eval. LLVM codegen will refuse to generate code for it.

We replace:

a = offset_of!(T,Variant1.Field1.Variant2.Field2);

By:

a = const{constant#n};{constant#n}: usize = {
_1 = offset_of::<T>(index of Variant1, index of Field1);
_2 = offset_of::<U>(index of Variant2, index of Field2);// Where T::Variant1::Field1 has type U
_0 = _1 + _2
}

The second commit modifies intrinsic const checking to take allow_internal_unstable into account. The new intrinsic should only be called from stable offset_of! macro. The intrinsic itself is unstable, const-unstable, but rustc_intrinsic_const_stable_indirect.

Fixes#123959
Fixes#125680
Fixes#129425
Fixes#136175

r? @ghost

@rustbotrustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Oct 26, 2025
@rust-log-analyzer

This comment has been minimized.

Comment threadlibrary/core/src/intrinsics/mod.rs Outdated
@cjgillot

Copy link
Copy Markdown
ContributorAuthor

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rust-bors

This comment has been minimized.

rust-borsBot added a commit that referenced this pull request Oct 27, 2025
Replace OffsetOf by an actual sum of calls to intrinsic.
@rustbotrustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Oct 27, 2025
@rust-bors

rust-borsBot commented Oct 27, 2025

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: 7721497 (772149783c4c312fd88b7dfaa68a045b14db3280, parent: f37aa9955f03bb1bc6fe08670cb1ecae534b5815)

@rust-timer

This comment has been minimized.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (7721497): comparison URL.

Overall result: ❌✅ regressions and improvements - no action needed

Benchmarking this pull request means it may be perf-sensitive – we'll automatically label it not fit for rolling up. You can override this, but we strongly advise not to, due to possible changes in compiler perf.

@bors rollup=never
@rustbot label: -S-waiting-on-perf -perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

meanrangecount
Regressions ❌
(primary)
--0
Regressions ❌
(secondary)
0.1%[0.0%, 0.1%]3
Improvements ✅
(primary)
--0
Improvements ✅
(secondary)
-0.1%[-0.1%, -0.1%]3
All ❌✅ (primary)--0

Max RSS (memory usage)

Results (secondary -1.9%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

meanrangecount
Regressions ❌
(primary)
--0
Regressions ❌
(secondary)
2.6%[2.1%, 3.2%]2
Improvements ✅
(primary)
--0
Improvements ✅
(secondary)
-3.7%[-4.9%, -1.5%]5
All ❌✅ (primary)--0

Cycles

Results (secondary -0.8%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

meanrangecount
Regressions ❌
(primary)
--0
Regressions ❌
(secondary)
2.7%[1.6%, 5.0%]3
Improvements ✅
(primary)
--0
Improvements ✅
(secondary)
-6.1%[-7.9%, -4.2%]2
All ❌✅ (primary)--0

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 473.876s -> 473.729s (-0.03%)
Artifact size: 390.50 MiB -> 390.46 MiB (-0.01%)

@rustbotrustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Oct 27, 2025
@bors

bors commented Oct 31, 2025

Copy link
Copy Markdown
Collaborator

☔ The latest upstream changes (presumably #148324) made this pull request unmergeable. Please resolve the merge conflicts.

@cjgillot
cjgillot marked this pull request as ready for review November 1, 2025 23:47
@rustbotrustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 1, 2025
@rustbot

Copy link
Copy Markdown
Collaborator

Some changes occurred in match checking

cc @Nadrieril

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

⚠️#[rustc_intrinsic_const_stable_indirect] controls whether intrinsics can be exposed to stable const
code; adding it needs t-lang approval.

cc @rust-lang/wg-const-eval

Some changes occurred to constck

cc @fee1-dead

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

This PR changes rustc_public

cc @oli-obk, @celinval, @ouz-a

Some changes occurred in rustc_ty_utils::consts.rs

cc @BoxyUwU

Some changes occurred to the intrinsics. Make sure the CTFE / Miri interpreter
gets adapted for the changes, if necessary.

cc @rust-lang/miri, @RalfJung, @oli-obk, @lcnr

This PR changes MIR

cc @oli-obk, @RalfJung, @JakobDegen, @vakaras

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

Some changes occurred in compiler/rustc_codegen_ssa

cc @WaffleLapkin

This PR changes a file inside tests/crashes. If a crash was fixed, please move into the corresponding ui subdir and add 'Fixes #' to the PR description to autoclose the issue upon merge.

@rustbotrustbot removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Nov 1, 2025
@cjgillotcjgillot added the I-lang-nominated Nominated for discussion during a lang team meeting. label Nov 2, 2025
@oli-obkoli-obk self-assigned this Nov 2, 2025
@BoxyUwU

BoxyUwU commented Nov 2, 2025

Copy link
Copy Markdown
Member

What's the justification/benefit for doing this, and what user facing impact does it have (i.e. why does it need a lang nomination)?

@cjgillot

Copy link
Copy Markdown
ContributorAuthor

My justification is simplifying MIR. This feature was implemented as a specific MIR statement, but does not need to, an intrinsic is sufficient.

There should be no user-facing change because of the offset_of manipulation. Maybe some diagnostics, but not more.

However, there are 2 user-facing changes in this PR that t-lang may want to know:

  • const-stability of intrinsics now takes allow_internal_unstable into account;
  • we get an additional intrinsic with rustc_intrinsic_const_stable_indirect.

@WaffleLapkin

This comment was marked as resolved.

@cjgillot

This comment was marked as resolved.

@traviscrosstraviscross added the T-lang Relevant to the language team label Nov 5, 2025
@cjgillot
cjgillot deleted the no-offset-of branch November 18, 2025 21:30
tautschnig added a commit to tautschnig/kani that referenced this pull request Nov 19, 2025
Relevant upstream PR:
- rust-lang/rust#148151 (Replace OffsetOf by an
actual sum of calls to intrinsic.)
Resolves: model-checking#4481
@panstromek

Copy link
Copy Markdown
Contributor

perf triage:

As indicated by the comment above, clap_derive is noise, include-blob is also noise (at least the opt variants, other ones didn't return to previous state, but they are tiny in absolute numbers).

@rustbot label: +perf-regression-triaged

@rustbotrustbot added the perf-regression-triaged The performance regression has been triaged. label Nov 19, 2025
github-merge-queueBot pushed a commit to model-checking/kani that referenced this pull request Nov 19, 2025
Relevant upstream PR:
- rust-lang/rust#148151 (Replace OffsetOf by an
actual sum of calls to intrinsic.)
Resolves: #4481
By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache 2.0 and MIT licenses.
github-actionsBot pushed a commit to model-checking/verify-rust-std that referenced this pull request Nov 30, 2025
Replace OffsetOf by an actual sum of calls to intrinsic.
This PR changes the way we compute the value of the `offset_of!` macro in MIR. The current implementation uses a dedicated MIR rvalue.
This PR proposes to replace it by an inline constant which sums calls to a new intrinsic `offset_of(variant index, field index)`. The desugaring is done at THIR building time, easier that doing it on MIR.
The new intrinsic is only meant to be used by const-eval. LLVM codegen will refuse to generate code for it.
We replace:
```rust
a = offset_of!(T, Variant1.Field1.Variant2.Field2);
```
By:
```rust
a = const {constant#n};
{constant#n}: usize = {
_1 = offset_of::<T>(index of Variant1, index of Field1);
_2 = offset_of::<U>(index of Variant2, index of Field2); // Where T::Variant1::Field1 has type U
_0 = _1 + _2
}
```
The second commit modifies intrinsic const checking to take `allow_internal_unstable` into account. The new intrinsic should only be called from stable `offset_of!` macro. The intrinsic itself is unstable, const-unstable, but `rustc_intrinsic_const_stable_indirect`.
Fixesrust-lang#123959Fixesrust-lang#125680Fixesrust-lang#129425Fixesrust-lang#136175
r? `@ghost`
makai410 pushed a commit to makai410/rust that referenced this pull request Dec 10, 2025
Replace OffsetOf by an actual sum of calls to intrinsic.
This PR changes the way we compute the value of the `offset_of!` macro in MIR. The current implementation uses a dedicated MIR rvalue.
This PR proposes to replace it by an inline constant which sums calls to a new intrinsic `offset_of(variant index, field index)`. The desugaring is done at THIR building time, easier that doing it on MIR.
The new intrinsic is only meant to be used by const-eval. LLVM codegen will refuse to generate code for it.
We replace:
```rust
a = offset_of!(T, Variant1.Field1.Variant2.Field2);
```
By:
```rust
a = const {constant#n};
{constant#n}: usize = {
_1 = offset_of::<T>(index of Variant1, index of Field1);
_2 = offset_of::<U>(index of Variant2, index of Field2); // Where T::Variant1::Field1 has type U
_0 = _1 + _2
}
```
The second commit modifies intrinsic const checking to take `allow_internal_unstable` into account. The new intrinsic should only be called from stable `offset_of!` macro. The intrinsic itself is unstable, const-unstable, but `rustc_intrinsic_const_stable_indirect`.
Fixesrust-lang#123959Fixesrust-lang#125680Fixesrust-lang#129425Fixesrust-lang#136175
r? `@ghost`
bors added a commit that referenced this pull request Dec 22, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on #148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After #148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/miri that referenced this pull request Dec 23, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
bjorn3 pushed a commit to rust-lang/rustc_codegen_cranelift that referenced this pull request Dec 23, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
Kobzol pushed a commit to Kobzol/rustc_codegen_cranelift that referenced this pull request Dec 23, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/rust-analyzer that referenced this pull request Dec 25, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
flip1995 pushed a commit to flip1995/rust-clippy that referenced this pull request Dec 25, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/compiler-builtins that referenced this pull request Dec 28, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/rustc-dev-guide that referenced this pull request Dec 29, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 6, 2026
…ery, r=petrochenkov
Fix ICE in `offset_of!` error recovery
Fixesrust-lang#153236.
`offset_of!` was changed in rust-lang#148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 6, 2026
…ery, r=petrochenkov
Fix ICE in `offset_of!` error recovery
Fixesrust-lang#153236.
`offset_of!` was changed in rust-lang#148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
rust-timer added a commit that referenced this pull request Mar 6, 2026
Rollup merge of #153495 - TaKO8Ki:fix-153236-offset-of-recovery, r=petrochenkov
Fix ICE in `offset_of!` error recovery
Fixes#153236.
`offset_of!` was changed in #148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
github-actionsBot pushed a commit to rust-lang/rust-analyzer that referenced this pull request Mar 9, 2026
…trochenkov
Fix ICE in `offset_of!` error recovery
Fixesrust-lang/rust#153236.
`offset_of!` was changed in rust-lang/rust#148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
makai410 pushed a commit to makai410/rustc_public that referenced this pull request Mar 19, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
makai410 pushed a commit to makai410/rustc_public that referenced this pull request Mar 19, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
makai410 pushed a commit to makai410/rustc_public that referenced this pull request Mar 27, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

disposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.finished-final-comment-periodThe final comment period is finished for this PR / Issue.I-lang-radarItems that are on lang's radar and will need eventual work or consideration.merged-by-borsThis PR was explicitly merged by bors.perf-regressionPerformance regression.perf-regression-triagedThe performance regression has been triaged.S-waiting-on-borsStatus: Waiting on bors to run and complete tests. Bors will change the label on completion.T-clippyRelevant to the Clippy team.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamT-libsRelevant to the library team, which will review and decide on the PR/issue.to-announceAnnounce this issue on triage meeting

Projects

None yet

15 participants

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

Replace OffsetOf by an actual sum of calls to intrinsic. - #148151

Merged
bors merged 5 commits into
rust-lang:mainfrom
cjgillot:no-offset-of
Nov 18, 2025
Merged

Replace OffsetOf by an actual sum of calls to intrinsic.#148151
bors merged 5 commits into
rust-lang:mainfrom
cjgillot:no-offset-of

Conversation

@cjgillot

@cjgillotcjgillot commented Oct 26, 2025

Copy link
Copy Markdown
Contributor

This PR changes the way we compute the value of the offset_of! macro in MIR. The current implementation uses a dedicated MIR rvalue.

This PR proposes to replace it by an inline constant which sums calls to a new intrinsic offset_of(variant index, field index). The desugaring is done at THIR building time, easier that doing it on MIR.

The new intrinsic is only meant to be used by const-eval. LLVM codegen will refuse to generate code for it.

We replace:

a = offset_of!(T,Variant1.Field1.Variant2.Field2);

By:

a = const{constant#n};{constant#n}: usize = {
_1 = offset_of::<T>(index of Variant1, index of Field1);
_2 = offset_of::<U>(index of Variant2, index of Field2);// Where T::Variant1::Field1 has type U
_0 = _1 + _2
}

The second commit modifies intrinsic const checking to take allow_internal_unstable into account. The new intrinsic should only be called from stable offset_of! macro. The intrinsic itself is unstable, const-unstable, but rustc_intrinsic_const_stable_indirect.

Fixes#123959
Fixes#125680
Fixes#129425
Fixes#136175

r? @ghost

@rustbotrustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Oct 26, 2025
@rust-log-analyzer

This comment has been minimized.

Comment threadlibrary/core/src/intrinsics/mod.rs Outdated
@cjgillot

Copy link
Copy Markdown
ContributorAuthor

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rust-bors

This comment has been minimized.

rust-borsBot added a commit that referenced this pull request Oct 27, 2025
Replace OffsetOf by an actual sum of calls to intrinsic.
@rustbotrustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Oct 27, 2025
@rust-bors

rust-borsBot commented Oct 27, 2025

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: 7721497 (772149783c4c312fd88b7dfaa68a045b14db3280, parent: f37aa9955f03bb1bc6fe08670cb1ecae534b5815)

@rust-timer

This comment has been minimized.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (7721497): comparison URL.

Overall result: ❌✅ regressions and improvements - no action needed

Benchmarking this pull request means it may be perf-sensitive – we'll automatically label it not fit for rolling up. You can override this, but we strongly advise not to, due to possible changes in compiler perf.

@bors rollup=never
@rustbot label: -S-waiting-on-perf -perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

meanrangecount
Regressions ❌
(primary)
--0
Regressions ❌
(secondary)
0.1%[0.0%, 0.1%]3
Improvements ✅
(primary)
--0
Improvements ✅
(secondary)
-0.1%[-0.1%, -0.1%]3
All ❌✅ (primary)--0

Max RSS (memory usage)

Results (secondary -1.9%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

meanrangecount
Regressions ❌
(primary)
--0
Regressions ❌
(secondary)
2.6%[2.1%, 3.2%]2
Improvements ✅
(primary)
--0
Improvements ✅
(secondary)
-3.7%[-4.9%, -1.5%]5
All ❌✅ (primary)--0

Cycles

Results (secondary -0.8%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

meanrangecount
Regressions ❌
(primary)
--0
Regressions ❌
(secondary)
2.7%[1.6%, 5.0%]3
Improvements ✅
(primary)
--0
Improvements ✅
(secondary)
-6.1%[-7.9%, -4.2%]2
All ❌✅ (primary)--0

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 473.876s -> 473.729s (-0.03%)
Artifact size: 390.50 MiB -> 390.46 MiB (-0.01%)

@rustbotrustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Oct 27, 2025
@bors

bors commented Oct 31, 2025

Copy link
Copy Markdown
Collaborator

☔ The latest upstream changes (presumably #148324) made this pull request unmergeable. Please resolve the merge conflicts.

@cjgillot
cjgillot marked this pull request as ready for review November 1, 2025 23:47
@rustbotrustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 1, 2025
@rustbot

Copy link
Copy Markdown
Collaborator

Some changes occurred in match checking

cc @Nadrieril

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

⚠️#[rustc_intrinsic_const_stable_indirect] controls whether intrinsics can be exposed to stable const
code; adding it needs t-lang approval.

cc @rust-lang/wg-const-eval

Some changes occurred to constck

cc @fee1-dead

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

This PR changes rustc_public

cc @oli-obk, @celinval, @ouz-a

Some changes occurred in rustc_ty_utils::consts.rs

cc @BoxyUwU

Some changes occurred to the intrinsics. Make sure the CTFE / Miri interpreter
gets adapted for the changes, if necessary.

cc @rust-lang/miri, @RalfJung, @oli-obk, @lcnr

This PR changes MIR

cc @oli-obk, @RalfJung, @JakobDegen, @vakaras

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

Some changes occurred in compiler/rustc_codegen_ssa

cc @WaffleLapkin

This PR changes a file inside tests/crashes. If a crash was fixed, please move into the corresponding ui subdir and add 'Fixes #' to the PR description to autoclose the issue upon merge.

@rustbotrustbot removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Nov 1, 2025
@cjgillotcjgillot added the I-lang-nominated Nominated for discussion during a lang team meeting. label Nov 2, 2025
@oli-obkoli-obk self-assigned this Nov 2, 2025
@BoxyUwU

BoxyUwU commented Nov 2, 2025

Copy link
Copy Markdown
Member

What's the justification/benefit for doing this, and what user facing impact does it have (i.e. why does it need a lang nomination)?

@cjgillot

Copy link
Copy Markdown
ContributorAuthor

My justification is simplifying MIR. This feature was implemented as a specific MIR statement, but does not need to, an intrinsic is sufficient.

There should be no user-facing change because of the offset_of manipulation. Maybe some diagnostics, but not more.

However, there are 2 user-facing changes in this PR that t-lang may want to know:

  • const-stability of intrinsics now takes allow_internal_unstable into account;
  • we get an additional intrinsic with rustc_intrinsic_const_stable_indirect.

@WaffleLapkin

This comment was marked as resolved.

@cjgillot

This comment was marked as resolved.

@traviscrosstraviscross added the T-lang Relevant to the language team label Nov 5, 2025
@cjgillot
cjgillot deleted the no-offset-of branch November 18, 2025 21:30
tautschnig added a commit to tautschnig/kani that referenced this pull request Nov 19, 2025
Relevant upstream PR:
- rust-lang/rust#148151 (Replace OffsetOf by an
actual sum of calls to intrinsic.)
Resolves: model-checking#4481
@panstromek

Copy link
Copy Markdown
Contributor

perf triage:

As indicated by the comment above, clap_derive is noise, include-blob is also noise (at least the opt variants, other ones didn't return to previous state, but they are tiny in absolute numbers).

@rustbot label: +perf-regression-triaged

@rustbotrustbot added the perf-regression-triaged The performance regression has been triaged. label Nov 19, 2025
github-merge-queueBot pushed a commit to model-checking/kani that referenced this pull request Nov 19, 2025
Relevant upstream PR:
- rust-lang/rust#148151 (Replace OffsetOf by an
actual sum of calls to intrinsic.)
Resolves: #4481
By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache 2.0 and MIT licenses.
github-actionsBot pushed a commit to model-checking/verify-rust-std that referenced this pull request Nov 30, 2025
Replace OffsetOf by an actual sum of calls to intrinsic.
This PR changes the way we compute the value of the `offset_of!` macro in MIR. The current implementation uses a dedicated MIR rvalue.
This PR proposes to replace it by an inline constant which sums calls to a new intrinsic `offset_of(variant index, field index)`. The desugaring is done at THIR building time, easier that doing it on MIR.
The new intrinsic is only meant to be used by const-eval. LLVM codegen will refuse to generate code for it.
We replace:
```rust
a = offset_of!(T, Variant1.Field1.Variant2.Field2);
```
By:
```rust
a = const {constant#n};
{constant#n}: usize = {
_1 = offset_of::<T>(index of Variant1, index of Field1);
_2 = offset_of::<U>(index of Variant2, index of Field2); // Where T::Variant1::Field1 has type U
_0 = _1 + _2
}
```
The second commit modifies intrinsic const checking to take `allow_internal_unstable` into account. The new intrinsic should only be called from stable `offset_of!` macro. The intrinsic itself is unstable, const-unstable, but `rustc_intrinsic_const_stable_indirect`.
Fixesrust-lang#123959Fixesrust-lang#125680Fixesrust-lang#129425Fixesrust-lang#136175
r? `@ghost`
makai410 pushed a commit to makai410/rust that referenced this pull request Dec 10, 2025
Replace OffsetOf by an actual sum of calls to intrinsic.
This PR changes the way we compute the value of the `offset_of!` macro in MIR. The current implementation uses a dedicated MIR rvalue.
This PR proposes to replace it by an inline constant which sums calls to a new intrinsic `offset_of(variant index, field index)`. The desugaring is done at THIR building time, easier that doing it on MIR.
The new intrinsic is only meant to be used by const-eval. LLVM codegen will refuse to generate code for it.
We replace:
```rust
a = offset_of!(T, Variant1.Field1.Variant2.Field2);
```
By:
```rust
a = const {constant#n};
{constant#n}: usize = {
_1 = offset_of::<T>(index of Variant1, index of Field1);
_2 = offset_of::<U>(index of Variant2, index of Field2); // Where T::Variant1::Field1 has type U
_0 = _1 + _2
}
```
The second commit modifies intrinsic const checking to take `allow_internal_unstable` into account. The new intrinsic should only be called from stable `offset_of!` macro. The intrinsic itself is unstable, const-unstable, but `rustc_intrinsic_const_stable_indirect`.
Fixesrust-lang#123959Fixesrust-lang#125680Fixesrust-lang#129425Fixesrust-lang#136175
r? `@ghost`
bors added a commit that referenced this pull request Dec 22, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on #148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After #148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/miri that referenced this pull request Dec 23, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
bjorn3 pushed a commit to rust-lang/rustc_codegen_cranelift that referenced this pull request Dec 23, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
Kobzol pushed a commit to Kobzol/rustc_codegen_cranelift that referenced this pull request Dec 23, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/rust-analyzer that referenced this pull request Dec 25, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
flip1995 pushed a commit to flip1995/rust-clippy that referenced this pull request Dec 25, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/compiler-builtins that referenced this pull request Dec 28, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/rustc-dev-guide that referenced this pull request Dec 29, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 6, 2026
…ery, r=petrochenkov
Fix ICE in `offset_of!` error recovery
Fixesrust-lang#153236.
`offset_of!` was changed in rust-lang#148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 6, 2026
…ery, r=petrochenkov
Fix ICE in `offset_of!` error recovery
Fixesrust-lang#153236.
`offset_of!` was changed in rust-lang#148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
rust-timer added a commit that referenced this pull request Mar 6, 2026
Rollup merge of #153495 - TaKO8Ki:fix-153236-offset-of-recovery, r=petrochenkov
Fix ICE in `offset_of!` error recovery
Fixes#153236.
`offset_of!` was changed in #148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
github-actionsBot pushed a commit to rust-lang/rust-analyzer that referenced this pull request Mar 9, 2026
…trochenkov
Fix ICE in `offset_of!` error recovery
Fixesrust-lang/rust#153236.
`offset_of!` was changed in rust-lang/rust#148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
makai410 pushed a commit to makai410/rustc_public that referenced this pull request Mar 19, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
makai410 pushed a commit to makai410/rustc_public that referenced this pull request Mar 19, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
makai410 pushed a commit to makai410/rustc_public that referenced this pull request Mar 27, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

disposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.finished-final-comment-periodThe final comment period is finished for this PR / Issue.I-lang-radarItems that are on lang's radar and will need eventual work or consideration.merged-by-borsThis PR was explicitly merged by bors.perf-regressionPerformance regression.perf-regression-triagedThe performance regression has been triaged.S-waiting-on-borsStatus: Waiting on bors to run and complete tests. Bors will change the label on completion.T-clippyRelevant to the Clippy team.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamT-libsRelevant to the library team, which will review and decide on the PR/issue.to-announceAnnounce this issue on triage meeting

Projects

None yet

15 participants

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

Replace OffsetOf by an actual sum of calls to intrinsic. - #148151

Merged
bors merged 5 commits into
rust-lang:mainfrom
cjgillot:no-offset-of
Nov 18, 2025
Merged

Replace OffsetOf by an actual sum of calls to intrinsic.#148151
bors merged 5 commits into
rust-lang:mainfrom
cjgillot:no-offset-of

Conversation

@cjgillot

@cjgillotcjgillot commented Oct 26, 2025

Copy link
Copy Markdown
Contributor

This PR changes the way we compute the value of the offset_of! macro in MIR. The current implementation uses a dedicated MIR rvalue.

This PR proposes to replace it by an inline constant which sums calls to a new intrinsic offset_of(variant index, field index). The desugaring is done at THIR building time, easier that doing it on MIR.

The new intrinsic is only meant to be used by const-eval. LLVM codegen will refuse to generate code for it.

We replace:

a = offset_of!(T,Variant1.Field1.Variant2.Field2);

By:

a = const{constant#n};{constant#n}: usize = {
_1 = offset_of::<T>(index of Variant1, index of Field1);
_2 = offset_of::<U>(index of Variant2, index of Field2);// Where T::Variant1::Field1 has type U
_0 = _1 + _2
}

The second commit modifies intrinsic const checking to take allow_internal_unstable into account. The new intrinsic should only be called from stable offset_of! macro. The intrinsic itself is unstable, const-unstable, but rustc_intrinsic_const_stable_indirect.

Fixes#123959
Fixes#125680
Fixes#129425
Fixes#136175

r? @ghost

@rustbotrustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Oct 26, 2025
@rust-log-analyzer

This comment has been minimized.

Comment threadlibrary/core/src/intrinsics/mod.rs Outdated
@cjgillot

Copy link
Copy Markdown
ContributorAuthor

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rust-bors

This comment has been minimized.

rust-borsBot added a commit that referenced this pull request Oct 27, 2025
Replace OffsetOf by an actual sum of calls to intrinsic.
@rustbotrustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Oct 27, 2025
@rust-bors

rust-borsBot commented Oct 27, 2025

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: 7721497 (772149783c4c312fd88b7dfaa68a045b14db3280, parent: f37aa9955f03bb1bc6fe08670cb1ecae534b5815)

@rust-timer

This comment has been minimized.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (7721497): comparison URL.

Overall result: ❌✅ regressions and improvements - no action needed

Benchmarking this pull request means it may be perf-sensitive – we'll automatically label it not fit for rolling up. You can override this, but we strongly advise not to, due to possible changes in compiler perf.

@bors rollup=never
@rustbot label: -S-waiting-on-perf -perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

meanrangecount
Regressions ❌
(primary)
--0
Regressions ❌
(secondary)
0.1%[0.0%, 0.1%]3
Improvements ✅
(primary)
--0
Improvements ✅
(secondary)
-0.1%[-0.1%, -0.1%]3
All ❌✅ (primary)--0

Max RSS (memory usage)

Results (secondary -1.9%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

meanrangecount
Regressions ❌
(primary)
--0
Regressions ❌
(secondary)
2.6%[2.1%, 3.2%]2
Improvements ✅
(primary)
--0
Improvements ✅
(secondary)
-3.7%[-4.9%, -1.5%]5
All ❌✅ (primary)--0

Cycles

Results (secondary -0.8%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

meanrangecount
Regressions ❌
(primary)
--0
Regressions ❌
(secondary)
2.7%[1.6%, 5.0%]3
Improvements ✅
(primary)
--0
Improvements ✅
(secondary)
-6.1%[-7.9%, -4.2%]2
All ❌✅ (primary)--0

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 473.876s -> 473.729s (-0.03%)
Artifact size: 390.50 MiB -> 390.46 MiB (-0.01%)

@rustbotrustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Oct 27, 2025
@bors

bors commented Oct 31, 2025

Copy link
Copy Markdown
Collaborator

☔ The latest upstream changes (presumably #148324) made this pull request unmergeable. Please resolve the merge conflicts.

@cjgillot
cjgillot marked this pull request as ready for review November 1, 2025 23:47
@rustbotrustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 1, 2025
@rustbot

Copy link
Copy Markdown
Collaborator

Some changes occurred in match checking

cc @Nadrieril

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

⚠️#[rustc_intrinsic_const_stable_indirect] controls whether intrinsics can be exposed to stable const
code; adding it needs t-lang approval.

cc @rust-lang/wg-const-eval

Some changes occurred to constck

cc @fee1-dead

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

This PR changes rustc_public

cc @oli-obk, @celinval, @ouz-a

Some changes occurred in rustc_ty_utils::consts.rs

cc @BoxyUwU

Some changes occurred to the intrinsics. Make sure the CTFE / Miri interpreter
gets adapted for the changes, if necessary.

cc @rust-lang/miri, @RalfJung, @oli-obk, @lcnr

This PR changes MIR

cc @oli-obk, @RalfJung, @JakobDegen, @vakaras

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

Some changes occurred in compiler/rustc_codegen_ssa

cc @WaffleLapkin

This PR changes a file inside tests/crashes. If a crash was fixed, please move into the corresponding ui subdir and add 'Fixes #' to the PR description to autoclose the issue upon merge.

@rustbotrustbot removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Nov 1, 2025
@cjgillotcjgillot added the I-lang-nominated Nominated for discussion during a lang team meeting. label Nov 2, 2025
@oli-obkoli-obk self-assigned this Nov 2, 2025
@BoxyUwU

BoxyUwU commented Nov 2, 2025

Copy link
Copy Markdown
Member

What's the justification/benefit for doing this, and what user facing impact does it have (i.e. why does it need a lang nomination)?

@cjgillot

Copy link
Copy Markdown
ContributorAuthor

My justification is simplifying MIR. This feature was implemented as a specific MIR statement, but does not need to, an intrinsic is sufficient.

There should be no user-facing change because of the offset_of manipulation. Maybe some diagnostics, but not more.

However, there are 2 user-facing changes in this PR that t-lang may want to know:

  • const-stability of intrinsics now takes allow_internal_unstable into account;
  • we get an additional intrinsic with rustc_intrinsic_const_stable_indirect.

@WaffleLapkin

This comment was marked as resolved.

@cjgillot

This comment was marked as resolved.

@traviscrosstraviscross added the T-lang Relevant to the language team label Nov 5, 2025
@cjgillot
cjgillot deleted the no-offset-of branch November 18, 2025 21:30
tautschnig added a commit to tautschnig/kani that referenced this pull request Nov 19, 2025
Relevant upstream PR:
- rust-lang/rust#148151 (Replace OffsetOf by an
actual sum of calls to intrinsic.)
Resolves: model-checking#4481
@panstromek

Copy link
Copy Markdown
Contributor

perf triage:

As indicated by the comment above, clap_derive is noise, include-blob is also noise (at least the opt variants, other ones didn't return to previous state, but they are tiny in absolute numbers).

@rustbot label: +perf-regression-triaged

@rustbotrustbot added the perf-regression-triaged The performance regression has been triaged. label Nov 19, 2025
github-merge-queueBot pushed a commit to model-checking/kani that referenced this pull request Nov 19, 2025
Relevant upstream PR:
- rust-lang/rust#148151 (Replace OffsetOf by an
actual sum of calls to intrinsic.)
Resolves: #4481
By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache 2.0 and MIT licenses.
github-actionsBot pushed a commit to model-checking/verify-rust-std that referenced this pull request Nov 30, 2025
Replace OffsetOf by an actual sum of calls to intrinsic.
This PR changes the way we compute the value of the `offset_of!` macro in MIR. The current implementation uses a dedicated MIR rvalue.
This PR proposes to replace it by an inline constant which sums calls to a new intrinsic `offset_of(variant index, field index)`. The desugaring is done at THIR building time, easier that doing it on MIR.
The new intrinsic is only meant to be used by const-eval. LLVM codegen will refuse to generate code for it.
We replace:
```rust
a = offset_of!(T, Variant1.Field1.Variant2.Field2);
```
By:
```rust
a = const {constant#n};
{constant#n}: usize = {
_1 = offset_of::<T>(index of Variant1, index of Field1);
_2 = offset_of::<U>(index of Variant2, index of Field2); // Where T::Variant1::Field1 has type U
_0 = _1 + _2
}
```
The second commit modifies intrinsic const checking to take `allow_internal_unstable` into account. The new intrinsic should only be called from stable `offset_of!` macro. The intrinsic itself is unstable, const-unstable, but `rustc_intrinsic_const_stable_indirect`.
Fixesrust-lang#123959Fixesrust-lang#125680Fixesrust-lang#129425Fixesrust-lang#136175
r? `@ghost`
makai410 pushed a commit to makai410/rust that referenced this pull request Dec 10, 2025
Replace OffsetOf by an actual sum of calls to intrinsic.
This PR changes the way we compute the value of the `offset_of!` macro in MIR. The current implementation uses a dedicated MIR rvalue.
This PR proposes to replace it by an inline constant which sums calls to a new intrinsic `offset_of(variant index, field index)`. The desugaring is done at THIR building time, easier that doing it on MIR.
The new intrinsic is only meant to be used by const-eval. LLVM codegen will refuse to generate code for it.
We replace:
```rust
a = offset_of!(T, Variant1.Field1.Variant2.Field2);
```
By:
```rust
a = const {constant#n};
{constant#n}: usize = {
_1 = offset_of::<T>(index of Variant1, index of Field1);
_2 = offset_of::<U>(index of Variant2, index of Field2); // Where T::Variant1::Field1 has type U
_0 = _1 + _2
}
```
The second commit modifies intrinsic const checking to take `allow_internal_unstable` into account. The new intrinsic should only be called from stable `offset_of!` macro. The intrinsic itself is unstable, const-unstable, but `rustc_intrinsic_const_stable_indirect`.
Fixesrust-lang#123959Fixesrust-lang#125680Fixesrust-lang#129425Fixesrust-lang#136175
r? `@ghost`
bors added a commit that referenced this pull request Dec 22, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on #148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After #148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/miri that referenced this pull request Dec 23, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
bjorn3 pushed a commit to rust-lang/rustc_codegen_cranelift that referenced this pull request Dec 23, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
Kobzol pushed a commit to Kobzol/rustc_codegen_cranelift that referenced this pull request Dec 23, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/rust-analyzer that referenced this pull request Dec 25, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
flip1995 pushed a commit to flip1995/rust-clippy that referenced this pull request Dec 25, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/compiler-builtins that referenced this pull request Dec 28, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/rustc-dev-guide that referenced this pull request Dec 29, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 6, 2026
…ery, r=petrochenkov
Fix ICE in `offset_of!` error recovery
Fixesrust-lang#153236.
`offset_of!` was changed in rust-lang#148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 6, 2026
…ery, r=petrochenkov
Fix ICE in `offset_of!` error recovery
Fixesrust-lang#153236.
`offset_of!` was changed in rust-lang#148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
rust-timer added a commit that referenced this pull request Mar 6, 2026
Rollup merge of #153495 - TaKO8Ki:fix-153236-offset-of-recovery, r=petrochenkov
Fix ICE in `offset_of!` error recovery
Fixes#153236.
`offset_of!` was changed in #148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
github-actionsBot pushed a commit to rust-lang/rust-analyzer that referenced this pull request Mar 9, 2026
…trochenkov
Fix ICE in `offset_of!` error recovery
Fixesrust-lang/rust#153236.
`offset_of!` was changed in rust-lang/rust#148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
makai410 pushed a commit to makai410/rustc_public that referenced this pull request Mar 19, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
makai410 pushed a commit to makai410/rustc_public that referenced this pull request Mar 19, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
makai410 pushed a commit to makai410/rustc_public that referenced this pull request Mar 27, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

disposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.finished-final-comment-periodThe final comment period is finished for this PR / Issue.I-lang-radarItems that are on lang's radar and will need eventual work or consideration.merged-by-borsThis PR was explicitly merged by bors.perf-regressionPerformance regression.perf-regression-triagedThe performance regression has been triaged.S-waiting-on-borsStatus: Waiting on bors to run and complete tests. Bors will change the label on completion.T-clippyRelevant to the Clippy team.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamT-libsRelevant to the library team, which will review and decide on the PR/issue.to-announceAnnounce this issue on triage meeting

Projects

None yet

15 participants

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

Replace OffsetOf by an actual sum of calls to intrinsic. - #148151

Merged
bors merged 5 commits into
rust-lang:mainfrom
cjgillot:no-offset-of
Nov 18, 2025
Merged

Replace OffsetOf by an actual sum of calls to intrinsic.#148151
bors merged 5 commits into
rust-lang:mainfrom
cjgillot:no-offset-of

Conversation

@cjgillot

@cjgillotcjgillot commented Oct 26, 2025

Copy link
Copy Markdown
Contributor

This PR changes the way we compute the value of the offset_of! macro in MIR. The current implementation uses a dedicated MIR rvalue.

This PR proposes to replace it by an inline constant which sums calls to a new intrinsic offset_of(variant index, field index). The desugaring is done at THIR building time, easier that doing it on MIR.

The new intrinsic is only meant to be used by const-eval. LLVM codegen will refuse to generate code for it.

We replace:

a = offset_of!(T,Variant1.Field1.Variant2.Field2);

By:

a = const{constant#n};{constant#n}: usize = {
_1 = offset_of::<T>(index of Variant1, index of Field1);
_2 = offset_of::<U>(index of Variant2, index of Field2);// Where T::Variant1::Field1 has type U
_0 = _1 + _2
}

The second commit modifies intrinsic const checking to take allow_internal_unstable into account. The new intrinsic should only be called from stable offset_of! macro. The intrinsic itself is unstable, const-unstable, but rustc_intrinsic_const_stable_indirect.

Fixes#123959
Fixes#125680
Fixes#129425
Fixes#136175

r? @ghost

@rustbotrustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Oct 26, 2025
@rust-log-analyzer

This comment has been minimized.

Comment threadlibrary/core/src/intrinsics/mod.rs Outdated
@cjgillot

Copy link
Copy Markdown
ContributorAuthor

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rust-bors

This comment has been minimized.

rust-borsBot added a commit that referenced this pull request Oct 27, 2025
Replace OffsetOf by an actual sum of calls to intrinsic.
@rustbotrustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Oct 27, 2025
@rust-bors

rust-borsBot commented Oct 27, 2025

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: 7721497 (772149783c4c312fd88b7dfaa68a045b14db3280, parent: f37aa9955f03bb1bc6fe08670cb1ecae534b5815)

@rust-timer

This comment has been minimized.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (7721497): comparison URL.

Overall result: ❌✅ regressions and improvements - no action needed

Benchmarking this pull request means it may be perf-sensitive – we'll automatically label it not fit for rolling up. You can override this, but we strongly advise not to, due to possible changes in compiler perf.

@bors rollup=never
@rustbot label: -S-waiting-on-perf -perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

meanrangecount
Regressions ❌
(primary)
--0
Regressions ❌
(secondary)
0.1%[0.0%, 0.1%]3
Improvements ✅
(primary)
--0
Improvements ✅
(secondary)
-0.1%[-0.1%, -0.1%]3
All ❌✅ (primary)--0

Max RSS (memory usage)

Results (secondary -1.9%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

meanrangecount
Regressions ❌
(primary)
--0
Regressions ❌
(secondary)
2.6%[2.1%, 3.2%]2
Improvements ✅
(primary)
--0
Improvements ✅
(secondary)
-3.7%[-4.9%, -1.5%]5
All ❌✅ (primary)--0

Cycles

Results (secondary -0.8%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

meanrangecount
Regressions ❌
(primary)
--0
Regressions ❌
(secondary)
2.7%[1.6%, 5.0%]3
Improvements ✅
(primary)
--0
Improvements ✅
(secondary)
-6.1%[-7.9%, -4.2%]2
All ❌✅ (primary)--0

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 473.876s -> 473.729s (-0.03%)
Artifact size: 390.50 MiB -> 390.46 MiB (-0.01%)

@rustbotrustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Oct 27, 2025
@bors

bors commented Oct 31, 2025

Copy link
Copy Markdown
Collaborator

☔ The latest upstream changes (presumably #148324) made this pull request unmergeable. Please resolve the merge conflicts.

@cjgillot
cjgillot marked this pull request as ready for review November 1, 2025 23:47
@rustbotrustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 1, 2025
@rustbot

Copy link
Copy Markdown
Collaborator

Some changes occurred in match checking

cc @Nadrieril

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

⚠️#[rustc_intrinsic_const_stable_indirect] controls whether intrinsics can be exposed to stable const
code; adding it needs t-lang approval.

cc @rust-lang/wg-const-eval

Some changes occurred to constck

cc @fee1-dead

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

This PR changes rustc_public

cc @oli-obk, @celinval, @ouz-a

Some changes occurred in rustc_ty_utils::consts.rs

cc @BoxyUwU

Some changes occurred to the intrinsics. Make sure the CTFE / Miri interpreter
gets adapted for the changes, if necessary.

cc @rust-lang/miri, @RalfJung, @oli-obk, @lcnr

This PR changes MIR

cc @oli-obk, @RalfJung, @JakobDegen, @vakaras

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

Some changes occurred in compiler/rustc_codegen_ssa

cc @WaffleLapkin

This PR changes a file inside tests/crashes. If a crash was fixed, please move into the corresponding ui subdir and add 'Fixes #' to the PR description to autoclose the issue upon merge.

@rustbotrustbot removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Nov 1, 2025
@cjgillotcjgillot added the I-lang-nominated Nominated for discussion during a lang team meeting. label Nov 2, 2025
@oli-obkoli-obk self-assigned this Nov 2, 2025
@BoxyUwU

BoxyUwU commented Nov 2, 2025

Copy link
Copy Markdown
Member

What's the justification/benefit for doing this, and what user facing impact does it have (i.e. why does it need a lang nomination)?

@cjgillot

Copy link
Copy Markdown
ContributorAuthor

My justification is simplifying MIR. This feature was implemented as a specific MIR statement, but does not need to, an intrinsic is sufficient.

There should be no user-facing change because of the offset_of manipulation. Maybe some diagnostics, but not more.

However, there are 2 user-facing changes in this PR that t-lang may want to know:

  • const-stability of intrinsics now takes allow_internal_unstable into account;
  • we get an additional intrinsic with rustc_intrinsic_const_stable_indirect.

@WaffleLapkin

This comment was marked as resolved.

@cjgillot

This comment was marked as resolved.

@traviscrosstraviscross added the T-lang Relevant to the language team label Nov 5, 2025
@cjgillot
cjgillot deleted the no-offset-of branch November 18, 2025 21:30
tautschnig added a commit to tautschnig/kani that referenced this pull request Nov 19, 2025
Relevant upstream PR:
- rust-lang/rust#148151 (Replace OffsetOf by an
actual sum of calls to intrinsic.)
Resolves: model-checking#4481
@panstromek

Copy link
Copy Markdown
Contributor

perf triage:

As indicated by the comment above, clap_derive is noise, include-blob is also noise (at least the opt variants, other ones didn't return to previous state, but they are tiny in absolute numbers).

@rustbot label: +perf-regression-triaged

@rustbotrustbot added the perf-regression-triaged The performance regression has been triaged. label Nov 19, 2025
github-merge-queueBot pushed a commit to model-checking/kani that referenced this pull request Nov 19, 2025
Relevant upstream PR:
- rust-lang/rust#148151 (Replace OffsetOf by an
actual sum of calls to intrinsic.)
Resolves: #4481
By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache 2.0 and MIT licenses.
github-actionsBot pushed a commit to model-checking/verify-rust-std that referenced this pull request Nov 30, 2025
Replace OffsetOf by an actual sum of calls to intrinsic.
This PR changes the way we compute the value of the `offset_of!` macro in MIR. The current implementation uses a dedicated MIR rvalue.
This PR proposes to replace it by an inline constant which sums calls to a new intrinsic `offset_of(variant index, field index)`. The desugaring is done at THIR building time, easier that doing it on MIR.
The new intrinsic is only meant to be used by const-eval. LLVM codegen will refuse to generate code for it.
We replace:
```rust
a = offset_of!(T, Variant1.Field1.Variant2.Field2);
```
By:
```rust
a = const {constant#n};
{constant#n}: usize = {
_1 = offset_of::<T>(index of Variant1, index of Field1);
_2 = offset_of::<U>(index of Variant2, index of Field2); // Where T::Variant1::Field1 has type U
_0 = _1 + _2
}
```
The second commit modifies intrinsic const checking to take `allow_internal_unstable` into account. The new intrinsic should only be called from stable `offset_of!` macro. The intrinsic itself is unstable, const-unstable, but `rustc_intrinsic_const_stable_indirect`.
Fixesrust-lang#123959Fixesrust-lang#125680Fixesrust-lang#129425Fixesrust-lang#136175
r? `@ghost`
makai410 pushed a commit to makai410/rust that referenced this pull request Dec 10, 2025
Replace OffsetOf by an actual sum of calls to intrinsic.
This PR changes the way we compute the value of the `offset_of!` macro in MIR. The current implementation uses a dedicated MIR rvalue.
This PR proposes to replace it by an inline constant which sums calls to a new intrinsic `offset_of(variant index, field index)`. The desugaring is done at THIR building time, easier that doing it on MIR.
The new intrinsic is only meant to be used by const-eval. LLVM codegen will refuse to generate code for it.
We replace:
```rust
a = offset_of!(T, Variant1.Field1.Variant2.Field2);
```
By:
```rust
a = const {constant#n};
{constant#n}: usize = {
_1 = offset_of::<T>(index of Variant1, index of Field1);
_2 = offset_of::<U>(index of Variant2, index of Field2); // Where T::Variant1::Field1 has type U
_0 = _1 + _2
}
```
The second commit modifies intrinsic const checking to take `allow_internal_unstable` into account. The new intrinsic should only be called from stable `offset_of!` macro. The intrinsic itself is unstable, const-unstable, but `rustc_intrinsic_const_stable_indirect`.
Fixesrust-lang#123959Fixesrust-lang#125680Fixesrust-lang#129425Fixesrust-lang#136175
r? `@ghost`
bors added a commit that referenced this pull request Dec 22, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on #148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After #148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/miri that referenced this pull request Dec 23, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
bjorn3 pushed a commit to rust-lang/rustc_codegen_cranelift that referenced this pull request Dec 23, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
Kobzol pushed a commit to Kobzol/rustc_codegen_cranelift that referenced this pull request Dec 23, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/rust-analyzer that referenced this pull request Dec 25, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
flip1995 pushed a commit to flip1995/rust-clippy that referenced this pull request Dec 25, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/compiler-builtins that referenced this pull request Dec 28, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/rustc-dev-guide that referenced this pull request Dec 29, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 6, 2026
…ery, r=petrochenkov
Fix ICE in `offset_of!` error recovery
Fixesrust-lang#153236.
`offset_of!` was changed in rust-lang#148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 6, 2026
…ery, r=petrochenkov
Fix ICE in `offset_of!` error recovery
Fixesrust-lang#153236.
`offset_of!` was changed in rust-lang#148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
rust-timer added a commit that referenced this pull request Mar 6, 2026
Rollup merge of #153495 - TaKO8Ki:fix-153236-offset-of-recovery, r=petrochenkov
Fix ICE in `offset_of!` error recovery
Fixes#153236.
`offset_of!` was changed in #148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
github-actionsBot pushed a commit to rust-lang/rust-analyzer that referenced this pull request Mar 9, 2026
…trochenkov
Fix ICE in `offset_of!` error recovery
Fixesrust-lang/rust#153236.
`offset_of!` was changed in rust-lang/rust#148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
makai410 pushed a commit to makai410/rustc_public that referenced this pull request Mar 19, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
makai410 pushed a commit to makai410/rustc_public that referenced this pull request Mar 19, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
makai410 pushed a commit to makai410/rustc_public that referenced this pull request Mar 27, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

disposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.finished-final-comment-periodThe final comment period is finished for this PR / Issue.I-lang-radarItems that are on lang's radar and will need eventual work or consideration.merged-by-borsThis PR was explicitly merged by bors.perf-regressionPerformance regression.perf-regression-triagedThe performance regression has been triaged.S-waiting-on-borsStatus: Waiting on bors to run and complete tests. Bors will change the label on completion.T-clippyRelevant to the Clippy team.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamT-libsRelevant to the library team, which will review and decide on the PR/issue.to-announceAnnounce this issue on triage meeting

Projects

None yet

15 participants

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

Replace OffsetOf by an actual sum of calls to intrinsic. - #148151

Merged
bors merged 5 commits into
rust-lang:mainfrom
cjgillot:no-offset-of
Nov 18, 2025
Merged

Replace OffsetOf by an actual sum of calls to intrinsic.#148151
bors merged 5 commits into
rust-lang:mainfrom
cjgillot:no-offset-of

Conversation

@cjgillot

@cjgillotcjgillot commented Oct 26, 2025

Copy link
Copy Markdown
Contributor

This PR changes the way we compute the value of the offset_of! macro in MIR. The current implementation uses a dedicated MIR rvalue.

This PR proposes to replace it by an inline constant which sums calls to a new intrinsic offset_of(variant index, field index). The desugaring is done at THIR building time, easier that doing it on MIR.

The new intrinsic is only meant to be used by const-eval. LLVM codegen will refuse to generate code for it.

We replace:

a = offset_of!(T,Variant1.Field1.Variant2.Field2);

By:

a = const{constant#n};{constant#n}: usize = {
_1 = offset_of::<T>(index of Variant1, index of Field1);
_2 = offset_of::<U>(index of Variant2, index of Field2);// Where T::Variant1::Field1 has type U
_0 = _1 + _2
}

The second commit modifies intrinsic const checking to take allow_internal_unstable into account. The new intrinsic should only be called from stable offset_of! macro. The intrinsic itself is unstable, const-unstable, but rustc_intrinsic_const_stable_indirect.

Fixes#123959
Fixes#125680
Fixes#129425
Fixes#136175

r? @ghost

@rustbotrustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Oct 26, 2025
@rust-log-analyzer

This comment has been minimized.

Comment threadlibrary/core/src/intrinsics/mod.rs Outdated
@cjgillot

Copy link
Copy Markdown
ContributorAuthor

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rust-bors

This comment has been minimized.

rust-borsBot added a commit that referenced this pull request Oct 27, 2025
Replace OffsetOf by an actual sum of calls to intrinsic.
@rustbotrustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Oct 27, 2025
@rust-bors

rust-borsBot commented Oct 27, 2025

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: 7721497 (772149783c4c312fd88b7dfaa68a045b14db3280, parent: f37aa9955f03bb1bc6fe08670cb1ecae534b5815)

@rust-timer

This comment has been minimized.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (7721497): comparison URL.

Overall result: ❌✅ regressions and improvements - no action needed

Benchmarking this pull request means it may be perf-sensitive – we'll automatically label it not fit for rolling up. You can override this, but we strongly advise not to, due to possible changes in compiler perf.

@bors rollup=never
@rustbot label: -S-waiting-on-perf -perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

meanrangecount
Regressions ❌
(primary)
--0
Regressions ❌
(secondary)
0.1%[0.0%, 0.1%]3
Improvements ✅
(primary)
--0
Improvements ✅
(secondary)
-0.1%[-0.1%, -0.1%]3
All ❌✅ (primary)--0

Max RSS (memory usage)

Results (secondary -1.9%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

meanrangecount
Regressions ❌
(primary)
--0
Regressions ❌
(secondary)
2.6%[2.1%, 3.2%]2
Improvements ✅
(primary)
--0
Improvements ✅
(secondary)
-3.7%[-4.9%, -1.5%]5
All ❌✅ (primary)--0

Cycles

Results (secondary -0.8%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

meanrangecount
Regressions ❌
(primary)
--0
Regressions ❌
(secondary)
2.7%[1.6%, 5.0%]3
Improvements ✅
(primary)
--0
Improvements ✅
(secondary)
-6.1%[-7.9%, -4.2%]2
All ❌✅ (primary)--0

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 473.876s -> 473.729s (-0.03%)
Artifact size: 390.50 MiB -> 390.46 MiB (-0.01%)

@rustbotrustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Oct 27, 2025
@bors

bors commented Oct 31, 2025

Copy link
Copy Markdown
Collaborator

☔ The latest upstream changes (presumably #148324) made this pull request unmergeable. Please resolve the merge conflicts.

@cjgillot
cjgillot marked this pull request as ready for review November 1, 2025 23:47
@rustbotrustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 1, 2025
@rustbot

Copy link
Copy Markdown
Collaborator

Some changes occurred in match checking

cc @Nadrieril

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

⚠️#[rustc_intrinsic_const_stable_indirect] controls whether intrinsics can be exposed to stable const
code; adding it needs t-lang approval.

cc @rust-lang/wg-const-eval

Some changes occurred to constck

cc @fee1-dead

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

This PR changes rustc_public

cc @oli-obk, @celinval, @ouz-a

Some changes occurred in rustc_ty_utils::consts.rs

cc @BoxyUwU

Some changes occurred to the intrinsics. Make sure the CTFE / Miri interpreter
gets adapted for the changes, if necessary.

cc @rust-lang/miri, @RalfJung, @oli-obk, @lcnr

This PR changes MIR

cc @oli-obk, @RalfJung, @JakobDegen, @vakaras

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

Some changes occurred in compiler/rustc_codegen_ssa

cc @WaffleLapkin

This PR changes a file inside tests/crashes. If a crash was fixed, please move into the corresponding ui subdir and add 'Fixes #' to the PR description to autoclose the issue upon merge.

@rustbotrustbot removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Nov 1, 2025
@cjgillotcjgillot added the I-lang-nominated Nominated for discussion during a lang team meeting. label Nov 2, 2025
@oli-obkoli-obk self-assigned this Nov 2, 2025
@BoxyUwU

BoxyUwU commented Nov 2, 2025

Copy link
Copy Markdown
Member

What's the justification/benefit for doing this, and what user facing impact does it have (i.e. why does it need a lang nomination)?

@cjgillot

Copy link
Copy Markdown
ContributorAuthor

My justification is simplifying MIR. This feature was implemented as a specific MIR statement, but does not need to, an intrinsic is sufficient.

There should be no user-facing change because of the offset_of manipulation. Maybe some diagnostics, but not more.

However, there are 2 user-facing changes in this PR that t-lang may want to know:

  • const-stability of intrinsics now takes allow_internal_unstable into account;
  • we get an additional intrinsic with rustc_intrinsic_const_stable_indirect.

@WaffleLapkin

This comment was marked as resolved.

@cjgillot

This comment was marked as resolved.

@traviscrosstraviscross added the T-lang Relevant to the language team label Nov 5, 2025
@cjgillot
cjgillot deleted the no-offset-of branch November 18, 2025 21:30
tautschnig added a commit to tautschnig/kani that referenced this pull request Nov 19, 2025
Relevant upstream PR:
- rust-lang/rust#148151 (Replace OffsetOf by an
actual sum of calls to intrinsic.)
Resolves: model-checking#4481
@panstromek

Copy link
Copy Markdown
Contributor

perf triage:

As indicated by the comment above, clap_derive is noise, include-blob is also noise (at least the opt variants, other ones didn't return to previous state, but they are tiny in absolute numbers).

@rustbot label: +perf-regression-triaged

@rustbotrustbot added the perf-regression-triaged The performance regression has been triaged. label Nov 19, 2025
github-merge-queueBot pushed a commit to model-checking/kani that referenced this pull request Nov 19, 2025
Relevant upstream PR:
- rust-lang/rust#148151 (Replace OffsetOf by an
actual sum of calls to intrinsic.)
Resolves: #4481
By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache 2.0 and MIT licenses.
github-actionsBot pushed a commit to model-checking/verify-rust-std that referenced this pull request Nov 30, 2025
Replace OffsetOf by an actual sum of calls to intrinsic.
This PR changes the way we compute the value of the `offset_of!` macro in MIR. The current implementation uses a dedicated MIR rvalue.
This PR proposes to replace it by an inline constant which sums calls to a new intrinsic `offset_of(variant index, field index)`. The desugaring is done at THIR building time, easier that doing it on MIR.
The new intrinsic is only meant to be used by const-eval. LLVM codegen will refuse to generate code for it.
We replace:
```rust
a = offset_of!(T, Variant1.Field1.Variant2.Field2);
```
By:
```rust
a = const {constant#n};
{constant#n}: usize = {
_1 = offset_of::<T>(index of Variant1, index of Field1);
_2 = offset_of::<U>(index of Variant2, index of Field2); // Where T::Variant1::Field1 has type U
_0 = _1 + _2
}
```
The second commit modifies intrinsic const checking to take `allow_internal_unstable` into account. The new intrinsic should only be called from stable `offset_of!` macro. The intrinsic itself is unstable, const-unstable, but `rustc_intrinsic_const_stable_indirect`.
Fixesrust-lang#123959Fixesrust-lang#125680Fixesrust-lang#129425Fixesrust-lang#136175
r? `@ghost`
makai410 pushed a commit to makai410/rust that referenced this pull request Dec 10, 2025
Replace OffsetOf by an actual sum of calls to intrinsic.
This PR changes the way we compute the value of the `offset_of!` macro in MIR. The current implementation uses a dedicated MIR rvalue.
This PR proposes to replace it by an inline constant which sums calls to a new intrinsic `offset_of(variant index, field index)`. The desugaring is done at THIR building time, easier that doing it on MIR.
The new intrinsic is only meant to be used by const-eval. LLVM codegen will refuse to generate code for it.
We replace:
```rust
a = offset_of!(T, Variant1.Field1.Variant2.Field2);
```
By:
```rust
a = const {constant#n};
{constant#n}: usize = {
_1 = offset_of::<T>(index of Variant1, index of Field1);
_2 = offset_of::<U>(index of Variant2, index of Field2); // Where T::Variant1::Field1 has type U
_0 = _1 + _2
}
```
The second commit modifies intrinsic const checking to take `allow_internal_unstable` into account. The new intrinsic should only be called from stable `offset_of!` macro. The intrinsic itself is unstable, const-unstable, but `rustc_intrinsic_const_stable_indirect`.
Fixesrust-lang#123959Fixesrust-lang#125680Fixesrust-lang#129425Fixesrust-lang#136175
r? `@ghost`
bors added a commit that referenced this pull request Dec 22, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on #148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After #148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/miri that referenced this pull request Dec 23, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
bjorn3 pushed a commit to rust-lang/rustc_codegen_cranelift that referenced this pull request Dec 23, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
Kobzol pushed a commit to Kobzol/rustc_codegen_cranelift that referenced this pull request Dec 23, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/rust-analyzer that referenced this pull request Dec 25, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
flip1995 pushed a commit to flip1995/rust-clippy that referenced this pull request Dec 25, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/compiler-builtins that referenced this pull request Dec 28, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/rustc-dev-guide that referenced this pull request Dec 29, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 6, 2026
…ery, r=petrochenkov
Fix ICE in `offset_of!` error recovery
Fixesrust-lang#153236.
`offset_of!` was changed in rust-lang#148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 6, 2026
…ery, r=petrochenkov
Fix ICE in `offset_of!` error recovery
Fixesrust-lang#153236.
`offset_of!` was changed in rust-lang#148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
rust-timer added a commit that referenced this pull request Mar 6, 2026
Rollup merge of #153495 - TaKO8Ki:fix-153236-offset-of-recovery, r=petrochenkov
Fix ICE in `offset_of!` error recovery
Fixes#153236.
`offset_of!` was changed in #148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
github-actionsBot pushed a commit to rust-lang/rust-analyzer that referenced this pull request Mar 9, 2026
…trochenkov
Fix ICE in `offset_of!` error recovery
Fixesrust-lang/rust#153236.
`offset_of!` was changed in rust-lang/rust#148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
makai410 pushed a commit to makai410/rustc_public that referenced this pull request Mar 19, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
makai410 pushed a commit to makai410/rustc_public that referenced this pull request Mar 19, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
makai410 pushed a commit to makai410/rustc_public that referenced this pull request Mar 27, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

disposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.finished-final-comment-periodThe final comment period is finished for this PR / Issue.I-lang-radarItems that are on lang's radar and will need eventual work or consideration.merged-by-borsThis PR was explicitly merged by bors.perf-regressionPerformance regression.perf-regression-triagedThe performance regression has been triaged.S-waiting-on-borsStatus: Waiting on bors to run and complete tests. Bors will change the label on completion.T-clippyRelevant to the Clippy team.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamT-libsRelevant to the library team, which will review and decide on the PR/issue.to-announceAnnounce this issue on triage meeting

Projects

None yet

15 participants

@cjgillot@rust-log-analyzer@rust-timer@bors@rustbot@BoxyUwU@WaffleLapkin@scottmcm@rust-rfcbot@traviscross@nikomatsakis@oli-obk@lqd@panstromek@RalfJung
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Replace OffsetOf by an actual sum of calls to intrinsic. - #148151

Merged
bors merged 5 commits into
rust-lang:mainfrom
cjgillot:no-offset-of
Nov 18, 2025
Merged

Replace OffsetOf by an actual sum of calls to intrinsic.#148151
bors merged 5 commits into
rust-lang:mainfrom
cjgillot:no-offset-of

Conversation

@cjgillot

@cjgillotcjgillot commented Oct 26, 2025

Copy link
Copy Markdown
Contributor

This PR changes the way we compute the value of the offset_of! macro in MIR. The current implementation uses a dedicated MIR rvalue.

This PR proposes to replace it by an inline constant which sums calls to a new intrinsic offset_of(variant index, field index). The desugaring is done at THIR building time, easier that doing it on MIR.

The new intrinsic is only meant to be used by const-eval. LLVM codegen will refuse to generate code for it.

We replace:

a = offset_of!(T,Variant1.Field1.Variant2.Field2);

By:

a = const{constant#n};{constant#n}: usize = {
_1 = offset_of::<T>(index of Variant1, index of Field1);
_2 = offset_of::<U>(index of Variant2, index of Field2);// Where T::Variant1::Field1 has type U
_0 = _1 + _2
}

The second commit modifies intrinsic const checking to take allow_internal_unstable into account. The new intrinsic should only be called from stable offset_of! macro. The intrinsic itself is unstable, const-unstable, but rustc_intrinsic_const_stable_indirect.

Fixes#123959
Fixes#125680
Fixes#129425
Fixes#136175

r? @ghost

@rustbotrustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Oct 26, 2025
@rust-log-analyzer

This comment has been minimized.

Comment threadlibrary/core/src/intrinsics/mod.rs Outdated
@cjgillot

Copy link
Copy Markdown
ContributorAuthor

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rust-bors

This comment has been minimized.

rust-borsBot added a commit that referenced this pull request Oct 27, 2025
Replace OffsetOf by an actual sum of calls to intrinsic.
@rustbotrustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Oct 27, 2025
@rust-bors

rust-borsBot commented Oct 27, 2025

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: 7721497 (772149783c4c312fd88b7dfaa68a045b14db3280, parent: f37aa9955f03bb1bc6fe08670cb1ecae534b5815)

@rust-timer

This comment has been minimized.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (7721497): comparison URL.

Overall result: ❌✅ regressions and improvements - no action needed

Benchmarking this pull request means it may be perf-sensitive – we'll automatically label it not fit for rolling up. You can override this, but we strongly advise not to, due to possible changes in compiler perf.

@bors rollup=never
@rustbot label: -S-waiting-on-perf -perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

meanrangecount
Regressions ❌
(primary)
--0
Regressions ❌
(secondary)
0.1%[0.0%, 0.1%]3
Improvements ✅
(primary)
--0
Improvements ✅
(secondary)
-0.1%[-0.1%, -0.1%]3
All ❌✅ (primary)--0

Max RSS (memory usage)

Results (secondary -1.9%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

meanrangecount
Regressions ❌
(primary)
--0
Regressions ❌
(secondary)
2.6%[2.1%, 3.2%]2
Improvements ✅
(primary)
--0
Improvements ✅
(secondary)
-3.7%[-4.9%, -1.5%]5
All ❌✅ (primary)--0

Cycles

Results (secondary -0.8%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

meanrangecount
Regressions ❌
(primary)
--0
Regressions ❌
(secondary)
2.7%[1.6%, 5.0%]3
Improvements ✅
(primary)
--0
Improvements ✅
(secondary)
-6.1%[-7.9%, -4.2%]2
All ❌✅ (primary)--0

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 473.876s -> 473.729s (-0.03%)
Artifact size: 390.50 MiB -> 390.46 MiB (-0.01%)

@rustbotrustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Oct 27, 2025
@bors

bors commented Oct 31, 2025

Copy link
Copy Markdown
Collaborator

☔ The latest upstream changes (presumably #148324) made this pull request unmergeable. Please resolve the merge conflicts.

@cjgillot
cjgillot marked this pull request as ready for review November 1, 2025 23:47
@rustbotrustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 1, 2025
@rustbot

Copy link
Copy Markdown
Collaborator

Some changes occurred in match checking

cc @Nadrieril

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

⚠️#[rustc_intrinsic_const_stable_indirect] controls whether intrinsics can be exposed to stable const
code; adding it needs t-lang approval.

cc @rust-lang/wg-const-eval

Some changes occurred to constck

cc @fee1-dead

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

This PR changes rustc_public

cc @oli-obk, @celinval, @ouz-a

Some changes occurred in rustc_ty_utils::consts.rs

cc @BoxyUwU

Some changes occurred to the intrinsics. Make sure the CTFE / Miri interpreter
gets adapted for the changes, if necessary.

cc @rust-lang/miri, @RalfJung, @oli-obk, @lcnr

This PR changes MIR

cc @oli-obk, @RalfJung, @JakobDegen, @vakaras

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

Some changes occurred in compiler/rustc_codegen_ssa

cc @WaffleLapkin

This PR changes a file inside tests/crashes. If a crash was fixed, please move into the corresponding ui subdir and add 'Fixes #' to the PR description to autoclose the issue upon merge.

@rustbotrustbot removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Nov 1, 2025
@cjgillotcjgillot added the I-lang-nominated Nominated for discussion during a lang team meeting. label Nov 2, 2025
@oli-obkoli-obk self-assigned this Nov 2, 2025
@BoxyUwU

BoxyUwU commented Nov 2, 2025

Copy link
Copy Markdown
Member

What's the justification/benefit for doing this, and what user facing impact does it have (i.e. why does it need a lang nomination)?

@cjgillot

Copy link
Copy Markdown
ContributorAuthor

My justification is simplifying MIR. This feature was implemented as a specific MIR statement, but does not need to, an intrinsic is sufficient.

There should be no user-facing change because of the offset_of manipulation. Maybe some diagnostics, but not more.

However, there are 2 user-facing changes in this PR that t-lang may want to know:

  • const-stability of intrinsics now takes allow_internal_unstable into account;
  • we get an additional intrinsic with rustc_intrinsic_const_stable_indirect.

@WaffleLapkin

This comment was marked as resolved.

@cjgillot

This comment was marked as resolved.

@traviscrosstraviscross added the T-lang Relevant to the language team label Nov 5, 2025
@cjgillot
cjgillot deleted the no-offset-of branch November 18, 2025 21:30
tautschnig added a commit to tautschnig/kani that referenced this pull request Nov 19, 2025
Relevant upstream PR:
- rust-lang/rust#148151 (Replace OffsetOf by an
actual sum of calls to intrinsic.)
Resolves: model-checking#4481
@panstromek

Copy link
Copy Markdown
Contributor

perf triage:

As indicated by the comment above, clap_derive is noise, include-blob is also noise (at least the opt variants, other ones didn't return to previous state, but they are tiny in absolute numbers).

@rustbot label: +perf-regression-triaged

@rustbotrustbot added the perf-regression-triaged The performance regression has been triaged. label Nov 19, 2025
github-merge-queueBot pushed a commit to model-checking/kani that referenced this pull request Nov 19, 2025
Relevant upstream PR:
- rust-lang/rust#148151 (Replace OffsetOf by an
actual sum of calls to intrinsic.)
Resolves: #4481
By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache 2.0 and MIT licenses.
github-actionsBot pushed a commit to model-checking/verify-rust-std that referenced this pull request Nov 30, 2025
Replace OffsetOf by an actual sum of calls to intrinsic.
This PR changes the way we compute the value of the `offset_of!` macro in MIR. The current implementation uses a dedicated MIR rvalue.
This PR proposes to replace it by an inline constant which sums calls to a new intrinsic `offset_of(variant index, field index)`. The desugaring is done at THIR building time, easier that doing it on MIR.
The new intrinsic is only meant to be used by const-eval. LLVM codegen will refuse to generate code for it.
We replace:
```rust
a = offset_of!(T, Variant1.Field1.Variant2.Field2);
```
By:
```rust
a = const {constant#n};
{constant#n}: usize = {
_1 = offset_of::<T>(index of Variant1, index of Field1);
_2 = offset_of::<U>(index of Variant2, index of Field2); // Where T::Variant1::Field1 has type U
_0 = _1 + _2
}
```
The second commit modifies intrinsic const checking to take `allow_internal_unstable` into account. The new intrinsic should only be called from stable `offset_of!` macro. The intrinsic itself is unstable, const-unstable, but `rustc_intrinsic_const_stable_indirect`.
Fixesrust-lang#123959Fixesrust-lang#125680Fixesrust-lang#129425Fixesrust-lang#136175
r? `@ghost`
makai410 pushed a commit to makai410/rust that referenced this pull request Dec 10, 2025
Replace OffsetOf by an actual sum of calls to intrinsic.
This PR changes the way we compute the value of the `offset_of!` macro in MIR. The current implementation uses a dedicated MIR rvalue.
This PR proposes to replace it by an inline constant which sums calls to a new intrinsic `offset_of(variant index, field index)`. The desugaring is done at THIR building time, easier that doing it on MIR.
The new intrinsic is only meant to be used by const-eval. LLVM codegen will refuse to generate code for it.
We replace:
```rust
a = offset_of!(T, Variant1.Field1.Variant2.Field2);
```
By:
```rust
a = const {constant#n};
{constant#n}: usize = {
_1 = offset_of::<T>(index of Variant1, index of Field1);
_2 = offset_of::<U>(index of Variant2, index of Field2); // Where T::Variant1::Field1 has type U
_0 = _1 + _2
}
```
The second commit modifies intrinsic const checking to take `allow_internal_unstable` into account. The new intrinsic should only be called from stable `offset_of!` macro. The intrinsic itself is unstable, const-unstable, but `rustc_intrinsic_const_stable_indirect`.
Fixesrust-lang#123959Fixesrust-lang#125680Fixesrust-lang#129425Fixesrust-lang#136175
r? `@ghost`
bors added a commit that referenced this pull request Dec 22, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on #148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After #148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/miri that referenced this pull request Dec 23, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
bjorn3 pushed a commit to rust-lang/rustc_codegen_cranelift that referenced this pull request Dec 23, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
Kobzol pushed a commit to Kobzol/rustc_codegen_cranelift that referenced this pull request Dec 23, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/rust-analyzer that referenced this pull request Dec 25, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
flip1995 pushed a commit to flip1995/rust-clippy that referenced this pull request Dec 25, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/compiler-builtins that referenced this pull request Dec 28, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/rustc-dev-guide that referenced this pull request Dec 29, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 6, 2026
…ery, r=petrochenkov
Fix ICE in `offset_of!` error recovery
Fixesrust-lang#153236.
`offset_of!` was changed in rust-lang#148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 6, 2026
…ery, r=petrochenkov
Fix ICE in `offset_of!` error recovery
Fixesrust-lang#153236.
`offset_of!` was changed in rust-lang#148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
rust-timer added a commit that referenced this pull request Mar 6, 2026
Rollup merge of #153495 - TaKO8Ki:fix-153236-offset-of-recovery, r=petrochenkov
Fix ICE in `offset_of!` error recovery
Fixes#153236.
`offset_of!` was changed in #148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
github-actionsBot pushed a commit to rust-lang/rust-analyzer that referenced this pull request Mar 9, 2026
…trochenkov
Fix ICE in `offset_of!` error recovery
Fixesrust-lang/rust#153236.
`offset_of!` was changed in rust-lang/rust#148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
makai410 pushed a commit to makai410/rustc_public that referenced this pull request Mar 19, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
makai410 pushed a commit to makai410/rustc_public that referenced this pull request Mar 19, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
makai410 pushed a commit to makai410/rustc_public that referenced this pull request Mar 27, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

disposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.finished-final-comment-periodThe final comment period is finished for this PR / Issue.I-lang-radarItems that are on lang's radar and will need eventual work or consideration.merged-by-borsThis PR was explicitly merged by bors.perf-regressionPerformance regression.perf-regression-triagedThe performance regression has been triaged.S-waiting-on-borsStatus: Waiting on bors to run and complete tests. Bors will change the label on completion.T-clippyRelevant to the Clippy team.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamT-libsRelevant to the library team, which will review and decide on the PR/issue.to-announceAnnounce this issue on triage meeting

Projects

None yet

15 participants

@cjgillot@rust-log-analyzer@rust-timer@bors@rustbot@BoxyUwU@WaffleLapkin@scottmcm@rust-rfcbot@traviscross@nikomatsakis@oli-obk@lqd@panstromek@RalfJung
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Replace OffsetOf by an actual sum of calls to intrinsic. - #148151

Merged
bors merged 5 commits into
rust-lang:mainfrom
cjgillot:no-offset-of
Nov 18, 2025
Merged

Replace OffsetOf by an actual sum of calls to intrinsic.#148151
bors merged 5 commits into
rust-lang:mainfrom
cjgillot:no-offset-of

Conversation

@cjgillot

@cjgillotcjgillot commented Oct 26, 2025

Copy link
Copy Markdown
Contributor

This PR changes the way we compute the value of the offset_of! macro in MIR. The current implementation uses a dedicated MIR rvalue.

This PR proposes to replace it by an inline constant which sums calls to a new intrinsic offset_of(variant index, field index). The desugaring is done at THIR building time, easier that doing it on MIR.

The new intrinsic is only meant to be used by const-eval. LLVM codegen will refuse to generate code for it.

We replace:

a = offset_of!(T,Variant1.Field1.Variant2.Field2);

By:

a = const{constant#n};{constant#n}: usize = {
_1 = offset_of::<T>(index of Variant1, index of Field1);
_2 = offset_of::<U>(index of Variant2, index of Field2);// Where T::Variant1::Field1 has type U
_0 = _1 + _2
}

The second commit modifies intrinsic const checking to take allow_internal_unstable into account. The new intrinsic should only be called from stable offset_of! macro. The intrinsic itself is unstable, const-unstable, but rustc_intrinsic_const_stable_indirect.

Fixes#123959
Fixes#125680
Fixes#129425
Fixes#136175

r? @ghost

@rustbotrustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Oct 26, 2025
@rust-log-analyzer

This comment has been minimized.

Comment threadlibrary/core/src/intrinsics/mod.rs Outdated
@cjgillot

Copy link
Copy Markdown
ContributorAuthor

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rust-bors

This comment has been minimized.

rust-borsBot added a commit that referenced this pull request Oct 27, 2025
Replace OffsetOf by an actual sum of calls to intrinsic.
@rustbotrustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Oct 27, 2025
@rust-bors

rust-borsBot commented Oct 27, 2025

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: 7721497 (772149783c4c312fd88b7dfaa68a045b14db3280, parent: f37aa9955f03bb1bc6fe08670cb1ecae534b5815)

@rust-timer

This comment has been minimized.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (7721497): comparison URL.

Overall result: ❌✅ regressions and improvements - no action needed

Benchmarking this pull request means it may be perf-sensitive – we'll automatically label it not fit for rolling up. You can override this, but we strongly advise not to, due to possible changes in compiler perf.

@bors rollup=never
@rustbot label: -S-waiting-on-perf -perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

meanrangecount
Regressions ❌
(primary)
--0
Regressions ❌
(secondary)
0.1%[0.0%, 0.1%]3
Improvements ✅
(primary)
--0
Improvements ✅
(secondary)
-0.1%[-0.1%, -0.1%]3
All ❌✅ (primary)--0

Max RSS (memory usage)

Results (secondary -1.9%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

meanrangecount
Regressions ❌
(primary)
--0
Regressions ❌
(secondary)
2.6%[2.1%, 3.2%]2
Improvements ✅
(primary)
--0
Improvements ✅
(secondary)
-3.7%[-4.9%, -1.5%]5
All ❌✅ (primary)--0

Cycles

Results (secondary -0.8%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

meanrangecount
Regressions ❌
(primary)
--0
Regressions ❌
(secondary)
2.7%[1.6%, 5.0%]3
Improvements ✅
(primary)
--0
Improvements ✅
(secondary)
-6.1%[-7.9%, -4.2%]2
All ❌✅ (primary)--0

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 473.876s -> 473.729s (-0.03%)
Artifact size: 390.50 MiB -> 390.46 MiB (-0.01%)

@rustbotrustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Oct 27, 2025
@bors

bors commented Oct 31, 2025

Copy link
Copy Markdown
Collaborator

☔ The latest upstream changes (presumably #148324) made this pull request unmergeable. Please resolve the merge conflicts.

@cjgillot
cjgillot marked this pull request as ready for review November 1, 2025 23:47
@rustbotrustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 1, 2025
@rustbot

Copy link
Copy Markdown
Collaborator

Some changes occurred in match checking

cc @Nadrieril

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

⚠️#[rustc_intrinsic_const_stable_indirect] controls whether intrinsics can be exposed to stable const
code; adding it needs t-lang approval.

cc @rust-lang/wg-const-eval

Some changes occurred to constck

cc @fee1-dead

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

This PR changes rustc_public

cc @oli-obk, @celinval, @ouz-a

Some changes occurred in rustc_ty_utils::consts.rs

cc @BoxyUwU

Some changes occurred to the intrinsics. Make sure the CTFE / Miri interpreter
gets adapted for the changes, if necessary.

cc @rust-lang/miri, @RalfJung, @oli-obk, @lcnr

This PR changes MIR

cc @oli-obk, @RalfJung, @JakobDegen, @vakaras

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

Some changes occurred in compiler/rustc_codegen_ssa

cc @WaffleLapkin

This PR changes a file inside tests/crashes. If a crash was fixed, please move into the corresponding ui subdir and add 'Fixes #' to the PR description to autoclose the issue upon merge.

@rustbotrustbot removed the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Nov 1, 2025
@cjgillotcjgillot added the I-lang-nominated Nominated for discussion during a lang team meeting. label Nov 2, 2025
@oli-obkoli-obk self-assigned this Nov 2, 2025
@BoxyUwU

BoxyUwU commented Nov 2, 2025

Copy link
Copy Markdown
Member

What's the justification/benefit for doing this, and what user facing impact does it have (i.e. why does it need a lang nomination)?

@cjgillot

Copy link
Copy Markdown
ContributorAuthor

My justification is simplifying MIR. This feature was implemented as a specific MIR statement, but does not need to, an intrinsic is sufficient.

There should be no user-facing change because of the offset_of manipulation. Maybe some diagnostics, but not more.

However, there are 2 user-facing changes in this PR that t-lang may want to know:

  • const-stability of intrinsics now takes allow_internal_unstable into account;
  • we get an additional intrinsic with rustc_intrinsic_const_stable_indirect.

@WaffleLapkin

This comment was marked as resolved.

@cjgillot

This comment was marked as resolved.

@traviscrosstraviscross added the T-lang Relevant to the language team label Nov 5, 2025
@cjgillot
cjgillot deleted the no-offset-of branch November 18, 2025 21:30
tautschnig added a commit to tautschnig/kani that referenced this pull request Nov 19, 2025
Relevant upstream PR:
- rust-lang/rust#148151 (Replace OffsetOf by an
actual sum of calls to intrinsic.)
Resolves: model-checking#4481
@panstromek

Copy link
Copy Markdown
Contributor

perf triage:

As indicated by the comment above, clap_derive is noise, include-blob is also noise (at least the opt variants, other ones didn't return to previous state, but they are tiny in absolute numbers).

@rustbot label: +perf-regression-triaged

@rustbotrustbot added the perf-regression-triaged The performance regression has been triaged. label Nov 19, 2025
github-merge-queueBot pushed a commit to model-checking/kani that referenced this pull request Nov 19, 2025
Relevant upstream PR:
- rust-lang/rust#148151 (Replace OffsetOf by an
actual sum of calls to intrinsic.)
Resolves: #4481
By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache 2.0 and MIT licenses.
github-actionsBot pushed a commit to model-checking/verify-rust-std that referenced this pull request Nov 30, 2025
Replace OffsetOf by an actual sum of calls to intrinsic.
This PR changes the way we compute the value of the `offset_of!` macro in MIR. The current implementation uses a dedicated MIR rvalue.
This PR proposes to replace it by an inline constant which sums calls to a new intrinsic `offset_of(variant index, field index)`. The desugaring is done at THIR building time, easier that doing it on MIR.
The new intrinsic is only meant to be used by const-eval. LLVM codegen will refuse to generate code for it.
We replace:
```rust
a = offset_of!(T, Variant1.Field1.Variant2.Field2);
```
By:
```rust
a = const {constant#n};
{constant#n}: usize = {
_1 = offset_of::<T>(index of Variant1, index of Field1);
_2 = offset_of::<U>(index of Variant2, index of Field2); // Where T::Variant1::Field1 has type U
_0 = _1 + _2
}
```
The second commit modifies intrinsic const checking to take `allow_internal_unstable` into account. The new intrinsic should only be called from stable `offset_of!` macro. The intrinsic itself is unstable, const-unstable, but `rustc_intrinsic_const_stable_indirect`.
Fixesrust-lang#123959Fixesrust-lang#125680Fixesrust-lang#129425Fixesrust-lang#136175
r? `@ghost`
makai410 pushed a commit to makai410/rust that referenced this pull request Dec 10, 2025
Replace OffsetOf by an actual sum of calls to intrinsic.
This PR changes the way we compute the value of the `offset_of!` macro in MIR. The current implementation uses a dedicated MIR rvalue.
This PR proposes to replace it by an inline constant which sums calls to a new intrinsic `offset_of(variant index, field index)`. The desugaring is done at THIR building time, easier that doing it on MIR.
The new intrinsic is only meant to be used by const-eval. LLVM codegen will refuse to generate code for it.
We replace:
```rust
a = offset_of!(T, Variant1.Field1.Variant2.Field2);
```
By:
```rust
a = const {constant#n};
{constant#n}: usize = {
_1 = offset_of::<T>(index of Variant1, index of Field1);
_2 = offset_of::<U>(index of Variant2, index of Field2); // Where T::Variant1::Field1 has type U
_0 = _1 + _2
}
```
The second commit modifies intrinsic const checking to take `allow_internal_unstable` into account. The new intrinsic should only be called from stable `offset_of!` macro. The intrinsic itself is unstable, const-unstable, but `rustc_intrinsic_const_stable_indirect`.
Fixesrust-lang#123959Fixesrust-lang#125680Fixesrust-lang#129425Fixesrust-lang#136175
r? `@ghost`
bors added a commit that referenced this pull request Dec 22, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on #148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After #148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/miri that referenced this pull request Dec 23, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
bjorn3 pushed a commit to rust-lang/rustc_codegen_cranelift that referenced this pull request Dec 23, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
Kobzol pushed a commit to Kobzol/rustc_codegen_cranelift that referenced this pull request Dec 23, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/rust-analyzer that referenced this pull request Dec 25, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
flip1995 pushed a commit to flip1995/rust-clippy that referenced this pull request Dec 25, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/compiler-builtins that referenced this pull request Dec 28, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
github-actionsBot pushed a commit to rust-lang/rustc-dev-guide that referenced this pull request Dec 29, 2025
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
christian-schilling pushed a commit to christian-schilling/rustc_codegen_cranelift that referenced this pull request Jan 27, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 6, 2026
…ery, r=petrochenkov
Fix ICE in `offset_of!` error recovery
Fixesrust-lang#153236.
`offset_of!` was changed in rust-lang#148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Mar 6, 2026
…ery, r=petrochenkov
Fix ICE in `offset_of!` error recovery
Fixesrust-lang#153236.
`offset_of!` was changed in rust-lang#148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
rust-timer added a commit that referenced this pull request Mar 6, 2026
Rollup merge of #153495 - TaKO8Ki:fix-153236-offset-of-recovery, r=petrochenkov
Fix ICE in `offset_of!` error recovery
Fixes#153236.
`offset_of!` was changed in #148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
github-actionsBot pushed a commit to rust-lang/rust-analyzer that referenced this pull request Mar 9, 2026
…trochenkov
Fix ICE in `offset_of!` error recovery
Fixesrust-lang/rust#153236.
`offset_of!` was changed in rust-lang/rust#148151 to lower through THIR as a sum of calls to the `offset_of` intrinsic. In the error-recovery case, when no valid field indices are recorded, that lowering synthesized `0` as a `u32` even though the overall `offset_of!` expression has type `usize`.
On 64-bit targets, const-eval then tried to write a 4-byte immediate into an 8-byte destination, which caused the ICE.
makai410 pushed a commit to makai410/rustc_public that referenced this pull request Mar 19, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
makai410 pushed a commit to makai410/rustc_public that referenced this pull request Mar 19, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
makai410 pushed a commit to makai410/rustc_public that referenced this pull request Mar 27, 2026
…,saethlin
Replace Rvalue::NullaryOp by a variant in mir::Operand.
Based on rust-lang/rust#148151
This PR fully removes the MIR `Rvalue::NullaryOp`. After rust-lang/rust#148151, it was only useful for runtime checks like `ub_checks`, `contract_checks` and `overflow_checks`.
These are "runtime" checks, boolean constants that may only be `true` in codegen. It depends on a rustc flag passed to codegen, so we need to represent those flags cross-crate.
This PR replaces those runtime checks by special variants in MIR `ConstValue`. This allows code that expects constants to manipulate those as such, even if we may not always be able to evaluate them to actual scalars.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

disposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.finished-final-comment-periodThe final comment period is finished for this PR / Issue.I-lang-radarItems that are on lang's radar and will need eventual work or consideration.merged-by-borsThis PR was explicitly merged by bors.perf-regressionPerformance regression.perf-regression-triagedThe performance regression has been triaged.S-waiting-on-borsStatus: Waiting on bors to run and complete tests. Bors will change the label on completion.T-clippyRelevant to the Clippy team.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamT-libsRelevant to the library team, which will review and decide on the PR/issue.to-announceAnnounce this issue on triage meeting

Projects

None yet

15 participants

@cjgillot@rust-log-analyzer@rust-timer@bors@rustbot@BoxyUwU@WaffleLapkin@scottmcm@rust-rfcbot@traviscross@nikomatsakis@oli-obk@lqd@panstromek@RalfJung