@@ -238,7 +238,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
238238 }
239239
240240 /** A class that represents a type tree. */
241- signature class TypeTreeSig {
241+ private signature class TypeTreeSig {
242242 Type resolveTypeAt(TypePath path);
243243
244244 /** Gets a textual representation of this type abstraction. */
@@ -357,21 +357,38 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
357357 result = tm.resolveTypeAt(TypePath::nil())
358358 }
359359
360- signature module IsInstantiationOfSig <TypeTreeSig App> {
360+ signature module IsInstantiationOfInputSig <TypeTreeSig App> {
361361 /**
362362 * Holds if `abs` is a type abstraction under which `tm` occurs and if
363363 * `app` is potentially the result of applying the abstraction to type
364364 * some type argument.
365365 */
366366 predicate potentialInstantiationOf(App app, TypeAbstraction abs, TypeMention tm);
367+
368+ /**
369+ * Holds if `constraint` might occur as the third argument of
370+ * `potentialInstantiationOf`. Defaults to simply projecting the third
371+ * argument of `potentialInstantiationOf`.
372+ */
373+ default predicate relevantTypeMention(TypeMention tm) { potentialInstantiationOf(_, _, tm) }
367374 }
368375
369- module IsInstantiationOf<TypeTreeSig App, IsInstantiationOfSig<App> Input> {
376+ /**
377+ * Provides functionality for determining if a type is a possible
378+ * instantiation of a type mention containing type parameters.
379+ */
380+ module IsInstantiationOf<TypeTreeSig App, IsInstantiationOfInputSig<App> Input> {
370381 private import Input
371382
372383 /** Gets the `i`th path in `tm` per some arbitrary order. */
384+ pragma[nomagic]
373385 private TypePath getNthPath(TypeMention tm, int i) {
374- result = rank[i + 1](TypePath path | exists(tm.resolveTypeAt(path)) | path)
386+ result =
387+ rank[i + 1](TypePath path |
388+ exists(tm.resolveTypeAt(path)) and relevantTypeMention(tm)
389+ |
390+ path
391+ )
375392 }
376393
377394 /**
@@ -389,6 +406,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
389406 )
390407 }
391408
409+ pragma[nomagic]
392410 private predicate satisfiesConcreteTypesFromIndex(
393411 App app, TypeAbstraction abs, TypeMention tm, int i
394412 ) {
@@ -398,7 +416,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
398416 if i = 0 then any() else satisfiesConcreteTypesFromIndex(app, abs, tm, i - 1)
399417 }
400418
401- pragma[inline ]
419+ pragma[nomagic ]
402420 private predicate satisfiesConcreteTypes(App app, TypeAbstraction abs, TypeMention tm) {
403421 satisfiesConcreteTypesFromIndex(app, abs, tm, max(int i | exists(getNthPath(tm, i))))
404422 }
@@ -417,18 +435,19 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
417435 * arbitrary order, if any.
418436 */
419437 private TypePath getNthTypeParameterPath(TypeMention tm, TypeParameter tp, int i) {
420- result = rank[i + 1](TypePath path | tp = tm.resolveTypeAt(path) | path)
438+ result =
439+ rank[i + 1](TypePath path | tp = tm.resolveTypeAt(path) and relevantTypeMention(tm) | path)
421440 }
422441
442+ pragma[nomagic]
423443 private predicate typeParametersEqualFromIndex(
424- App app, TypeAbstraction abs, TypeMention tm, TypeParameter tp, int i
444+ App app, TypeAbstraction abs, TypeMention tm, TypeParameter tp, Type t, int i
425445 ) {
426446 potentialInstantiationOf(app, abs, tm) and
427- exists(TypePath path, TypePath nextPath |
447+ exists(TypePath path |
428448 path = getNthTypeParameterPath(tm, tp, i) and
429- nextPath = getNthTypeParameterPath(tm, tp, i - 1) and
430- app.resolveTypeAt(path) = app.resolveTypeAt(nextPath) and
431- if i = 1 then any() else typeParametersEqualFromIndex(app, abs, tm, tp, i - 1)
449+ t = app.resolveTypeAt(path) and
450+ if i = 0 then any() else typeParametersEqualFromIndex(app, abs, tm, tp, t, i - 1)
432451 )
433452 }
434453
@@ -443,7 +462,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
443462 exists(int n | n = max(int i | exists(getNthTypeParameterPath(tm, tp, i))) |
444463 // If the largest index is 0, then there are no equalities to check as
445464 // the type parameter only occurs once.
446- if n = 0 then any() else typeParametersEqualFromIndex(app, abs, tm, tp, n)
465+ if n = 0 then any() else typeParametersEqualFromIndex(app, abs, tm, tp, _, n)
447466 )
448467 )
449468 }
@@ -488,7 +507,6 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
488507 * - `Pair<int, string>` is _not_ an instantiation of `Pair<string, string>`
489508 */
490509 predicate isInstantiationOf(App app, TypeAbstraction abs, TypeMention tm) {
491- potentialInstantiationOf(app, abs, tm) and
492510 satisfiesConcreteTypes(app, abs, tm) and
493511 typeParametersHaveEqualInstantiation(app, abs, tm)
494512 }
@@ -513,7 +531,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
513531 )
514532 }
515533
516- module IsInstantiationOfInput implements IsInstantiationOfSig <TypeMention> {
534+ module IsInstantiationOfInput implements IsInstantiationOfInputSig <TypeMention> {
517535 pragma[nomagic]
518536 private predicate typeCondition(Type type, TypeAbstraction abs, TypeMention lhs) {
519537 conditionSatisfiesConstraint(abs, lhs, _) and type = resolveTypeMentionRoot(lhs)
@@ -954,7 +972,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
954972 Location getLocation() { result = a.getLocation() }
955973 }
956974
957- private module IsInstantiationOfInput implements IsInstantiationOfSig <RelevantAccess> {
975+ private module IsInstantiationOfInput implements IsInstantiationOfInputSig <RelevantAccess> {
958976 predicate potentialInstantiationOf(
959977 RelevantAccess at, TypeAbstraction abs, TypeMention cond
960978 ) {
@@ -965,6 +983,10 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
965983 countConstraintImplementations(type, constraint) > 1
966984 )
967985 }
986+
987+ predicate relevantTypeMention(TypeMention constraint) {
988+ rootTypesSatisfaction(_, _, _, constraint, _)
989+ }
968990 }
969991
970992 /**
0 commit comments