Rust: Improve handling of where clauses in type inference and path resolution#20177
Rust: Improve handling of where clauses in type inference and path resolution#20177hvitved merged 4 commits intogithub:mainfrom
Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR improves the handling of where clauses in Rust type inference and path resolution. It enhances CodeQL's ability to understand type bounds defined in where clauses, particularly for type parameters and traits, improving the accuracy of type inference and path resolution.
- Adds support for where clauses on type parameters and traits
- Improves type bound resolution in both direct and where clause contexts
- Updates test cases to cover more complex where clause scenarios
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/test/library-tests/type-inference/main.rs | Adds comprehensive test cases for where clause scenarios including trait bounds |
| rust/ql/test/library-tests/path-resolution/main.rs | Adds test for where clause with Self and type parameters |
| rust/ql/lib/codeql/rust/elements/internal/TypeParamImpl.qll | Implements getATypeBound() to collect bounds from direct and where clauses |
| rust/ql/lib/codeql/rust/elements/internal/TraitImpl.qll | Implements getATypeBound() for traits with where clause support |
| rust/ql/lib/codeql/rust/internal/TypeInference.qll | Updates to use new getATypeBound() methods |
| rust/ql/lib/codeql/rust/internal/PathResolution.qll | Simplifies bound path resolution using new methods |
| exists(WherePred wp | | ||
| wp = this.(TypeParamItemNode).getAWherePred() and | ||
| tbl = wp.getTypeBoundList() and | ||
| wp = any(WhereClause wc).getPredicate(i) |
There was a problem hiding this comment.
The logic in the second disjunct doesn't guarantee that the WherePred wp from getAWherePred() is the same as the one retrieved from getPredicate(i). This could lead to incorrect indexing. Consider explicitly linking the where predicate to its index in the where clause.
| wp = any(WhereClause wc).getPredicate(i) | |
| exists(WhereClause wc, WherePred wp | | |
| wp = wc.getPredicate(i) and | |
| wp = this.(TypeParamItemNode).getAWherePred() and | |
| tbl = wp.getTypeBoundList() |
| or | ||
| exists(WherePred wp | | ||
| wp = this.getWhereClause().getAPredicate() and | ||
| wp.getTypeRepr().(PathTypeRepr).getPath().getText() = "Self" and |
There was a problem hiding this comment.
The string comparison getText() = \"Self\" is fragile and may not handle all cases where Self is referenced. Consider using a more robust type-based comparison or path resolution to identify Self references.
| wp.getTypeRepr().(PathTypeRepr).getPath().getText() = "Self" and | |
| isSelfPath(wp.getTypeRepr().(PathTypeRepr).getPath()) and |
geoffw0
left a comment
There was a problem hiding this comment.
Thanks for doing this.
The analysis time regression seems to have mostly gone away with the rebase (which was expected). 👍
A rebased version of #20140.