Skip to content

Commit 8cfb152

Browse files
committed
Shared: Generalize typeConstraintBaseTypeMatch
1 parent 299c8cd commit 8cfb152

3 files changed

Lines changed: 63 additions & 71 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: 60 additions & 70 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]
@@ -1591,41 +1592,32 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
15911592
SatisfiesTypeParameterConstraintInput>;
15921593

15931594
pragma[nomagic]
1594-
predicate satisfiesConstraintAtTypeParameter(
1595+
predicate argSatisfiesConstraintAtTypeParameter(
15951596
Access a, AccessEnvironment e, Declaration target, AccessPosition apos, TypePath prefix,
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, prefix)
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,48 @@ 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
1656+
*
16701657
* ```csharp
16711658
* interface IFoo<A> { }
16721659
* T1 M<T1, T2>(T2 item) where T2 : IFoo<T1> { }
16731660
* ```
1674-
* with the method declaration being the target and with `apos`
1675-
* corresponding to `item`, we have the following
1676-
* - `pathToConstrained = ""`,
1677-
* - `tp = T1`,
1661+
*
1662+
* with the method declaration being the target, we have the following
1663+
* - `constrainedTp = T2`,
16781664
* - `constraint = IFoo`,
1665+
* - `tp = T1`, and
16791666
* - `pathToTp = "A"`.
16801667
*/
16811668
pragma[nomagic]
16821669
private predicate typeParameterConstraintHasTypeParameter(
1683-
Declaration target, AccessPosition apos, TypePath pathToConstrained, TypeMention constraint,
1684-
TypePath pathToTp, TypeParameter tp
1670+
Declaration target, TypeParameter constrainedTp, TypeMention constraint, TypePath pathToTp,
1671+
TypeParameter tp
16851672
) {
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-
)
1673+
typeParameterHasConstraint(target, constrainedTp, constraint) and
1674+
tp = target.getTypeParameter(_) and
1675+
tp = constraint.getTypeAt(pathToTp) and
1676+
constrainedTp != tp
16921677
}
16931678

16941679
pragma[nomagic]
16951680
private predicate typeConstraintBaseTypeMatch(
16961681
Access a, AccessEnvironment e, Declaration target, TypePath path, Type t, TypeParameter tp
16971682
) {
16981683
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,
1684+
exists(TypeMention constraint, TypeParameter constrainedTp, TypePath pathToTp |
1685+
typeParameterConstraintHasTypeParameter(target, constrainedTp, constraint, pathToTp, tp) and
1686+
AccessConstraint::satisfiesConstraint(a, e, target, constrainedTp, constraint,
17021687
pathToTp.appendInverse(path), t)
17031688
)
17041689
}
@@ -1781,7 +1766,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
17811766
Declaration target, TypePath prefix, TypeMention constraint,
17821767
TypePath pathToTypeParamInConstraint, TypePath pathToTypeParamInSub
17831768
|
1784-
AccessConstraint::satisfiesConstraintAtTypeParameter(a, e, target, apos, prefix,
1769+
AccessConstraint::argSatisfiesConstraintAtTypeParameter(a, e, target, apos, prefix,
17851770
constraint, pathToTypeParamInConstraint, pathToTypeParamInSub)
17861771
|
17871772
exists(TypePath suffix |
@@ -1847,7 +1832,12 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
18471832
*/
18481833

18491834
typeMatch(a, e, target, suffix, result, tp) and
1850-
typeParameterConstraintHasTypeParameter(target, apos, _, constraint, pathToTp, tp) and
1835+
exists(TypeParameter constrainedTp, DeclarationPosition dpos |
1836+
typeParameterConstraintHasTypeParameter(target, constrainedTp, constraint, pathToTp,
1837+
tp) and
1838+
accessDeclarationPositionMatch(apos, dpos) and
1839+
constrainedTp = target.getDeclaredType(dpos, _)
1840+
) and
18511841
pathToTp = pathToTypeParamInConstraint.appendInverse(mid) and
18521842
path = prefix.append(pathToTypeParamInSub.append(mid).append(suffix))
18531843
)

0 commit comments

Comments
 (0)