Rust: Handle unqualified UseTrees in path resolution#20744
Rust: Handle unqualified UseTrees in path resolution#20744hvitved merged 3 commits intogithub:mainfrom
UseTrees in path resolution#20744Conversation
168b66d to
0bfc7cf
Compare
0bfc7cf to
50552da
Compare
There was a problem hiding this comment.
Pull Request Overview
This PR enhances path resolution for Rust use statements to support complex nested use tree patterns. Specifically, it handles cases like use {{{my::{{self as my_alias, *}}}}} where braces are deeply nested without intervening path segments.
- Introduces
getAUseTreeUseTree()to recursively traverse nested use trees that lack path segments - Updates path resolution logic to handle nested glob imports and aliases within brace groups
- Adds test coverage for the new nested use tree pattern with
my_alias::nested_f()
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| rust/ql/lib/codeql/rust/internal/PathResolution.qll | Core implementation adding getAUseTreeUseTree() and getAUseUseTree() helpers, and updating resolution logic to handle nested use trees without paths |
| rust/ql/test/library-tests/path-resolution/main.rs | Test case demonstrating nested braces with alias (use {{{my::{{self as my_alias, *}}}}}) and its usage |
| rust/ql/test/library-tests/path-resolution/path-resolution.expected | Updated expected output with new path resolutions and shifted line numbers |
| rust/ql/test/library-tests/path-resolution/CONSISTENCY/PathResolutionConsistency.expected | Updated line numbers for consistency checks |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
paldepind
left a comment
There was a problem hiding this comment.
LGTM! One question that might need addressing, but I've improved in case it's intended.
| exists(UseTree root | root = use.getUseTree() | | ||
| result = root |
There was a problem hiding this comment.
Is the overlap in the disjunction here intended? If not we could do if root.hasPath() then ... else ....
There was a problem hiding this comment.
Yeah, we may as well; this predicate is only called in one place, and it expects the result to have a path.
Previously, we assumed that use trees
{ ... }always had a qualifier, but this need not be the case.DCA looks good; we gain an additional 0.4 %-point call edges, although at the cost of a slowdown on
rust(which happens because we compute more data flow, for example the predicateAccessAfterLifetime::AccessAfterLifetimeFlow::Flow::Stage3::fwdFlowThroughgrows from3,626,391,847tuples to4,361,916,386tuples.).