Uh oh!
There was an error while loading. Please reload this page.
Rust: Infer argument types based on trait bounds on parameters - #21206
Conversation
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
b5bd829 to
29951e8Compared40ec21 to
c337f51Comparec337f51 to
888f87aCompareUh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
feb9b52 to
3ddf2f4CompareUh oh!
There was an error while loading. Please reload this page.
06f175b to
0fa4b85Compare823903e to
102deaaCompare102deaa to
d75c3d6Compare| } | ||
| } | ||
| mod regression6 { |
There was a problem hiding this comment.
Note that this example has actually nothing to do with the changes in this PR.
There was a problem hiding this comment.
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
| File | Description |
|---|---|
| shared/typeinference/codeql/typeinference/internal/TypeInference.qll | Extends constraint satisfaction plumbing used by multiple languages. |
| rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll | Enhances Rust inference for closures/dynamic calls and constraint-driven propagation. |
| rust/ql/lib/codeql/rust/internal/typeinference/TypeMention.qll | Adjusts associated-type resolution to the updated constraint API. |
| rust/ql/lib/codeql/rust/internal/typeinference/BlanketImplementation.qll | Updates blanket-impl constraint checks to the renamed constraint predicate. |
| rust/ql/test/library-tests/type-inference/main.rs | Adds a targeted test for inferring argument types via trait bounds on parameters. |
| rust/ql/test/library-tests/type-inference/closure.rs | Adds/updates closure inference tests (trait-bound driven and dynamic-call cases). |
| rust/ql/test/library-tests/type-inference/regressions.rs | Adds regressions documenting known spurious resolutions / sibling-impl limitations. |
| rust/ql/test/utils-tests/modelgenerator/option.rs | Updates model-generator expectations/documentation around a spurious model. |
| rust/ql/test/library-tests/type-inference/type-inference.expected | Regenerated expected results for expanded inference output. |
| rust/ql/test/library-tests/type-inference/CONSISTENCY/PathResolutionConsistency.expected | Regenerated consistency expectations after additional resolution. |
Comments suppressed due to low confidence (2)
shared/typeinference/codeql/typeinference/internal/TypeInference.qll:1212
- The
dissatisfiesConstraintdocstring still refers tosatisfiesConstraintType, but that predicate was renamed tosatisfiesConstraintabove. 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>`.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
d75c3d6 to
6dc98cfCompare
This PR adds support for inferring argument types based on trait bounds on parameters. Example (thanks to @paldepind):
In order to determine that the type of
visi64, we need to link theT: Container<i64>constraint inmy_getwith theimplblock.A similar thing happens for closures:
In order to infer that the type of
xin the closure isbool, we need to first matchTinapplyagainstboolvia thefalseargument, and then match the closure against the trait boundFn(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
Unknowntype, which allows for type information to flow into the parameter.Additional changes are required for closures that are invoked directly:
In order to infer that the type of
yin the closure isi32, we desugar the call toFn::call(g, (0i32))using theFntrait, which makes it an instance of theapplycase 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 Limitincreases significantly; one source of this is documented in theregression5test case, and instead of postponing this PR further, I suggest we look into fixing that follow-up.