Skip to content

Skipping borrowck because of trivial const#149468

Open
chenyukang wants to merge 1 commit intorust-lang:mainfrom
chenyukang:yukang-fix-ice-149278
Open

Skipping borrowck because of trivial const#149468
chenyukang wants to merge 1 commit intorust-lang:mainfrom
chenyukang:yukang-fix-ice-149278

Conversation

@chenyukang
Copy link
Copy Markdown
Member

@chenyukang chenyukang commented Nov 30, 2025

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
Copy link
Copy Markdown
Collaborator

rustbot commented May 1, 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

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.

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

Labels

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. 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.

7 participants