Rust: Fix type inference for explicit dereference with * to the Deref trait#19820
Rust: Fix type inference for explicit dereference with * to the Deref trait#19820paldepind merged 7 commits intogithub:mainfrom
* to the Deref trait#19820Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR enhances the Rust type-inference engine to correctly handle explicit * dereferences via the Deref trait and to distinguish “certain” borrows, and it updates tests and internal QL logic accordingly.
- Add new dereference tests and update existing expected-results files to exercise explicit/implicit
Derefcalls. - Extend
CallExprBaseMatchingInputto carry acertainflag on borrows and adjustTypeInference.qllto honor explicit*in both argument and return positions. - Update internal QL modules (
OperationImpl.qll,CallImpl.qll) to propagate the new borrow flags and update test annotations for write‐formatted calls and dataflow.
Reviewed Changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| rust/ql/test/query-tests/security/.../PathResolutionConsistency.expected | Add expected write_fmt paths for explicit deref consistency tests. |
| rust/ql/test/library-tests/type-inference/main.rs | Introduce MyInt, ATrait, remove spurious annotations, register new dereference module. |
| rust/ql/test/library-tests/type-inference/dereference.rs | New file with explicit/implicit deref tests through Deref trait. |
| rust/ql/test/library-tests/type-inference/CONSISTENCY/... | Add consistency expectations for e1.deref(). |
| rust/ql/test/library-tests/dataflow/.../DataFlowStep.expected | Insert unwrap receiver entries in local dataflow steps. |
| rust/ql/test/library-tests/dataflow/global/viableCallable.expected | Add explicit * deref entries to viable callables. |
| rust/ql/test/library-tests/dataflow/global/main.rs | Update sink comment to include hasTaintFlow. |
| rust/ql/lib/codeql/rust/internal/TypeInference.qll | Track “certain” borrows in AccessPosition, adjust primitive handling of explicit *. |
| rust/ql/lib/codeql/rust/elements/internal/OperationImpl.qll | Change deref operator’s borrows count from 0 to 1. |
| rust/ql/lib/codeql/rust/elements/internal/CallImpl.qll | Expand implicitBorrowAt predicate to accept a certain flag. |
* to the Deref trait* to the Deref trait
c9943a2 to
6b2c125
Compare
|
DCA shows a decent increase in resolved method calls. Unfortunately |
|
The blowup on Two guesses as to why that might be: 1/ There is ambiguity in method calls where both In interest of getting this PR in a mergeable state before I go on vacation I've partially reverted the aforementioned commit such that we only resolve |
6ec844f to
bd2812c
Compare
This PR should fix type inference for explicit dereferencing.
&types. Previously types in the receiver position where always dereferenced before method lookup. Now for a&Twe lookup methods both on&Titself and onT.*in the desugaring of*.*edesugars to*Deref::deref(&e)and two handle the*after the call we need a special case in the return position of*.Callabstraction. For instance, sincea == bdesugars toEqual::eq(&a, &b)so we can be certain thataandbare borrowed. Making these certain sidesteps some issues with the way we infer implicit borrows. For instance for an argument type of the form&Twe will attempt to infer a dereference and never infer an implicit borrow. But thederefmethod on&Tis a actually a borrow from&Tto&&T.