Skip to content

Rust: Add SatisfiesConstraintInput module in shared type inference #19829

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

paldepind
Copy link
Contributor

@paldepind paldepind commented Jun 20, 2025

This PR refactors the shared type inference library, it untangles the logic for figuring out whether a type tree implements a trait, such that we can expose that logic from the shared library. This is done by a new module called SatisfiesConstraintInput. This module can be used to figure out if and how the type of an AST nodes (or more generally any HasTypeTree) implements a given trait.


I believe we can use this module for quite a few things in Rust:

  • In for loops like for i of e { ... } where the type of i depends on how e implements the IntoIterator trait.
  • Method resolution for trait implementations on type parameters. For an implementation like
    impl<T: Trait1> Trait2 for T { fn a_method(...) ... }
    and a method call like
    receiver.a_method()
    we need to figure out if and how receiver implements Trait1.
  • For implicit dereferences through the Deref trait we need to figure out whether the potentially deref'ed value implements Deref.
  • If we want to handle calls to closures we must figure out if the target of a call implements Fn, FnOnce, etc.
  • For foo.await we must know if foo implements Future.

To show that this works, the last item is carried out in this PR (results in a simplification compared to the current implementation that uses the Matching module). for loops should also be pretty easy, but I didn't want to create conflicts with #19754.


Below is an explanation of how this module can be used in the case of the iterator in a for loop:

First we create a class that satisfies the HasTypeTree signature and which includes nodes that occur as the iterator in a for loop:

final class ForLoopTarget extends Expr {
  ForLoopTarget() { this = any(ForExpr fe).getIterable() }

  Type getTypeAt(TypePath path) { result = inferType(this, path) }
}

Then we create a modules that satisfies the SatisfiesConstraint signature. The signature only contains a predicate that for every type tree gives the traits that we're interested in that type tree satisfying:

private module SatisfiesConstraintInput implements SatisfiesConstraintSig<ForLoopTarget> {
  predicate relevantConstraint(ForLoopTarget flt, Type constraint) {
    exists(flt) and
    constraint.(TraitType).getTrait() instanceof IntoIteratorTrait
  }
}

Now we can instantiate the module and get the type of e as an implementation of the IntoIterator trait:

SatisfiesConstraint<ForLoopTarget, SatisfiesConstraintInput>::satisfiesConstraintTypeMention(flt,
    constraint, path, t)

This should make it possible to type for loops over any iterator type, which we could do following #19754.

@github-actions github-actions bot added the Rust Pull requests that update Rust code label Jun 20, 2025
@paldepind
Copy link
Contributor Author

CI failure is unrelated.

@paldepind paldepind force-pushed the rust/type-tree-constraint branch from aad400c to 266d5c6 Compare June 20, 2025 12:52
@paldepind paldepind marked this pull request as ready for review June 20, 2025 13:14
@Copilot Copilot AI review requested due to automatic review settings June 20, 2025 13:14
@paldepind paldepind requested a review from a team as a code owner June 20, 2025 13:14
Copilot

This comment was marked as off-topic.

@paldepind paldepind added the no-change-note-required This PR does not need a change note label Jun 20, 2025
@paldepind paldepind changed the title Rust: Expose SatisfiesConstraintInput in shared type inference Rust: Add SatisfiesConstraintInput module in shared type inference Jun 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
no-change-note-required This PR does not need a change note Rust Pull requests that update Rust code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant