-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Rust: Improve handling of where clauses in type inference and path resolution #20140
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
955ad03
to
ff4cb51
Compare
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.
Looks promising, I think I've spotted a couple of bugs (I could be wrong), and we need to review DCA when it's finished.
exists(WherePred wp | | ||
wp = this.getWhereClause().getAPredicate() and | ||
wp.getTypeRepr().(PathTypeRepr).getPath().getText() = "Self" and | ||
result = wp.getTypeBoundList().getBound(index - this.nrOfDirectTypeBounds()) |
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.
It appears to be legal to have two where predicates with Self
as the path, e.g.:
trait Subtrait
where
Self: Supertrait1,
Self: Supertrait2,
I think at the moment this will break your index numbering.
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.
You're right, that is legal and the implementation currently does not account for that.
ac4e9f9
to
6e34415
Compare
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
This PR improves handling of where
clauses in Rust type inference and path resolution by ensuring type bounds from where
clauses are properly considered alongside direct trait bounds. The changes add member predicates to traits and type parameters that aggregate bounds from all sources (direct bounds and where
clauses) and update path resolution and type inference to use these comprehensive bound collections.
Key Changes:
- Added
getATypeBound()
andgetTypeBound(int)
methods to traits and type parameters that include both direct bounds andwhere
clause bounds - Updated type inference and path resolution logic to use the new comprehensive bound predicates
- Added test cases covering
where
clause scenarios for trait bounds and supertrait relationships
Reviewed Changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 2 comments.
Show a summary per file
File | Description |
---|---|
rust/ql/lib/codeql/rust/elements/internal/TypeParamImpl.qll | Adds methods to collect type bounds from both direct bounds and where clauses for type parameters |
rust/ql/lib/codeql/rust/elements/internal/TraitImpl.qll | Adds methods to collect type bounds from both direct bounds and where clauses for traits |
rust/ql/lib/codeql/rust/internal/TypeInference.qll | Updates type inference to use new comprehensive bound collection methods |
rust/ql/lib/codeql/rust/internal/PathResolution.qll | Updates path resolution to use new comprehensive bound collection methods and simplifies bound checking logic |
rust/ql/test/library-tests/type-inference/main.rs | Adds test cases for where clause scenarios in type inference |
rust/ql/test/library-tests/path-resolution/main.rs | Adds test cases for where clause scenarios in path resolution |
wp = any(WhereClause wc).getPredicate(i) | ||
) | ||
) | ||
} |
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 getTypeBoundAt
method uses magic numbers and has unclear indexing logic. Consider adding documentation to explain the indexing scheme where i=0
represents direct bounds and i>0
represents where clause predicates, or use more descriptive parameter names like source
and boundIndex
.
Copilot uses AI. Check for mistakes.
or | ||
exists(WherePred wp | | ||
wp = this.getWhereClause().getAPredicate() and | ||
wp.getTypeRepr().(PathTypeRepr).getPath().getText() = "Self" and |
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 hardcoded string comparison getText() = \"Self\"
is fragile and may not handle all valid representations of Self
. Consider using a more robust method to identify Self
type references, such as checking the resolved type or using semantic analysis rather than text comparison.
wp.getTypeRepr().(PathTypeRepr).getPath().getText() = "Self" and | |
wp.getTypeRepr() instanceof SelfTypeRepr and |
Copilot uses AI. Check for mistakes.
wp = this.(TypeParamItemNode).getAWherePred() and | ||
tbl = wp.getTypeBoundList() and | ||
wp = any(WhereClause wc).getPredicate(i) | ||
) |
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.
I feel like this case should simplify to tbl = this.(TypeParamItemNode).getWherePred(i).getTypeBoundList()
(except that getWherePred(i)
doesn't exist there). I don't feel strongly if this is a pain to change.
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.
I'll give it a try. I had that predicate before, but ran into non-monotonic recursion. But it should be doable as long as the getWherePred(i)
is not actually used in path resolution itself.
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.
I agree that what you propose is a lot cleaner, but the getWherePred
on TypeParamItemNode
would have to use rank
and then we got non-monotonic recursion 😢
6e34415
to
69ca7ff
Compare
It turns out that we don't handle type bounds added by
where
clauses in all cases in path resolution and type inference.This PR improves the situration by adding member predicates to traits and type parameters that take all sources of bounds into account. These are then used in path resolution and type inference.