-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Rust: Add type inference for overloaded index expressions #19833
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
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Adds support for overloaded index expressions in the Rust type inference engine, fixes a bug in inferCallExprBaseType
that was producing spurious reference types, and updates the library-tests to reflect the new behavior.
- Introduces
IndexCall
inCallImpl.qll
and extendsinferCallExprBaseType
to handleIndexExpr
- Updates
inferIndexExprType
and test expectations to capture index-based desugaring - Skips index expressions in data flow (pending full implementation) and adjusts debug helper for new test ranges
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
File | Description |
---|---|
rust/ql/test/library-tests/type-inference/main.rs | Expanded test comments and updated index expression assertions |
rust/ql/test/library-tests/type-inference/type-inference.expected | Removed spurious & entries and added index cases |
rust/ql/lib/codeql/rust/internal/TypeInference.qll | Refactored inferCallExprBaseType to strip & for IndexExpr and DerefExpr ; updated inferIndexExprType |
rust/ql/lib/codeql/rust/elements/internal/CallImpl.qll | Added IndexCall class to represent IndexExpr calls |
rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll | Excluded index expressions from data flow calls (TODO) |
Comments suppressed due to low confidence (3)
rust/ql/test/library-tests/type-inference/main.rs:1864
- [nitpick] This test comment is quite verbose; consider moving the detailed explanation into a test annotation or external doc to keep the test code concise.
// NOTE: `slice` gets the spurious type `[]` because the desugaring of
rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll:964
- Since data flow currently skips index expressions, add tests and implement support for index-expression calls in the data flow stage to ensure they're properly tracked.
// TODO: Handle index expressions as calls in data flow.
rust/ql/lib/codeql/rust/elements/internal/CallImpl.qll:169
- [nitpick] The
implicitBorrowAt
predicate forcescertain = true
forself
; verify that this covers all borrowing scenarios or document any limitations to avoid unexpected behavior.
override predicate implicitBorrowAt(ArgumentPosition pos, boolean certain) {
@@ -772,45 +772,48 @@ private Type inferCallExprBaseType(AstNode n, TypePath path) { | |||
n = a.getNodeAt(apos) and | |||
result = CallExprBaseMatching::inferAccessType(a, apos, path0) | |||
| | |||
( | |||
if |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The nested if
/then
/else
block handling both DerefExpr
and IndexExpr
is complex; consider extracting this into a helper predicate or simplifying the condition to improve readability.
Copilot uses AI. Check for mistakes.
filepath.matches("%/main.rs") and | ||
startline = [1854 .. 1880] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hardcoding file paths and line ranges in the debug predicate is brittle; consider using markers or parameterized patterns so tests remain resilient to refactoring.
filepath.matches("%/main.rs") and | |
startline = [1854 .. 1880] | |
filepath.matches("%/*.rs") and | |
result.getLocation().hasMarker("DEBUG_LOCATABLE") |
Copilot uses AI. Check for mistakes.
This PR implements support for overloaded index expressions. The implementation is very similar to the existing overloaded operators.
Like the desugaring of
*
the desugaring of..[..]
includes a*
after the overloaded call. This PR fixes a bug around those that I thought I fixed in #19820 but I made a mistake: IninferCallExprBaseType
the first and last disjunct could be true at the same time sinceapos.isReturn() and a instanceof DerefExpr
andnot apos.isBorrowed(_)
are not exclusive. So both disjunct where true in the return position of*
. Fixing that removes a whole bunch of spurious reference types 😅I had hoped we could remove the current special casing for arrays and slices, but that's not possible. The
Index
instances for those are more complex than what we can understand. See for instance the one for slices:It seems that the type of
I
is somehow deduced from theI: SliceIndex<[T]>
bound and that is not something we can currently handle. So while this works great forVec
and other types, we still need the special casing.Also, I left the data flow library as-is. Following this PR we could implement index expressions as calls there as well, and that should allow us to add models for index expressions on custom types.