Skip to content

Clean up and speed up inference variable resolving code - #160913

Open
jdonszelmann wants to merge 8 commits into
rust-lang:mainfrom
jdonszelmann:cleanup-resolving
Open

Clean up and speed up inference variable resolving code#160913
jdonszelmann wants to merge 8 commits into
rust-lang:mainfrom
jdonszelmann:cleanup-resolving

Conversation

@jdonszelmann

@jdonszelmann jdonszelmann commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

View all comments

r? @lcnr

Clean up the resolve* family of functions in InferCtxt, renaming various functions to have more consistent and descriptive names. Adds a lot of documentation, and even wins some performance using the fact that shallow_resolve now returns root vids.

Reviewable commit by commit: some are large renames across the board, which are separated from the perf wins and small renames in other commits to hopefully make more sense.

Note

I've not used an LLM for any part of this PR, or any other PR I make. This includes any related work like research.

@rustbot

rustbot commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

changes to inspect_obligations.rs

cc @lcnr

changes to the core type system

cc @lcnr

Some changes occurred in need_type_info.rs

cc @lcnr

Some changes occurred to the core trait solver

cc @rust-lang/initiative-trait-system-refactor

changes to the core type system

cc @lcnr

@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. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver) labels Aug 11, 2026
@jdonszelmann

Copy link
Copy Markdown
Contributor Author

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Aug 11, 2026
@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Aug 11, 2026
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

match self.inner.borrow_mut().type_variables().probe(vid) {
TypeVariableValue::Known { value } => Ok(value),
match value {
TypeVariableValue::Known { value } => Ok(self.shallow_resolve_non_recursive(value)),

@jdonszelmann jdonszelmann Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

this method (and the one below) now also does the recursive resolving shallow_resolve already did. No tests change here.

View changes since the review

// Cold because the case in which a tyvar resolves to an intvar which resolves to a type is
// quite rare. It's way more common for `shallow_resolve_non_recursive` to return ty.
#[cold]
fn shallow_resolve_infer_non_recursive(&self, infer: InferTy, ty: Ty<'tcx>) -> Ty<'tcx> {

@jdonszelmann jdonszelmann Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

the non-recursive caase helps ~0.5% on local benchmarks. Not much, but still a bit.

View changes since the review

}

ty::Infer(ty::IntVar(vid)) => {
let nt = self.infcx.unwrap().opportunistic_resolve_int_var(vid);

@jdonszelmann jdonszelmann Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

renames all the opportunistic_* functions with simply shallow_resolve_*. I've done this in many places. I've added a lot of docs to all the resolve methods, which I think makes it super clear that resolving is always an opportunistic process that doesn't necessarily resolve all variables, simply because it can't always.

From the perspective of a new contributor, they'll see a resolve_* function for the first time, go to its docs, and learn that the purpose of all resolve_* methods is to opportunistically resolve variables.

Since the behavior is the same for all the resolve_* functions I think that will actually make things clearer than randomly calling some of them "opportunistic" even when the others are inherently also opportunistic.

View changes since the review

/// In cases where we do, this can aid performance.
#[inline(always)]
fn shallow_resolve_ty_var(&self, v: TyVid, ty: Ty<'tcx>) -> Ty<'tcx> {
fn shallow_resolve_ty_var_with_ty(&self, v: TyVid, ty: Option<Ty<'tcx>>) -> Ty<'tcx> {

@jdonszelmann jdonszelmann Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

By taking an Option here, we can merge more methods' implementations. Doing this has 0 performance overhead, #[inline(always)] makes sure the callsites that always call with Some get optimized properly.

View changes since the review

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

could we instead change this function to not take a ty and return and Option instead?

@rust-bors rust-bors Bot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 11, 2026
@rust-log-analyzer

This comment has been minimized.

@rust-bors

rust-bors Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

💔 Test for 7e8d4ec failed: CI. Failed job:

@rustbot rustbot added the T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output. label Aug 11, 2026
@jdonszelmann

Copy link
Copy Markdown
Contributor Author

@bors try (failed due to missing rustdoc changes now applied)

@rust-bors

rust-bors Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Unknown argument "(failed". Did you mean to use @bors jobs=<jobs>|parent=<parent>? Run @bors help or go to https://bors.rust-lang.org/help to see available commands.

@rust-log-analyzer

This comment has been minimized.

@panstromek

Copy link
Copy Markdown
Contributor

@bors try

@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Aug 11, 2026
@rust-bors

rust-bors Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: d881e22 (d881e228b79422918a125ef8385170091369309b)
Base parent: a04c7a0 (a04c7a037d59b6dedc9f921e84e391f13a257aa4)

@rust-timer

This comment has been minimized.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (d881e22): comparison URL.

Overall result: ✅ improvements - no action needed

Benchmarking means the PR may be perf-sensitive. It's automatically marked not fit for rolling up. Overriding is possible but disadvised: it risks changing compiler perf.

@bors rollup=never rustc-perf
@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.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-0.2% [-0.4%, -0.1%] 34
Improvements ✅
(secondary)
-0.5% [-1.2%, -0.2%] 39
All ❌✅ (primary) -0.2% [-0.4%, -0.1%] 34

Max RSS (memory usage)

Results (primary 5.7%, secondary -0.7%)

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

mean range count
Regressions ❌
(primary)
5.7% [5.1%, 6.3%] 2
Regressions ❌
(secondary)
0.6% [0.6%, 0.6%] 1
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-0.8% [-3.0%, -0.4%] 10
All ❌✅ (primary) 5.7% [5.1%, 6.3%] 2

Cycles

Results (primary 2.5%, secondary 0.4%)

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

mean range count
Regressions ❌
(primary)
2.5% [2.5%, 2.5%] 1
Regressions ❌
(secondary)
0.8% [0.4%, 1.5%] 8
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-0.9% [-1.6%, -0.5%] 3
All ❌✅ (primary) 2.5% [2.5%, 2.5%] 1

Binary size

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

Bootstrap: 463.191s -> 456.07s (-1.54%)
Artifact size: 396.43 MiB -> 396.43 MiB (-0.00%)

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Aug 11, 2026
@rust-bors

This comment has been minimized.

@jdonszelmann

Copy link
Copy Markdown
Contributor Author

that seems worth it :3

@rustbot

rustbot commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

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.

@jdonszelmann

Copy link
Copy Markdown
Contributor Author

@rustbot review

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Aug 12, 2026
@lcnr lcnr changed the title Clean up and speed up resolving code Clean up and speed up inference variable resolving code Aug 12, 2026
Comment thread compiler/rustc_infer/src/infer/mod.rs
Comment thread compiler/rustc_infer/src/infer/mod.rs
Ty::new_int_var(self.tcx, inner.int_unification_table().find(vid))
}
}
pub fn shallow_resolve_int_var(&self, vid: ty::IntVid) -> Ty<'tcx> {

@lcnr lcnr Aug 12, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

if we return None if the inner function doesn't make progress, could we always be explicit about reconstructing the type in the caller to make it explicit where we (likely unnecessarily) do so?

View changes since the review

.borrow_mut()
.unwrap_region_constraints()
.opportunistic_resolve_var(canonicalizer.tcx, vid);
.shallow_resolve_region_var(canonicalizer.tcx, vid);

@lcnr lcnr Aug 12, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

we don't reuse r here if the root doesn't change 🤔 feels like doing so would be good for perf 🤔

View changes since the review

@lcnr

lcnr commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

so we have the following now

  • shallow_resolve_X now
  • deep_resolve_non_region_vars
  • eagerly_resolve_vars deep resolve which does resolve region vars
  • fully_resolve deep resolve which uses the region graph instead of only the unification tables

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. T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output. 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.

6 participants