Content-Length: 465800 | pFad | http://github.com/github/codeql/pull/20020

AA Rust: Type inference for pattern matching by hvitved · Pull Request #20020 · github/codeql · GitHub
Skip to content

Rust: Type inference for pattern matching #20020

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

Merged
merged 5 commits into from
Jul 11, 2025

Conversation

hvitved
Copy link
Contributor

@hvitved hvitved commented Jul 10, 2025

This PR implements type inference support for pattern matching. For example, we are now able to infer that x has type i32 in

if let Some(x) = Some(0) { ... }

We also fix an existing bug where we would not distinguish let x = ... from let ref x = ..., as well as handling type arguments supplied to variants, e.g. Option::Some::<i32>(Default::default) (#19847 follow-up).

Commit-by-commit review is encouraged.

DCA looks great; call resolution rate up by 2.5 percentage points, no significant performance regressions.

@github-actions github-actions bot added the Rust Pull requests that update Rust code label Jul 10, 2025
@hvitved hvitved force-pushed the rust/type-inference-pattern-matching branch from 97cf8fe to 78a6968 Compare July 10, 2025 19:27
class AccessPosition = DeclarationPosition;

class Access extends StructPat {
Type getTypeArgument(TypeArgumentPosition apos, TypePath path) { none() }
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this none()?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since #19847, getTypeArgument is only used for type arguments supplied to functions, not to their defining type, i.e. it is used for foo::<i32>(...) but not for Bar::<i32>::foo(...).

Since explicit type arguments in pattern matching corresponds to the latter, it is none() here, and instead handled in getInferredType below. I'll add some tests for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Adding test, of course, revealed some corner cases that were not handled, I'm gonna do that on this PR as well.

let x = value1; // $ MISSING: type=x:i32
let y = value2; // $ MISSING: type=y:bool
let x = value1; // $ type=x:i32
let y = value2; // $ type=y:bool
();
}

let my_tuple_struct = MyTupleStruct(42, false);
if let MyTupleStruct(value1, value2) = my_tuple_struct {
Copy link
Contributor

Choose a reason for hiding this comment

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

There are a bunch of other pattern types, lets add some tests for those too. No need to fully implement them all, having some MISSING annotations is fine.

Let's also add some more tests with:

  • some more deeply nested patterns
  • use of ref keyword: let Some(ref x) = ...
  • a union type

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea with nested patterns and ref; we don't handle union types yet, so I'll not add those here.

Copy link
Contributor

Choose a reason for hiding this comment

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

I just asked co-pilot to generate sample test code that covers all the cases for Pat from the ungrammar. This is the result hvitved#8 .

I had to drop the sample code about "const block patterns" because that feature has been removed from Rust.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Could we perhaps add those tests follow-up?

Copy link
Contributor

Choose a reason for hiding this comment

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

Sure, just wanted to let you know, so you wouldn't write them manually.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks :-)

Copy link
Contributor

@aibaars aibaars left a comment

Choose a reason for hiding this comment

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

Very nice! Are you planning to add pattern matching on tuple types as well? Or is that best left as a follow-up?

@hvitved hvitved force-pushed the rust/type-inference-pattern-matching branch from 78a6968 to 29dc76c Compare July 11, 2025 06:36
@hvitved
Copy link
Contributor Author

hvitved commented Jul 11, 2025

Very nice! Are you planning to add pattern matching on tuple types as well? Or is that best left as a follow-up?

I was thinking we could do that once we even support tuple types.

@hvitved hvitved force-pushed the rust/type-inference-pattern-matching branch from 29dc76c to 4ab2977 Compare July 11, 2025 08:38
aibaars
aibaars previously approved these changes Jul 11, 2025
Copy link
Contributor

@aibaars aibaars left a comment

Choose a reason for hiding this comment

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

LGTM

geoffw0
geoffw0 previously approved these changes Jul 11, 2025
Copy link
Contributor

@geoffw0 geoffw0 left a comment

Choose a reason for hiding this comment

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

LGTM as well.

I also looked at the DCA run, it shows a pretty substantial improvement on missing call targets, and some new results for rust/access-after-lifetime-ended (probably as we're identifying more sinks correctly). 👍

@hvitved hvitved dismissed stale reviews from geoffw0 and aibaars via edf6c7f July 11, 2025 10:45
@hvitved hvitved marked this pull request as ready for review July 11, 2025 11:08
@hvitved hvitved requested a review from a team as a code owner July 11, 2025 11:08
@hvitved hvitved merged commit 0a18db8 into github:main Jul 11, 2025
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Rust Pull requests that update Rust code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/github/codeql/pull/20020

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy