Skip to content

HIR "Eager Type Inference" / Expectations dev guide page - #2924

Open
fallible-algebra wants to merge 12 commits into
rust-lang:mainfrom
fallible-algebra:types-overhaul/hir-tyck
Open

HIR "Eager Type Inference" / Expectations dev guide page#2924
fallible-algebra wants to merge 12 commits into
rust-lang:mainfrom
fallible-algebra:types-overhaul/hir-tyck

Conversation

@fallible-algebra

@fallible-algebra fallible-algebra commented Jul 10, 2026

Copy link
Copy Markdown
Member

Page on "Eager Type Inference" / Expectations. Currently deep in drafts.

  • Is eager type inference the right phrase here? How do we need to represent it to the reader?
  • Answer why the following need to use eager type inference / expectations
    • closures (kinda done)
    • coercions
    • These do not reference expectations in terms of logic, but do pass around an expectations arg for diagnostics.
      • indexes
      • fields
      • methods
  • Establish if the whole bidirectional type system paper needs mentioning, and how to do that in a way that makes sense to people other than type theory sickos.
    • it's the source of "do some more type checking earlier"(?)
  • Post in the zulip

@fallible-algebra

Copy link
Copy Markdown
Member Author

@BoxyUwU

@BoxyUwU

BoxyUwU commented Jul 10, 2026

Copy link
Copy Markdown
Member

@fallible-algebra :)

@fallible-algebra
fallible-algebra requested a review from BoxyUwU July 24, 2026 10:03
@fallible-algebra fallible-algebra changed the title HIR Expectations dev guide page HIR "Eager Type Inference" / Expectations dev guide page Jul 29, 2026
@fallible-algebra
fallible-algebra marked this pull request as ready for review July 29, 2026 07:45
@rustbot rustbot added the S-waiting-on-review Status: this PR is waiting for a reviewer to verify its content label Jul 29, 2026
@rustbot

rustbot commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the PR. If you have write access, feel free to merge this PR if it does not need reviews. You can request a review using r? rustc-dev-guide or r? <username>.

@BoxyUwU BoxyUwU self-assigned this Jul 29, 2026

@BoxyUwU BoxyUwU left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Comment thread src/hir-typeck/expectations.md Outdated

In reality, we perform it (at least) twice: First, at eager evaluation points, and secondly "at the end" when those constraints have been collected.

`Expectations` are a piece of type inference state we maintain for the cases where we need to eagerly infer the types of expressions rather than leave them to the end. They allow us to "ask questions" of the form "hey, we're expecting this term to have this type, is this true?"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

i feel like its more of a we can ask "what are we expecting the type of this expression to be?"

Comment thread src/hir-typeck/eager-inference.md Outdated

If we didn't do eager type inference we would instead have closures whose types were filled with [inference variables](../appendix/glossary.md#inf-var).

This would be able to be solved in some situations, but because we do not have Higher-Ranked Inference Variables[^higher-ranked-inference] this would make the higher-ranked bounds for lifetimes that rust can have unusable without more annotation.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

the other reason we care about this is that if you have fn(?x) -> ?y as your closure signature then you can't do field accesses/method calls/etc on ?x which is a quite common thing to want to do

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think more generally we want to talk about how inferring higher ranked things is eager, and there are two main places this happens:

  • inferring higher ranked closure signatures
  • subtyping of higher ranked types

Comment thread src/hir-typeck/eager-inference.md Outdated

[Coercions](./coercions.md) can happen in many places. We check to see if a coercion can happen, and if it can we perform the coercion.

When we successfully find a coercion, we need to eagerly perform type inference/checking on it as future inference will require or benefit from this information to be known ahead of time.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't really know what this sentence is saying 🤔 it also feels a bit backwards to me because once we've "successfully found a coercion" then we've already done "eager type inference" because finding a coercion is the thing that cares about the current state of inference :3

Comment thread src/hir-typeck/eager-inference.md Outdated

When we successfully find a coercion, we need to eagerly perform type inference/checking on it as future inference will require or benefit from this information to be known ahead of time.

### Method calls, Fields, and Indexes.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

structuring this as

  • Closures
  • Coercions
  • Other stuff

feels slightly off to me as I feel like it places too much importance on the expectation vs non expectation distinction between cases of eager type inference

I feel like I would prefer just a flat list of all the places that are eager type inference spots

Comment thread src/hir-typeck/eager-inference.md Outdated

#### Methods

Maybe Not. Maybe just point to [method lookup](./method-lookup.md).

@BoxyUwU BoxyUwU Jul 29, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

definitely want to talk about methods :3

I think for each item (e.g. coercions, closures, fields, etc) here we want to cover:

  • Why it is an eager inference spot
  • How we handle it being an eager inference spot (we would probably talk about "hey we use expectations" here if we do)
  • Why we handle it the way we do

for methods this is probably:

  • method lookup is an eager inference spot because we need to look at the type of the receiver to determine what methods exist
  • we handle this by erroring if there are inference variables which prevent us from figuring out all the methods we might be able to call
  • we could move this into the trait solver but it'd complicate things quite a lot and hasn't really been necessary to do so (so mostly historical reasons).

Comment thread src/hir-typeck/eager-inference.md Outdated

? Method calls engage in Coercion and therefore need to engage in Eager Type Inference.

#### Fields?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

definitely want to talk about field accesses :3 its mostly the same reasoning as methods

Eager evaluation of the type of a term (type inference) is required at some specific points to either make later type inference more consistent or (in the case of higher-ranked bounds / Higher Ranked Lifetime bounds) make it even possible.

Eager type inference is when we do type inference earlier than we otherwise would. To do this, we bring in Expectations as an additional piece of context.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

general structural thing I think it would be nice to talk about like "the ways we can handle places that care about the current inference state" and sort of talk abstractly about:

  • we can defer it to arbitrary points during type inference (trait solving works like this)
  • we can eagerly error on inference variables
  • we can defer it to the end of typeck after everything has been inferred (array repeat expr checks do this)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

  • re: trait solver doing this: Does this behave differently between the current and next trait solver? And is that a relevant thing for me to bring up :p


Eager type inference is when we do type inference earlier than we otherwise would. To do this, we bring in Expectations as an additional piece of context.

### Closures and Higher-Ranked Variables

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

i kind of want to add trait solving to the list of "eager inference points" in that they're still part of the general "sometimes we do things which cares about the current inference state" its just that "trait" solving is how we handle that correctly instead of jankily

@jyn514

jyn514 commented Aug 17, 2026

Copy link
Copy Markdown
Member

@BoxyUwU @fallible-algebra 👋 what's the state of this? is it ok to merge as-is and improve in follow-ups?

@jyn514

jyn514 commented Aug 17, 2026

Copy link
Copy Markdown
Member

(note that CI is failing)

@fallible-algebra

Copy link
Copy Markdown
Member Author

Still working on it, and I'm away until next week.

@jyn514

jyn514 commented Aug 17, 2026

Copy link
Copy Markdown
Member

No worries at all :) thanks for the update

@jyn514 jyn514 added S-waiting-on-author Status: this PR is waiting for additional action by the OP and removed S-waiting-on-review Status: this PR is waiting for a reviewer to verify its content labels Aug 17, 2026
@rustbot rustbot added S-waiting-on-review Status: this PR is waiting for a reviewer to verify its content and removed S-waiting-on-author Status: this PR is waiting for additional action by the OP labels Aug 31, 2026
// Maybe later?
?a = Vec<?b>;
// And later still
?a = Vec<String>;

@BoxyUwU BoxyUwU Aug 31, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

in practice we won't ever record a second constraint for an inference variable. instead we'll zonk it and would have Vec<?b> eq Vec<String> which yields a ?b = String constraint

View changes since the review

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Straight up


TODO: Stub, relationship to eager inference is not well established.

TODO: Following are stubs, need to determine if these are relevant to bring up.

@BoxyUwU BoxyUwU Aug 31, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Comment on lines +74 to +99
Top-level functions, such as the following, have their types fully annotated at their definition site:

```rust
fn is_even(number: i32) -> bool {
number % 2 == 0
}
---
// We don't have to infer this, it's annotated.
is_even: fn(i32) -> bool
```

This makes inference at points where they're used relatively easy. We know it's a `fn(i32) -> bool`, so when we give it an `i32` we know the expression is a `bool`.

_Closures_ need to have type inference eagerly applied to them because they are functions that are rarely fully annotated:

```rust
let closure = |a, b| if a < b {vec![1, 2, 3]} else {vec![5, 6, 7]};
---
// Doesn't capture any information so it's a bare function pointer
// but we still don't know much about it.
closure: fn(?x, ?y) -> ?z
```

If we didn't do eager type inference we would instead have closures whose types were filled with [inference variables](../appendix/glossary.md#inf-var) (like the `?x, ?y, ?z` variables above).

Eagerly inferring the type of `closure` here serves a couple of purposes. Firstly, it's a decent heuristic that if we define a closure we'll use it later and having its type be known will mean a less intense inference solve. Having eagerly inferred the type of a closure lets us establish [Expectations](#expectations) that don't have inference variables in them.

@BoxyUwU BoxyUwU Aug 31, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

truke

### Constraints

This is the set of constraints that need to be solved. We collect these constraints as we move through the codebase being type checked.

@BoxyUwU BoxyUwU Aug 31, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Obligations

sometimes we look at the set of current obligations/goals/predicates the trait solver is required to prove.

View changes since the review

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

Labels

S-waiting-on-review Status: this PR is waiting for a reviewer to verify its content

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants