Skip to content

Commit 36724d8

Browse files
committed
Shared: Generalize typeConstraintBaseTypeMatch
1 parent 8685c44 commit 36724d8

3 files changed

Lines changed: 58 additions & 69 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
@@ -469,7 +469,7 @@ mod method_non_parametric_trait_impl {
469469
let i = thing.convert_to(); // $ type=i:S1 target=T::convert_to
470470
let j = convert_to(thing); // $ target=convert_to $ MISSING: type=j:S1 -- the blanket implementation `impl<T: MyTrait<S1>> ConvertTo<S1> for T` is currently not included in the constraint analysis
471471

472-
let x = call_trait_m1_trait2_m3(MyThing { a: S2 }); // $ target=call_trait_m1_trait2_m3 $ MISSING: type=x:S1
472+
let x = call_trait_m1_trait2_m3(MyThing { a: S2 }); // $ target=call_trait_m1_trait2_m3 type=x:S1
473473
}
474474
}
475475

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8371,6 +8371,8 @@ inferType
83718371
| main.rs:469:17:469:34 | thing.convert_to() | | main.rs:249:5:250:14 | S1 |
83728372
| main.rs:470:28:470:32 | thing | | main.rs:238:5:241:5 | MyThing |
83738373
| main.rs:470:28:470:32 | thing | A | main.rs:249:5:250:14 | S1 |
8374+
| main.rs:472:13:472:13 | x | | main.rs:249:5:250:14 | S1 |
8375+
| main.rs:472:17:472:58 | call_trait_m1_trait2_m3(...) | | main.rs:249:5:250:14 | S1 |
83748376
| main.rs:472:41:472:57 | MyThing {...} | | main.rs:238:5:241:5 | MyThing |
83758377
| main.rs:472:41:472:57 | MyThing {...} | A | main.rs:251:5:252:14 | S2 |
83768378
| main.rs:472:54:472:55 | S2 | | main.rs:251:5:252:14 | S2 |

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

Lines changed: 55 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,6 +1346,14 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
13461346
module MatchingWithEnvironment<MatchingWithEnvironmentInputSig Input> {
13471347
private import Input
13481348

1349+
pragma[nomagic]
1350+
private TypeParameter getDeclTypeParameter(Declaration decl, TypeArgumentPosition tapos) {
1351+
exists(TypeParameterPosition tppos |
1352+
result = decl.getTypeParameter(tppos) and
1353+
typeArgumentParameterPositionMatch(tapos, tppos)
1354+
)
1355+
}
1356+
13491357
/**
13501358
* Gets the type of the type argument at `path` in `a` that corresponds to
13511359
* the type parameter `tp` in `target`, if any.
@@ -1356,11 +1364,11 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
13561364
*/
13571365
bindingset[a, target]
13581366
pragma[inline_late]
1359-
private Type getTypeArgument(Access a, Declaration target, TypeParameter tp, TypePath path) {
1360-
exists(TypeArgumentPosition tapos, TypeParameterPosition tppos |
1367+
Type getTypeArgument(Access a, Declaration target, TypeParameter tp, TypePath path) {
1368+
exists(TypeArgumentPosition tapos |
13611369
result = a.getTypeArgument(tapos, path) and
1362-
tp = target.getTypeParameter(tppos) and
1363-
typeArgumentParameterPositionMatch(tapos, tppos)
1370+
tp = getDeclTypeParameter(target, tapos) and
1371+
not isPseudoType(result)
13641372
)
13651373
}
13661374

@@ -1526,42 +1534,35 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
15261534

15271535
private module AccessConstraint {
15281536
private predicate relevantAccessConstraint(
1529-
Access a, AccessEnvironment e, Declaration target, AccessPosition apos, TypePath path,
1537+
Access a, AccessEnvironment e, Declaration target, TypeParameter constrainedTp,
15301538
TypeMention constraint
15311539
) {
15321540
target = a.getTarget(e) and
1533-
typeParameterHasConstraint(target, apos, _, path, constraint)
1541+
typeParameterHasConstraint(target, constrainedTp, constraint)
15341542
}
15351543

15361544
private newtype TRelevantAccess =
1537-
MkRelevantAccess(Access a, AccessPosition apos, AccessEnvironment e, TypePath path) {
1538-
relevantAccessConstraint(a, e, _, apos, path, _)
1545+
MkRelevantAccess(Access a, AccessEnvironment e, TypeParameter constrainedTp) {
1546+
relevantAccessConstraint(a, e, _, constrainedTp, _)
15391547
}
15401548

1541-
/**
1542-
* If the access `a` for `apos`, environment `e`, and `path` has an inferred type
1543-
* which type inference requires to satisfy some constraint.
1544-
*/
15451549
private class RelevantAccess extends MkRelevantAccess {
15461550
Access a;
1547-
AccessPosition apos;
15481551
AccessEnvironment e;
1549-
TypePath path;
1552+
TypeParameter constrainedTp;
15501553

1551-
RelevantAccess() { this = MkRelevantAccess(a, apos, e, path) }
1554+
RelevantAccess() { this = MkRelevantAccess(a, e, constrainedTp) }
15521555

15531556
pragma[nomagic]
1554-
Type getTypeAt(TypePath suffix) {
1555-
result = a.getInferredType(e, apos, path.appendInverse(suffix))
1556-
}
1557+
Type getTypeAt(TypePath path) { typeMatch(a, e, _, path, result, constrainedTp) }
15571558

15581559
/** Gets the constraint that this relevant access should satisfy. */
15591560
TypeMention getConstraint(Declaration target) {
1560-
relevantAccessConstraint(a, e, target, apos, path, result)
1561+
relevantAccessConstraint(a, e, target, constrainedTp, result)
15611562
}
15621563

15631564
string toString() {
1564-
result = a.toString() + ", " + apos.toString() + ", " + path.toString()
1565+
result = a.toString() + ", " + e.toString() + ", " + constrainedTp.toString()
15651566
}
15661567

15671568
Location getLocation() { result = a.getLocation() }
@@ -1577,7 +1578,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
15771578
class TypeMatchingContext = Access;
15781579

15791580
TypeMatchingContext getTypeMatchingContext(RelevantAccess at) {
1580-
at = MkRelevantAccess(result, _, _, _)
1581+
at = MkRelevantAccess(result, _, _)
15811582
}
15821583

15831584
pragma[nomagic]
@@ -1592,40 +1593,31 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
15921593

15931594
pragma[nomagic]
15941595
predicate satisfiesConstraintAtTypeParameter(
1595-
Access a, AccessEnvironment e, Declaration target, AccessPosition apos, TypePath prefix,
1596+
Access a, AccessEnvironment e, Declaration target, AccessPosition apos, TypePath path,
15961597
TypeMention constraint, TypePath pathToTypeParamInConstraint,
15971598
TypePath pathToTypeParamInSub
15981599
) {
1599-
exists(RelevantAccess ra |
1600-
ra = MkRelevantAccess(a, apos, e, prefix) and
1600+
exists(RelevantAccess ra, TypeParameter constrainedTp |
1601+
ra = MkRelevantAccess(a, e, constrainedTp) and
1602+
relevantAccessConstraint(a, e, target, constrainedTp, constraint) and
16011603
SatisfiesTypeParameterConstraint::satisfiesConstraintAtTypeParameter(ra, constraint,
16021604
pathToTypeParamInConstraint, pathToTypeParamInSub) and
1603-
constraint = ra.getConstraint(target)
1605+
exists(DeclarationPosition dpos |
1606+
accessDeclarationPositionMatch(apos, dpos) and
1607+
constrainedTp = target.getDeclaredType(dpos, path)
1608+
)
16041609
)
16051610
}
16061611

16071612
pragma[nomagic]
16081613
predicate satisfiesConstraint(
1609-
Access a, AccessEnvironment e, Declaration target, AccessPosition apos, TypePath prefix,
1614+
Access a, AccessEnvironment e, Declaration target, TypeParameter constrainedTp,
16101615
TypeMention constraint, TypePath path, Type t
16111616
) {
16121617
exists(RelevantAccess ra |
1613-
ra = MkRelevantAccess(a, apos, e, prefix) and
1614-
SatisfiesTypeParameterConstraint::satisfiesConstraint(ra, constraint, path, t) and
1615-
constraint = ra.getConstraint(target)
1616-
)
1617-
}
1618-
1619-
pragma[nomagic]
1620-
predicate satisfiesConstraintThrough(
1621-
Access a, AccessEnvironment e, Declaration target, AccessPosition apos, TypePath prefix,
1622-
TypeAbstraction abs, TypeMention constraint, TypePath path, Type t
1623-
) {
1624-
exists(RelevantAccess ra |
1625-
ra = MkRelevantAccess(a, apos, e, prefix) and
1626-
SatisfiesTypeParameterConstraint::satisfiesConstraintThrough(ra, abs, constraint, path,
1627-
t) and
1628-
constraint = ra.getConstraint(target)
1618+
ra = MkRelevantAccess(a, e, constrainedTp) and
1619+
relevantAccessConstraint(a, e, target, constrainedTp, constraint) and
1620+
SatisfiesTypeParameterConstraint::satisfiesConstraint(ra, constraint, path, t)
16291621
)
16301622
}
16311623
}
@@ -1650,55 +1642,45 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
16501642
*/
16511643
pragma[nomagic]
16521644
private predicate typeParameterHasConstraint(
1653-
Declaration target, AccessPosition apos, TypeParameter constrainedTp,
1654-
TypePath pathToConstrained, TypeMention constraint
1645+
Declaration target, TypeParameter constrainedTp, TypeMention constraint
16551646
) {
1656-
exists(DeclarationPosition dpos |
1657-
accessDeclarationPositionMatch(apos, dpos) and
1658-
constrainedTp = target.getTypeParameter(_) and
1659-
constrainedTp = target.getDeclaredType(dpos, pathToConstrained) and
1660-
constraint = getATypeParameterConstraint(constrainedTp, target)
1661-
)
1647+
constrainedTp = target.getTypeParameter(_) and
1648+
constraint = getATypeParameterConstraint(constrainedTp, target)
16621649
}
16631650

16641651
/**
1665-
* Holds if the declared type of `target` contains a type parameter at
1666-
* `apos` and `pathToConstrained` that must satisfy `constraint` and `tp`
1667-
* occurs at `pathToTp` in `constraint`.
1652+
* Holds if the declared type of `target` contains type parameter `constrainedTp`
1653+
* that must satisfy `constraint` and `tp` occurs at `pathToTp` in `constraint`.
16681654
*
16691655
* For example, in
16701656
* ```csharp
16711657
* interface IFoo<A> { }
16721658
* T1 M<T1, T2>(T2 item) where T2 : IFoo<T1> { }
16731659
* ```
1674-
* with the method declaration being the target and with `apos`
1675-
* corresponding to `item`, we have the following
1676-
* - `pathToConstrained = ""`,
1660+
* with the method declaration being the target, we have the following
16771661
* - `tp = T1`,
16781662
* - `constraint = IFoo`,
16791663
* - `pathToTp = "A"`.
16801664
*/
16811665
pragma[nomagic]
16821666
private predicate typeParameterConstraintHasTypeParameter(
1683-
Declaration target, AccessPosition apos, TypePath pathToConstrained, TypeMention constraint,
1684-
TypePath pathToTp, TypeParameter tp
1667+
Declaration target, TypeParameter constrainedTp, TypeMention constraint, TypePath pathToTp,
1668+
TypeParameter tp
16851669
) {
1686-
exists(TypeParameter constrainedTp |
1687-
typeParameterHasConstraint(target, apos, constrainedTp, pathToConstrained, constraint) and
1688-
tp = target.getTypeParameter(_) and
1689-
tp = constraint.getTypeAt(pathToTp) and
1690-
constrainedTp != tp
1691-
)
1670+
typeParameterHasConstraint(target, constrainedTp, constraint) and
1671+
tp = target.getTypeParameter(_) and
1672+
tp = constraint.getTypeAt(pathToTp) and
1673+
constrainedTp != tp
16921674
}
16931675

16941676
pragma[nomagic]
16951677
private predicate typeConstraintBaseTypeMatch(
16961678
Access a, AccessEnvironment e, Declaration target, TypePath path, Type t, TypeParameter tp
16971679
) {
16981680
not exists(getTypeArgument(a, target, tp, _)) and
1699-
exists(TypeMention constraint, AccessPosition apos, TypePath pathToTp, TypePath pathToTp2 |
1700-
typeParameterConstraintHasTypeParameter(target, apos, pathToTp2, constraint, pathToTp, tp) and
1701-
AccessConstraint::satisfiesConstraint(a, e, target, apos, pathToTp2, constraint,
1681+
exists(TypeMention constraint, TypeParameter constrainedTp, TypePath pathToTp |
1682+
typeParameterConstraintHasTypeParameter(target, constrainedTp, constraint, pathToTp, tp) and
1683+
AccessConstraint::satisfiesConstraint(a, e, target, constrainedTp, constraint,
17021684
pathToTp.appendInverse(path), t)
17031685
)
17041686
}
@@ -1847,7 +1829,12 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
18471829
*/
18481830

18491831
typeMatch(a, e, target, suffix, result, tp) and
1850-
typeParameterConstraintHasTypeParameter(target, apos, _, constraint, pathToTp, tp) and
1832+
exists(TypeParameter constrainedTp, DeclarationPosition dpos |
1833+
typeParameterConstraintHasTypeParameter(target, constrainedTp, constraint, pathToTp,
1834+
tp) and
1835+
accessDeclarationPositionMatch(apos, dpos) and
1836+
constrainedTp = target.getDeclaredType(dpos, _)
1837+
) and
18511838
pathToTp = pathToTypeParamInConstraint.appendInverse(mid) and
18521839
path = prefix.append(pathToTypeParamInSub.append(mid).append(suffix))
18531840
)

0 commit comments

Comments
 (0)