| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
There was a problem hiding this comment.
This PR enhances the type inference module by adding a transitive parameter to control whether constraints should be transitively propagated through trait bounds. The key change distinguishes between impl blocks (non-transitive) and trait bounds (transitive), fixing spurious type inference results.
Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file| File | Description |
|---|---|
| shared/typeinference/codeql/typeinference/internal/TypeInference.qll | Added transitive parameter to conditionSatisfiesConstraint predicate signature and updated all call sites |
| rust/ql/lib/codeql/rust/internal/TypeInference.qll | Set transitive = false for impl blocks and transitive = true for trait bounds, supertraits, and related constraints |
| rust/ql/lib/codeql/rust/internal/typeinference/FunctionType.qll | Refactored associated function type resolution to track parent traits, updated parameter binding sets, and corrected documentation table |
| rust/ql/test/library-tests/type-inference/main.rs | Removed SPURIOUS markers from test expectations that are now correctly resolved |
| rust/ql/test/library-tests/type-inference/type-inference.expected | Removed spurious reference type inferences for loop variables |
| rust/ql/test/library-tests/type-inference/CONSISTENCY/PathResolutionConsistency.expected | Removed entries for calls that no longer have multiple targets |
| rust/ql/test/library-tests/dataflow/sources/stdin/CONSISTENCY/PathResolutionConsistency.expected | Removed spurious multiple call target entry |
| rust/ql/test/library-tests/dataflow/models/CONSISTENCY/PathResolutionConsistency.expected | Removed spurious multiple call target entry |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Sorry, something went wrong.
| * free in `condition` and `constraint`, | ||
| * - and for every instantiation of the type parameters from `abs` the | ||
| * resulting `condition` satisifies the constraint given by `constraint`. | ||
| * - `transitive` corresponds to wether any further constraints satisifed |
There was a problem hiding this comment.
Corrected spelling of 'wether' to 'whether' and 'satisifed' to 'satisfied'.
| * - `transitive` corresponds to wether any further constraints satisifed | |
| * - `transitive` corresponds to whether any further constraints satisfied |
Sorry, something went wrong.
| * `m4` | `impl T2 for X` | `self` | `X` | ||
| * `m5` | `impl T2 for X` | `self` | `X` |
There was a problem hiding this comment.
The documentation table references functions m4 and m5 that don't exist in the example code. Based on the example, line 153 should reference m1 (from the impl T1 for X block) and line 154 should reference m3 (from the impl T2 for X block).
| * `m4` | `impl T2 for X` | `self` | `X` | |
| * `m5` | `impl T2 for X` | `self` | `X` | |
| * `m1` | `impl T1 for X` | `self` | `X` | |
| * `m3` | `impl T2 for X` | `self` | `X` |
Sorry, something went wrong.
| S5(0i32).m(); // $ target=<S5<i32>_as_MyTrait1>::m $ SPURIOUS: target=MyTrait1::m | ||
| S5::m(&S5(0i32)); // $ target=<S5<i32>_as_MyTrait1>::m $ SPURIOUS: target=MyTrait1::m | ||
| S5(0i32).m(); // $ target=<S5<i32>_as_MyTrait1>::m | ||
| S5::m(&S5(0i32)); // $ target=<S5<i32>_as_MyTrait1>::m |
There was a problem hiding this comment.
I'm not sure why the second test did not get fixed, especially since it looks a lot like the fourth test. I'm guessing something more might be needed here, as the AssocFunctionType looked fine when I eval'ed it.
Sorry, something went wrong.
There was a problem hiding this comment.
I think I have something to address this follow-up.
Sorry, something went wrong.
There was a problem hiding this comment.
Changes on DCA and existing tests LGTM.
Sorry, something went wrong.
| println!("{:?}", S3::m(&w, x)); // $ target=S3<T>::m | ||
|
|
||
| S4.m(); // $ target=<S4_as_MyTrait1>::m $ SPURIOUS: target=MyTrait1::m | ||
| S4.m(); // $ target=<S4_as_MyTrait1>::m |
There was a problem hiding this comment.
Though this calls the version of m in impl MyTrait1 for S4, if that did not override m I believe Rust would in fact fall back to the implementation in MyTrait1. It's also possible that a function in a direct Impl S4 could be called here. I'm seeking reassurance that we will get the right call targets in expanded cases such as these:
trait MyTrait1 {
// MyTrait1::m
fn m(&self) {}
// MyTrait1::n
fn n(&self) {}
// MyTrait1::o
fn o(&self) {}
}
#[derive(Debug)]
struct S4;
impl MyTrait1 for S4 {
// <S4_as_MyTrait1>::m
fn m(&self) {}
// <S4_as_MyTrait1>::n
fn n(&self) {}
}
impl S4 {
// S4::n
fn n(&self) {}
}
S4.m(); // $ target=<S4_as_MyTrait1>::m
S4.n(); // $ target=S4::n
S4.o(); // $ target=MyTrait1::o
Sorry, something went wrong.
There was a problem hiding this comment.
LGTM, just one nit comment.
Sorry, something went wrong.
| S5(0i32).m(); // $ target=<S5<i32>_as_MyTrait1>::m $ SPURIOUS: target=MyTrait1::m | ||
| S5::m(&S5(0i32)); // $ target=<S5<i32>_as_MyTrait1>::m $ SPURIOUS: target=MyTrait1::m | ||
| S5(0i32).m(); // $ target=<S5<i32>_as_MyTrait1>::m | ||
| S5::m(&S5(0i32)); // $ target=<S5<i32>_as_MyTrait1>::m |
There was a problem hiding this comment.
I think I have something to address this follow-up.
Sorry, something went wrong.
| * resulting `condition` satisifies the constraint given by `constraint`. | ||
| * resulting `condition` satisfies the constraint given by `constraint`. | ||
| * - `transitive` corresponds to whether any further constraints satisfied | ||
| * through `constraint` also applies to `condition`. |
There was a problem hiding this comment.
nit: apply
Sorry, something went wrong.
| | main.rs:2561:13:2561:31 | ...::from(...) | | ||
| | main.rs:2562:13:2562:31 | ...::from(...) | | ||
| | main.rs:2563:13:2563:31 | ...::from(...) | | ||
| ======= |
There was a problem hiding this comment.
Merge conflicts in this file.
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
This PR changes how we calculate the trait/implements hierarchy.
Currently an impl Trait for T block makes T directly implement both Trait and any supertraits, SuperTrait, of Trait. However, in order for this impl block to be valid, it must already be the case that T implements SuperTrait by some other impl block. Hence, the only new information from an impl block is the implementation of the specific target trait.
This PR changes how we handle impl blocks when calculating the trait/implements hierarchy, s.t. impl blocks only makes a type implement the specific trait in the impl block.
This restriction is also used in AssocFunctionType where the restriction removes some spurious call targets.
The DCA report shows a small speedup and decent reductions in "Path resolution inconsistencies" and "Nodes With Type At Length Limit". There is a small increase in "Unknown expression types". I think this increase looks reasonable when compared to the decrease in "Path resolution inconsistencies". I also did a quick and small spot check on neon, and the lost types all looked like spurious types.