Skip to content

Rust: Infer argument types based on trait bounds on parameters - #21206

Merged
hvitved merged 2 commits into
github:mainfrom
hvitved:rust/type-inference-closure-param-context-typed
Apr 7, 2026
Merged

Rust: Infer argument types based on trait bounds on parameters#21206
hvitved merged 2 commits into
github:mainfrom
hvitved:rust/type-inference-closure-param-context-typed

Conversation

@hvitved

@hvitvedhvitved commented Jan 22, 2026

Copy link
Copy Markdown
Contributor

This PR adds support for inferring argument types based on trait bounds on parameters. Example (thanks to @paldepind):

structGen<T>(T);traitContainer<T>{fnget_input(&self) -> T;}fnmy_get<T:Container<i64>>(c:&T) -> bool{ ...}impl<GT:Copy>Container<GT>forGen<GT>{ ... }fntest(){let v = Default::default();let g = Gen(v);my_get(&g);}

In order to determine that the type of v is i64, we need to link the T: Container<i64> constraint in my_get with the impl block.

A similar thing happens for closures:

fnapply<T,F:Fn(T) -> T>(f:F,a:T) -> T{f(a)}let f = |x| x;apply(f,false);

In order to infer that the type of x in the closure is bool, we need to first match T in apply against bool via the false argument, and then match the closure against the trait bound Fn(bool) -> bool.

The former example above is handled entirely by changes to the shared type inference library, where as the second example requires implicitly typed closure parameters to have the special Unknown type, which allows for type information to flow into the parameter.

Additional changes are required for closures that are invoked directly:

let g = |y| y;g(0i32);

In order to infer that the type of y in the closure is i32, we desugar the call to Fn::call(g, (0i32)) using the Fn trait, which makes it an instance of the apply case above. We then need to assign the argument list, (0i32), the 1-ary tuple type (i32).

DCA looks mostly good: As expected, we resolve more calls and consequently generate more alerts. The Nodes With Type At Length Limit increases significantly; one source of this is documented in the regression5 test case, and instead of postponing this PR further, I suggest we look into fixing that follow-up.

@github-actionsgithub-actionsBot added the Rust Pull requests that update Rust code label Jan 22, 2026
@hvitved
hvitvedforce-pushed the rust/type-inference-closure-param-context-typed branch from b5bd829 to 29951e8CompareJanuary 22, 2026 15:29
@hvitved
hvitvedforce-pushed the rust/type-inference-closure-param-context-typed branch 3 times, most recently from d40ec21 to c337f51CompareMarch 10, 2026 19:16
@hvitved
hvitvedforce-pushed the rust/type-inference-closure-param-context-typed branch from c337f51 to 888f87aCompareMarch 17, 2026 14:07
@hvitved
hvitvedforce-pushed the rust/type-inference-closure-param-context-typed branch 4 times, most recently from feb9b52 to 3ddf2f4CompareMarch 23, 2026 08:42
Comment threadshared/typeinference/codeql/typeinference/internal/TypeInference.qll Dismissed
@hvitved
hvitvedforce-pushed the rust/type-inference-closure-param-context-typed branch 4 times, most recently from 06f175b to 0fa4b85CompareMarch 25, 2026 09:22
@hvitvedhvitved changed the title Rust: Improve type inference for closuresRust: Infer argument types based on trait bounds on parametersMar 25, 2026
@hvitved
hvitvedforce-pushed the rust/type-inference-closure-param-context-typed branch 2 times, most recently from 823903e to 102deaaCompareMarch 26, 2026 15:59
@hvitved
hvitvedforce-pushed the rust/type-inference-closure-param-context-typed branch from 102deaa to d75c3d6CompareMarch 26, 2026 17:40
}
}

mod regression6 {

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Note that this example has actually nothing to do with the changes in this PR.

@hvitvedhvitved added the no-change-note-required This PR does not need a change note label Mar 27, 2026
@hvitved
hvitved marked this pull request as ready for review March 27, 2026 10:07
@hvitved
hvitved requested review from a team as code ownersMarch 27, 2026 10:07
CopilotAI review requested due to automatic review settings March 27, 2026 10:07

CopilotAI left a comment

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.

Pull request overview

Adds Rust type inference support for inferring argument/closure parameter types from trait bounds on parameters by linking function constraints to relevant impl blocks and modeling dynamically-invoked closures via Fn*::call_*-style desugaring.

Changes:

  • Extend shared type inference constraint satisfaction to propagate types through matching type parameters in constraints.
  • Update Rust type inference to better model closures (including dynamic call expressions and argument-list tuple typing) and allow type flow into implicitly-typed closure params.
  • Expand/update Rust type-inference and model-generator tests (including new regression coverage) and regenerate expected outputs.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Show a summary per file
FileDescription
shared/typeinference/codeql/typeinference/internal/TypeInference.qllExtends constraint satisfaction plumbing used by multiple languages.
rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qllEnhances Rust inference for closures/dynamic calls and constraint-driven propagation.
rust/ql/lib/codeql/rust/internal/typeinference/TypeMention.qllAdjusts associated-type resolution to the updated constraint API.
rust/ql/lib/codeql/rust/internal/typeinference/BlanketImplementation.qllUpdates blanket-impl constraint checks to the renamed constraint predicate.
rust/ql/test/library-tests/type-inference/main.rsAdds a targeted test for inferring argument types via trait bounds on parameters.
rust/ql/test/library-tests/type-inference/closure.rsAdds/updates closure inference tests (trait-bound driven and dynamic-call cases).
rust/ql/test/library-tests/type-inference/regressions.rsAdds regressions documenting known spurious resolutions / sibling-impl limitations.
rust/ql/test/utils-tests/modelgenerator/option.rsUpdates model-generator expectations/documentation around a spurious model.
rust/ql/test/library-tests/type-inference/type-inference.expectedRegenerated expected results for expanded inference output.
rust/ql/test/library-tests/type-inference/CONSISTENCY/PathResolutionConsistency.expectedRegenerated consistency expectations after additional resolution.
Comments suppressed due to low confidence (2)

shared/typeinference/codeql/typeinference/internal/TypeInference.qll:1212

  • The dissatisfiesConstraint docstring still refers to satisfiesConstraintType, but that predicate was renamed to satisfiesConstraint above. Update the comment to use the new predicate name so the documentation matches the code.
 * This is an approximation of `not satisfiesConstraintType(term, constraint, _, _)`,
* but defined without a negative occurrence of `satisfiesConstraintType`.
*
* Due to the approximation, both `satisfiesConstraintType` and `dissatisfiesConstraint`
* can hold for the same values. For example, if `term` has two different types `t1`

shared/typeinference/codeql/typeinference/internal/TypeInference.qll:1908

  • Typo in the comment: "allows us to to infer" has a duplicated "to". Please correct the wording.
 * That is, it allows us to to infer that the type of `y` is `MyThing<i32>`.

Comment threadshared/typeinference/codeql/typeinference/internal/TypeInference.qll Outdated
Comment threadrust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll Outdated
Comment threadrust/ql/test/utils-tests/modelgenerator/option.rs Outdated
@hvitved
hvitved requested a review from paldepindMarch 27, 2026 10:23
@hvitved
hvitvedforce-pushed the rust/type-inference-closure-param-context-typed branch from d75c3d6 to 6dc98cfCompareMarch 27, 2026 10:39

@paldepindpaldepind left a comment

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.

LGTM!

@hvitved
hvitved merged commit 7d184d0 into github:mainApr 7, 2026
134 of 136 checks passed
@hvitved
hvitved deleted the rust/type-inference-closure-param-context-typed branch April 7, 2026 07:17
@hvitvedhvitved mentioned this pull request Apr 14, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-change-note-requiredThis PR does not need a change noteRustPull requests that update Rust code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@hvitved@paldepind@github-advanced-security