Skip to content

Skipping borrowck because of trivial const#149468

Merged
rust-bors[bot] merged 1 commit intorust-lang:mainfrom
chenyukang:yukang-fix-ice-149278
May 7, 2026
Merged

Skipping borrowck because of trivial const#149468
rust-bors[bot] merged 1 commit intorust-lang:mainfrom
chenyukang:yukang-fix-ice-149278

Conversation

@chenyukang
Copy link
Copy Markdown
Member

@chenyukang chenyukang commented Nov 30, 2025

View all comments

r? @saethlin

the assertion is added in PR: #148040

I think we also need to skip trvial const in mir_borrowck.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Nov 30, 2025
@saethlin
Copy link
Copy Markdown
Member

saethlin commented Nov 30, 2025

I'm okay with this change, but I would like @lcnr's opinion on whether this sort of whack-a-mole approach is sustainable. (I don't want to have an ever-growing number of is_trivial_const checks that eventually upsets the types team)

@lcnr
Copy link
Copy Markdown
Contributor

lcnr commented Dec 1, 2025

What are the requirements for something to be a trivial const, are they written down somewhere? E.g. is const FOO: Tait = 1; a trivial const?

I personally feel quite... unhappy about this change. @BoxyUwU has been changing lowering of some constants for const generics to never actually get lowered to HIR expression but instead eagerly convert them into type system constants. That means we don't have a body for them and don't even try to call any of the typeck/mir_borrowck queries.

Having both of these impls seems fairly bad to me. It seems like ideally there should only be one way to get constants without corresponding MIR body.

I don't have the time to engage with that area myself right now :x I think we should not have both systems and ideally you'd chat with @BoxyUwU to figure out whether you can unify the two somehow

@saethlin
Copy link
Copy Markdown
Member

saethlin commented Dec 1, 2025

Well, that's why I asked.

I agree that Boxy's approach seems better.

If you wanted to know the semantics I implemented, they're all in here: https://github.com/rust-lang/rust/blob/2fb805367dd3012ce5c50865d03c86e70bf10f0f/compiler/rustc_mir_transform/src/trivial_const.rs

@lcnr
Copy link
Copy Markdown
Contributor

lcnr commented Dec 1, 2025

E.g. is const FOO: Tait = 1; a trivial const?

so this ends up as a trivial const? we never check that the type of the const is not an opaque. This code would start to fail/misbehave with this PR because MIR borrowck doesn't return the defining use anymore, would it not (at least with the new solver)?

@BoxyUwU
Copy link
Copy Markdown
Member

BoxyUwU commented Dec 3, 2025

Would definitely be interested in chatting about things here 🤔 @saethlin if you wanna reach out on zulip at some point that'd be cool :)

@apiraino
Copy link
Copy Markdown
Contributor

apiraino commented Feb 5, 2026

Checking for progress. Did a conversation happen about this? What's the current status?

thanks for an update :)

@lcnr
Copy link
Copy Markdown
Contributor

lcnr commented Feb 10, 2026

E.g. is const FOO: Tait = 1; a trivial const?

so this ends up as a trivial const? we never check that the type of the const is not an opaque. This code would start to fail/misbehave with this PR because MIR borrowck doesn't return the defining use anymore, would it not (at least with the new solver)?

is this an issue with this PR?

@chenyukang chenyukang force-pushed the yukang-fix-ice-149278 branch from 31c3857 to ec79af9 Compare February 11, 2026 01:53
@rustbot

This comment has been minimized.

@chenyukang
Copy link
Copy Markdown
Member Author

E.g. is const FOO: Tait = 1; a trivial const?

so this ends up as a trivial const? we never check that the type of the const is not an opaque. This code would start to fail/misbehave with this PR because MIR borrowck doesn't return the defining use anymore, would it not (at least with the new solver)?

is this an issue with this PR?

I rebased the code with latest upstream.

For const FOO: Tait = 1; — the trivial_const function already has a body.has_opaque_types() check that returns None early, so it's not a trivial const and the borrowck will run.

@chenyukang
Copy link
Copy Markdown
Member Author

Checking for progress. Did a conversation happen about this? What's the current status?

thanks for an update :)

I'm not sure about the status of lowering-level approach @BoxyUwU is working on, let's @BoxyUwU decide whether to close this PR?

@lcnr
Copy link
Copy Markdown
Contributor

lcnr commented Feb 12, 2026

r? lcnr

This optimization is unfortunately hard to unify with the work by Boxy. Given that we bail if there are any opaques,

For const FOO: Tait = 1; — the trivial_const function already has a body.has_opaque_types() check that returns None early, so it's not a trivial const and the borrowck will run.

I would expect that the current check isn't sufficient with the new solver here? Because in the new solver we actually normalize Tait to its underlying type during writeback, so the body doesn't reference the opaque itself, only when usng the fn_sig in borrowck do we actually constrain it.

Can you test it with -Znext-solver?

@rustbot rustbot assigned lcnr and unassigned saethlin Feb 12, 2026
@theemathas
Copy link
Copy Markdown
Contributor

theemathas commented Feb 13, 2026

This has a borrowck error on nightly. Is it occurring in a trivial const?

struct Thing<'a>(&'a ());
impl<'a: 'static> Thing<'a> {
    const X: i32 = 1;
}
impl<'a> Thing<'a> {
    const C: i32 = Thing::<'a>::X;
}

@saethlin
Copy link
Copy Markdown
Member

This optimization is unfortunately hard to unify with the work by Boxy.

I agree. I started looking into what Boxy is doing, and I found it rather difficult to connect that logic to the optimization I was looking to implement.

@lcnr If you think the existing trivial_const logic is unsustainable, I trust your judgement and have no objection to reverting it.

@lcnr
Copy link
Copy Markdown
Contributor

lcnr commented Apr 10, 2026

Sorry, marked this as read without seeing your question. I do think this optimization has a very high complexity cost. Having a new kind of body and making sure it's always handled correctly feels brittle to me. I would prefer removing that change :/ I don't remember the perf improvements we get from this and maybe they justify the added complexity 🤔

I would expect that the current check isn't sufficient with the new solver here? Because in the new solver we actually normalize Tait to its underlying type during writeback, so the body doesn't reference the opaque itself, only when usng the fn_sig in borrowck do we actually constrain it.

Can you test it with -Znext-solver?

@saethlin
Copy link
Copy Markdown
Member

The post-merge perf run is here: #148040 (comment)

I think some level of complexity is warranted.

@lcnr
Copy link
Copy Markdown
Contributor

lcnr commented Apr 30, 2026

yeah :/ i feel conflicted here, which is why I am kind of avoiding this PR 😅

For const FOO: Tait = 1; — the trivial_const function already has a body.has_opaque_types() check that returns None early, so it's not a trivial const and the borrowck will run.

I would expect that the current check isn't sufficient with the new solver here? Because in the new solver we actually normalize Tait to its underlying type during writeback, so the body doesn't reference the opaque itself, only when usng the fn_sig in borrowck do we actually constrain it.

Can you test it with -Znext-solver?

we can fix this by instead checking whether the constant is the defining scope of any opaque. I guess I am fine with this PR if we add such a test and make sure it works

@chenyukang chenyukang force-pushed the yukang-fix-ice-149278 branch from ec79af9 to 3c65785 Compare May 1, 2026 14:51
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented May 1, 2026

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

@rustbot rustbot added the WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver) label May 1, 2026
@rustbot

This comment has been minimized.

@chenyukang
Copy link
Copy Markdown
Member Author

yeah :/ i feel conflicted here, which is why I am kind of avoiding this PR 😅

For const FOO: Tait = 1; — the trivial_const function already has a body.has_opaque_types() check that returns None early, so it's not a trivial const and the borrowck will run.

I would expect that the current check isn't sufficient with the new solver here? Because in the new solver we actually normalize Tait to its underlying type during writeback, so the body doesn't reference the opaque itself, only when usng the fn_sig in borrowck do we actually constrain it.
Can you test it with -Znext-solver?

we can fix this by instead checking whether the constant is the defining scope of any opaque. I guess I am fine with this PR if we add such a test and make sure it works

I changed the trivial-const check so that we do not treat a const as trivial if it is the defining scope of any opaque (tcx.opaque_types_defined_by(def)).

I also added a -Znext-solver regression test for this scenario. It fails without the new check and passes with it.

Comment on lines +1 to +2
//@ compile-flags: -Znext-solver
//@ check-pass
Copy link
Copy Markdown
Contributor

@lcnr lcnr May 7, 2026

Choose a reason for hiding this comment

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

pls also add an old solver revision here

r=me after

View changes since the review

@chenyukang chenyukang force-pushed the yukang-fix-ice-149278 branch from 3c65785 to 1ee3899 Compare May 7, 2026 14:16
@chenyukang chenyukang force-pushed the yukang-fix-ice-149278 branch from 1ee3899 to 8e1f263 Compare May 7, 2026 14:20
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented May 7, 2026

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@chenyukang
Copy link
Copy Markdown
Member Author

@bors r=lcnr

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented May 7, 2026

📌 Commit 8e1f263 has been approved by lcnr

It is now in the queue for this repository.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 7, 2026
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request May 7, 2026
…r=lcnr

Skipping borrowck because of trivial const

r? @saethlin

the [assertion](https://github.com/chenyukang/rust/blob/31c38576a4cf1a0864af536f62d11f829db1c7c8/compiler/rustc_mir_transform/src/lib.rs#L424) is added in PR: rust-lang#148040

I think we also need to skip trvial const in `mir_borrowck`.
rust-bors Bot pushed a commit that referenced this pull request May 7, 2026
…uwer

Rollup of 4 pull requests

Successful merges:

 - #149468 (Skipping borrowck because of trivial const)
 - #152487 (core: drop unmapped ZSTs in array `map`)
 - #153759 (Add a suite of ChunkedBitSet union/subtract/intersect test scenarios)
 - #156198 (Add `sync` option to `-Z threads` to force synchronization on one thread)
@rust-bors

This comment has been minimized.

@rust-bors rust-bors Bot added merged-by-bors This PR was explicitly merged by bors. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels May 7, 2026
@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented May 7, 2026

☀️ Test successful - CI
Approved by: lcnr
Duration: 3h 16m 30s
Pushing f964de4 to main...

@rust-bors rust-bors Bot merged commit f964de4 into rust-lang:main May 7, 2026
12 checks passed
@rustbot rustbot added this to the 1.97.0 milestone May 7, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 7, 2026

What is this? This is an experimental post-merge analysis report that shows differences in test outcomes between the merged PR and its parent PR.

Comparing ffccab6 (parent) -> f964de4 (this PR)

Test differences

Show 9 test diffs

Stage 1

  • [ui] tests/ui/traits/const-traits/trivial-const-ice-149278.rs: [missing] -> pass (J1)
  • [ui] tests/ui/traits/next-solver/opaques/trivial-const-defines-opaque.rs#current: [missing] -> pass (J1)
  • [ui] tests/ui/traits/next-solver/opaques/trivial-const-defines-opaque.rs#next: [missing] -> pass (J1)

Stage 2

  • [ui] tests/ui/traits/const-traits/trivial-const-ice-149278.rs: [missing] -> pass (J0)
  • [ui] tests/ui/traits/next-solver/opaques/trivial-const-defines-opaque.rs#current: [missing] -> pass (J0)
  • [ui] tests/ui/traits/next-solver/opaques/trivial-const-defines-opaque.rs#next: [missing] -> pass (J0)

Additionally, 3 doctest diffs were found. These are ignored, as they are noisy.

Job group index

Test dashboard

Run

cargo run --manifest-path src/ci/citool/Cargo.toml -- \
    test-dashboard f964de49bcb561e5c6c725bb37201e11d852daf0 --output-dir test-dashboard

And then open test-dashboard/index.html in your browser to see an overview of all executed tests.

Job duration changes

  1. dist-various-1: 57m 36s -> 1h 13m (+27.6%)
  2. dist-x86_64-apple: 2h 18m -> 2h 56m (+27.2%)
  3. dist-powerpc64le-linux-musl: 1h 19m -> 1h 34m (+18.9%)
  4. dist-sparcv9-solaris: 1h 33m -> 1h 15m (-18.7%)
  5. optional-x86_64-gnu-parallel-frontend: 2h 44m -> 2h 13m (-18.5%)
  6. pr-check-1: 34m 45s -> 28m 26s (-18.2%)
  7. dist-x86_64-msvc-alt: 2h 33m -> 2h 11m (-14.5%)
  8. x86_64-rust-for-linux: 56m 15s -> 48m 40s (-13.5%)
  9. pr-check-2: 45m 26s -> 39m 25s (-13.2%)
  10. x86_64-gnu-nopt: 2h 32m -> 2h 12m (-13.2%)
How to interpret the job duration changes?

Job durations can vary a lot, based on the actual runner instance
that executed the job, system noise, invalidated caches, etc. The table above is provided
mostly for t-infra members, for simpler debugging of potential CI slow-downs.

@rust-timer
Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (f964de4): comparison URL.

Overall result: ✅ improvements - no action needed

@rustbot label: -perf-regression

Instruction count

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

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-0.3% [-0.3%, -0.3%] 1
All ❌✅ (primary) - - 0

Max RSS (memory usage)

Results (primary 3.3%, secondary -0.3%)

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

mean range count
Regressions ❌
(primary)
3.3% [1.7%, 5.3%] 4
Regressions ❌
(secondary)
1.2% [0.5%, 2.0%] 2
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-3.4% [-3.4%, -3.4%] 1
All ❌✅ (primary) 3.3% [1.7%, 5.3%] 4

Cycles

Results (secondary 0.2%)

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

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
1.0% [0.5%, 2.3%] 4
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-0.8% [-1.1%, -0.5%] 3
All ❌✅ (primary) - - 0

Binary size

This perf run didn't have relevant results for this metric.

Bootstrap: 497.124s -> 508.875s (2.36%)
Artifact size: 395.05 MiB -> 395.04 MiB (-0.00%)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merged-by-bors This PR was explicitly merged by bors. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants