Skip to content

Commit 49ecc60

Browse files
authored
Merge pull request #20076 from paldepind/rust/type-inference-cleanup-join
Rust: Type inference refactor and improve join orders
2 parents 28d3a6b + 43b2977 commit 49ecc60

File tree

1 file changed

+50
-52
lines changed

1 file changed

+50
-52
lines changed

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

Lines changed: 50 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,14 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
796796
)
797797
}
798798

799+
/**
800+
* Holds if there is multiple ways in which a type with `conditionRoot` at
801+
* the root can satisfy a constraint with `constraintRoot` at the root.
802+
*/
803+
predicate multipleConstraintImplementations(Type conditionRoot, Type constraintRoot) {
804+
countConstraintImplementations(conditionRoot, constraintRoot) > 1
805+
}
806+
799807
/**
800808
* Holds if `baseMention` is a (transitive) base type mention of `sub`,
801809
* and `t` is mentioned (implicitly) at `path` inside `baseMention`. For
@@ -902,14 +910,20 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
902910
{
903911
private import Input
904912

913+
/** Holds if the type tree has the type `type` and should satisfy `constraint`. */
914+
pragma[nomagic]
915+
private predicate hasTypeConstraint(HasTypeTree term, Type type, Type constraint) {
916+
type = term.getTypeAt(TypePath::nil()) and
917+
relevantConstraint(term, constraint)
918+
}
919+
905920
private module IsInstantiationOfInput implements IsInstantiationOfInputSig<HasTypeTree> {
906921
predicate potentialInstantiationOf(HasTypeTree tt, TypeAbstraction abs, TypeMention cond) {
907922
exists(Type constraint, Type type |
908-
type = tt.getTypeAt(TypePath::nil()) and
909-
relevantConstraint(tt, constraint) and
923+
hasTypeConstraint(tt, type, constraint) and
910924
rootTypesSatisfaction(type, constraint, abs, cond, _) and
911925
// We only need to check instantiations where there are multiple candidates.
912-
countConstraintImplementations(type, constraint) > 1
926+
multipleConstraintImplementations(type, constraint)
913927
)
914928
}
915929

@@ -918,13 +932,6 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
918932
}
919933
}
920934

921-
/** Holds if the type tree has the type `type` and should satisfy `constraint`. */
922-
pragma[nomagic]
923-
private predicate hasTypeConstraint(HasTypeTree term, Type type, Type constraint) {
924-
type = term.getTypeAt(TypePath::nil()) and
925-
relevantConstraint(term, constraint)
926-
}
927-
928935
/**
929936
* Holds if `tt` satisfies `constraint` through `abs`, `sub`, and `constraintMention`.
930937
*/
@@ -944,7 +951,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
944951
// When there are multiple ways the type could implement the
945952
// constraint we need to find the right implementation, which is the
946953
// one where the type instantiates the precondition.
947-
if countConstraintImplementations(type, constraint) > 1
954+
if multipleConstraintImplementations(type, constraint)
948955
then
949956
IsInstantiationOf<HasTypeTree, IsInstantiationOfInput>::isInstantiationOf(tt, abs, sub)
950957
else any()
@@ -989,7 +996,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
989996
path = prefix0.append(suffix)
990997
)
991998
or
992-
tt.getTypeAt(TypePath::nil()) = constraint and
999+
hasTypeConstraint(tt, constraint, constraint) and
9931000
t = tt.getTypeAt(path)
9941001
}
9951002
}
@@ -1229,11 +1236,8 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
12291236
predicate relevantAccessConstraint(
12301237
Access a, Declaration target, AccessPosition apos, TypePath path, Type constraint
12311238
) {
1232-
exists(DeclarationPosition dpos |
1233-
accessDeclarationPositionMatch(apos, dpos) and
1234-
target = a.getTarget() and
1235-
typeParameterConstraintHasTypeParameter(target, dpos, path, _, constraint, _, _)
1236-
)
1239+
target = a.getTarget() and
1240+
typeParameterConstraintHasTypeParameter(target, apos, path, constraint, _, _)
12371241
}
12381242

12391243
private newtype TRelevantAccess =
@@ -1276,12 +1280,11 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
12761280
}
12771281

12781282
predicate satisfiesConstraintType(
1279-
Access a, AccessPosition apos, TypePath prefix, Type constraint, TypePath path, Type t
1283+
Access a, Declaration target, AccessPosition apos, TypePath prefix, Type constraint,
1284+
TypePath path, Type t
12801285
) {
1281-
exists(RelevantAccess at | at = MkRelevantAccess(a, _, apos, prefix) |
1282-
SatisfiesConstraint<RelevantAccess, SatisfiesConstraintInput>::satisfiesConstraintType(at,
1283-
constraint, path, t)
1284-
)
1286+
SatisfiesConstraint<RelevantAccess, SatisfiesConstraintInput>::satisfiesConstraintType(MkRelevantAccess(a,
1287+
target, apos, prefix), constraint, path, t)
12851288
}
12861289
}
12871290

@@ -1370,37 +1373,38 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
13701373
}
13711374

13721375
/**
1373-
* Holds if `tp1` and `tp2` are distinct type parameters of `target`, the
1374-
* declared type at `dpos` mentions `tp1` at `path1`, `tp1` has a base
1375-
* type mention of type `constraint` that mentions `tp2` at the path
1376-
* `path2`.
1376+
* Holds if the declared type of `target` contains a type parameter at
1377+
* `apos` and `pathToConstrained` that must satisfy `constraint` and `tp`
1378+
* occurs at `pathToTp` in `constraint`.
13771379
*
1378-
* For this example
1380+
* For example, in
13791381
* ```csharp
13801382
* interface IFoo<A> { }
13811383
* T1 M<T1, T2>(T2 item) where T2 : IFoo<T1> { }
13821384
* ```
1383-
* with the method declaration being the target and the for the first
1384-
* parameter position, we have the following
1385-
* - `path1 = ""`,
1386-
* - `tp1 = T2`,
1385+
* with the method declaration being the target and with `apos`
1386+
* corresponding to `item`, we have the following
1387+
* - `pathToConstrained = ""`,
1388+
* - `tp = T1`,
13871389
* - `constraint = IFoo`,
1388-
* - `path2 = "A"`, and
1389-
* - `tp2 = T1`.
1390+
* - `pathToTp = "A"`.
13901391
*/
13911392
pragma[nomagic]
13921393
private predicate typeParameterConstraintHasTypeParameter(
1393-
Declaration target, DeclarationPosition dpos, TypePath path1, TypeParameter tp1,
1394-
Type constraint, TypePath path2, TypeParameter tp2
1394+
Declaration target, AccessPosition apos, TypePath pathToConstrained, Type constraint,
1395+
TypePath pathToTp, TypeParameter tp
13951396
) {
1396-
tp1 = target.getTypeParameter(_) and
1397-
tp2 = target.getTypeParameter(_) and
1398-
tp1 != tp2 and
1399-
tp1 = target.getDeclaredType(dpos, path1) and
1400-
exists(TypeMention tm |
1401-
tm = getATypeParameterConstraint(tp1) and
1402-
tm.resolveTypeAt(path2) = tp2 and
1403-
constraint = resolveTypeMentionRoot(tm)
1397+
exists(DeclarationPosition dpos, TypeParameter constrainedTp |
1398+
accessDeclarationPositionMatch(apos, dpos) and
1399+
constrainedTp = target.getTypeParameter(_) and
1400+
tp = target.getTypeParameter(_) and
1401+
constrainedTp != tp and
1402+
constrainedTp = target.getDeclaredType(dpos, pathToConstrained) and
1403+
exists(TypeMention tm |
1404+
tm = getATypeParameterConstraint(constrainedTp) and
1405+
tm.resolveTypeAt(pathToTp) = tp and
1406+
constraint = resolveTypeMentionRoot(tm)
1407+
)
14041408
)
14051409
}
14061410

@@ -1409,15 +1413,9 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
14091413
Access a, Declaration target, TypePath path, Type t, TypeParameter tp
14101414
) {
14111415
not exists(getTypeArgument(a, target, tp, _)) and
1412-
target = a.getTarget() and
1413-
exists(
1414-
Type constraint, AccessPosition apos, DeclarationPosition dpos, TypePath pathToTp,
1415-
TypePath pathToTp2
1416-
|
1417-
accessDeclarationPositionMatch(apos, dpos) and
1418-
typeParameterConstraintHasTypeParameter(target, dpos, pathToTp2, _, constraint, pathToTp,
1419-
tp) and
1420-
AccessConstraint::satisfiesConstraintType(a, apos, pathToTp2, constraint,
1416+
exists(Type constraint, AccessPosition apos, TypePath pathToTp, TypePath pathToTp2 |
1417+
typeParameterConstraintHasTypeParameter(target, apos, pathToTp2, constraint, pathToTp, tp) and
1418+
AccessConstraint::satisfiesConstraintType(a, target, apos, pathToTp2, constraint,
14211419
pathToTp.appendInverse(path), t)
14221420
)
14231421
}

0 commit comments

Comments
 (0)