Skip to content

Commit cd3d056

Browse files
committed
Type inference: Improve constraint matching
1 parent b439222 commit cd3d056

3 files changed

Lines changed: 69 additions & 17 deletions

File tree

‎rust/ql/test/library-tests/type-inference/main.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2830,7 +2830,7 @@ mod contextual_bound {
28302830
bar(x, Some(y)); // $ target=bar
28312831

28322832
let x = S(0);
2833-
let z = MyThingB(Default::default()); // $ MISSING: type=z@MyThingB<B>.S<T>:i32 target=default
2833+
let z = MyThingB(Default::default()); // $ type=z@MyThingB<B>.S<T>:i32 target=default
28342834
bar([x], Some(z)); // $ target=bar
28352835
}
28362836
}

‎rust/ql/test/library-tests/type-inference/type-inference.expected‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12814,7 +12814,13 @@ inferType
1281412814
| main.rs:2832:17:2832:20 | S(...) | T | {EXTERNAL LOCATION} | i32 |
1281512815
| main.rs:2832:19:2832:19 | 0 | | {EXTERNAL LOCATION} | i32 |
1281612816
| main.rs:2833:13:2833:13 | z | | main.rs:2817:5:2817:26 | MyThingB |
12817+
| main.rs:2833:13:2833:13 | z | B | main.rs:2814:5:2815:19 | S |
12818+
| main.rs:2833:13:2833:13 | z | B.T | {EXTERNAL LOCATION} | i32 |
1281712819
| main.rs:2833:17:2833:44 | MyThingB(...) | | main.rs:2817:5:2817:26 | MyThingB |
12820+
| main.rs:2833:17:2833:44 | MyThingB(...) | B | main.rs:2814:5:2815:19 | S |
12821+
| main.rs:2833:17:2833:44 | MyThingB(...) | B.T | {EXTERNAL LOCATION} | i32 |
12822+
| main.rs:2833:26:2833:43 | ...::default(...) | | main.rs:2814:5:2815:19 | S |
12823+
| main.rs:2833:26:2833:43 | ...::default(...) | T | {EXTERNAL LOCATION} | i32 |
1281812824
| main.rs:2834:9:2834:25 | bar(...) | | {EXTERNAL LOCATION} | () |
1281912825
| main.rs:2834:13:2834:15 | [...] | | {EXTERNAL LOCATION} | [;] |
1282012826
| main.rs:2834:13:2834:15 | [...] | TArray | main.rs:2814:5:2815:19 | S |
@@ -12823,7 +12829,11 @@ inferType
1282312829
| main.rs:2834:14:2834:14 | x | T | {EXTERNAL LOCATION} | i32 |
1282412830
| main.rs:2834:18:2834:24 | Some(...) | | {EXTERNAL LOCATION} | Option |
1282512831
| main.rs:2834:18:2834:24 | Some(...) | T | main.rs:2817:5:2817:26 | MyThingB |
12832+
| main.rs:2834:18:2834:24 | Some(...) | T.B | main.rs:2814:5:2815:19 | S |
12833+
| main.rs:2834:18:2834:24 | Some(...) | T.B.T | {EXTERNAL LOCATION} | i32 |
1282612834
| main.rs:2834:23:2834:23 | z | | main.rs:2817:5:2817:26 | MyThingB |
12835+
| main.rs:2834:23:2834:23 | z | B | main.rs:2814:5:2815:19 | S |
12836+
| main.rs:2834:23:2834:23 | z | B.T | {EXTERNAL LOCATION} | i32 |
1282712837
| main.rs:2838:11:2874:1 | { ... } | | {EXTERNAL LOCATION} | () |
1282812838
| main.rs:2839:5:2839:21 | ...::f(...) | | {EXTERNAL LOCATION} | () |
1282912839
| main.rs:2840:5:2840:20 | ...::f(...) | | main.rs:72:5:72:21 | Foo |

‎shared/typeinference/codeql/typeinference/internal/TypeInference.qll‎

Lines changed: 58 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,44 +1785,86 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
17851785
)
17861786
or
17871787
exists(TypeParameter tp, TypePath suffix, TypePath mid, TypePath pathToTp |
1788+
exists(TypeParameter constrainedTp, DeclarationPosition dpos |
1789+
typeParameterConstraintHasTypeParameter(target, constrainedTp, constraint, pathToTp,
1790+
tp) and
1791+
accessDeclarationPositionMatch(apos, dpos) and
1792+
constrainedTp = target.getDeclaredType(dpos, _)
1793+
)
1794+
|
17881795
/*
17891796
* Example:
17901797
*
17911798
* ```rust
1799+
* struct S<T> { ... }
1800+
*
17921801
* struct MyThing<A> { ... }
17931802
*
17941803
* trait MyTrait<B> { ... }
17951804
*
17961805
* impl<T> MyTrait<T> for MyThing<T> { ... }
17971806
*
1798-
* fn bar<T1, T2: MyTrait<T1>>(x: T1, y: T2) {}
1807+
* fn bar<T1, T2: MyTrait<T1>>(x: T1, y: Option<T2>) {}
17991808
*
1800-
* let x: i32 = ...;
1809+
* let x: S<i32> = ...;
18011810
* let y = MyThing(Default::default());
1802-
* bar(x, y);
1811+
* bar(x, Some(y));
18031812
* ```
18041813
*
1805-
* At `term` = `bar(x, y)`, we have
1814+
* At `term` = `bar([x], Some(y))`, we have
18061815
* - `constraint = MyTrait<T1>`,
1807-
* - `pathToTypeParamInConstraint` = `"B"`,
1808-
* - `pathToTypeParamInSub` = `"A"`,
1809-
* - `prefix` = `suffix` = `mid` = `""`,
1816+
* - `pathToTypeParamInConstraint` = `"MyTrait<B>"`,
1817+
* - `pathToTypeParamInSub` = `"MyThing<A>"`,
1818+
* - `prefix` = `"Option<T>"`
1819+
* - `mid` = `""`,
18101820
* - `tp = T1`,
1811-
* - `pathToTp` = `"B"`, and
1812-
* - `result` = `i32`.
1821+
* - `pathToTp` = `"MyTrait<B>"`, and
1822+
* - `suffix` = `""` and `result` = `S`, or
1823+
* - `suffix` = `"Option<T>"` and `result` = `i32`.
18131824
*
1814-
* That is, it allows us to infer that the type of `y` is `MyThing<i32>`.
1825+
* That is, it allows us to infer that the type of `y` is `MyThing<S<i32>>`.
18151826
*/
18161827

18171828
typeMatch(a, e, target, suffix, result, tp) and
1818-
exists(TypeParameter constrainedTp, DeclarationPosition dpos |
1819-
typeParameterConstraintHasTypeParameter(target, constrainedTp, constraint, pathToTp,
1820-
tp) and
1821-
accessDeclarationPositionMatch(apos, dpos) and
1822-
constrainedTp = target.getDeclaredType(dpos, _)
1823-
) and
18241829
pathToTp = pathToTypeParamInConstraint.appendInverse(mid) and
18251830
path = prefix.append(pathToTypeParamInSub.append(mid).append(suffix))
1831+
or
1832+
/*
1833+
* Example:
1834+
*
1835+
* ```rust
1836+
* struct S<T> { ... }
1837+
*
1838+
* struct MyThing<A> { ... }
1839+
*
1840+
* trait MyTrait<B> { ... }
1841+
*
1842+
* impl<T> MyTrait<[T;1]> for MyThing<T> { ... }
1843+
*
1844+
* fn bar<T1, T2: MyTrait<T1>>(x: T1, y: Option<T2>) {}
1845+
*
1846+
* let x: S<i32> = ...;
1847+
* let y = MyThing(Default::default());
1848+
* bar([x], Some(y));
1849+
* ```
1850+
*
1851+
* At `term` = `bar([x], Some(y))`, we have
1852+
* - `constraint = MyTrait<T1>`,
1853+
* - `pathToTypeParamInConstraint` = `"MyTrait<B>.[]<TArray>"`,
1854+
* - `pathToTypeParamInSub` = `"MyThing<A>"`,
1855+
* - `prefix` = `"Option<T>"`
1856+
* - `mid` = `"[]<TArray>"`,
1857+
* - `tp = T1`,
1858+
* - `pathToTp` = `"MyTrait<B>"`, and
1859+
* - `suffix` = `""` and `result` = `S`, or
1860+
* - `suffix` = `"Option<T>"` and `result` = `i32`.
1861+
*
1862+
* That is, it allows us to infer that the type of `y` is `MyThing<S<i32>>`.
1863+
*/
1864+
1865+
pathToTypeParamInConstraint = pathToTp.appendInverse(mid) and
1866+
typeMatch(a, e, target, mid.appendInverse(suffix), result, tp) and
1867+
path = prefix.append(pathToTypeParamInSub.append(suffix))
18261868
)
18271869
)
18281870
}

0 commit comments

Comments
 (0)