@@ -1261,30 +1261,58 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
12611261 module MatchingWithEnvironment< MatchingWithEnvironmentInputSig Input> {
12621262 private import Input
12631263
1264+ private Type getTypeArgumentNonPseudo ( Access a , int pos , TypePath path ) {
1265+ result = a .getTypeArgument ( pos , path ) and
1266+ not result instanceof PseudoType
1267+ }
1268+
12641269 /**
12651270 * Gets the type of the type argument at `path` in `a` that corresponds to
12661271 * the type parameter `tp` in `target`, if any.
12671272 *
12681273 * Note that this predicate crucially does not depend on type inference,
1269- * and hence can appear in negated position, e.g., as in
1270- * `directTypeMatch`.
1274+ * and hence can appear in negated position, e.g., as in `directTypeMatch`.
12711275 */
12721276 bindingset [ a, target]
12731277 pragma [ inline_late]
12741278 Type getTypeArgument ( Access a , Declaration target , TypeParameter tp , TypePath path ) {
12751279 exists ( int pos |
1276- result = a .getTypeArgument ( pos , path ) and
1277- tp = target .getTypeParameter ( pos ) and
1278- not result instanceof PseudoType
1280+ result = getTypeArgumentNonPseudo ( a , pos , path ) and
1281+ tp = target .getTypeParameter ( pos )
1282+ )
1283+ }
1284+
1285+ bindingset [ a, target]
1286+ pragma [ inline_late]
1287+ private predicate hasNotTypeArgument0 ( Access a , Declaration target , TypeParameter tp ) {
1288+ exists ( int pos |
1289+ tp = target .getTypeParameter ( pragma [ only_bind_into ] ( pos ) ) and
1290+ not exists ( getTypeArgumentNonPseudo ( a , pos , _) )
12791291 )
12801292 }
12811293
1294+ bindingset [ target, tp]
1295+ pragma [ inline_late]
1296+ private predicate hasNotTypeArgument1 ( Declaration target , TypeParameter tp ) {
1297+ not tp = target .getTypeParameter ( _)
1298+ }
1299+
1300+ /**
1301+ * A join-order optimized version of `not exists(getTypeArgument(a, target, tp, _)`.
1302+ */
1303+ pragma [ inline]
1304+ private predicate hasNotTypeArgument ( Access a , Declaration target , TypeParameter tp ) {
1305+ hasNotTypeArgument0 ( a , target , tp )
1306+ or
1307+ hasNotTypeArgument1 ( target , tp )
1308+ }
1309+
12821310 pragma [ nomagic]
12831311 private predicate directTypeMatch0 (
12841312 Access a , DeclarationPosition dpos , AccessEnvironment e , Declaration target ,
12851313 TypePath pathToTypeParam , TypeParameter tp
12861314 ) {
1287- not exists ( getTypeArgument ( a , target , tp , _ ) ) and
1315+ hasNotTypeArgument ( a , target , tp ) and
12881316 tp = target .getDeclaredType ( dpos , pathToTypeParam ) and
12891317 target = a .getTarget ( e )
12901318 }
@@ -1359,12 +1387,18 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
13591387 t = a .getInferredType ( e , apos , TypePath:: nil ( ) )
13601388 }
13611389
1390+ private predicate relevantAccessTarget (
1391+ Access a , AccessPosition apos , AccessEnvironment e , Declaration target
1392+ ) {
1393+ exists ( Type t |
1394+ accessTargetsWithArgRootType ( a , e , target , apos , t ) and
1395+ argRootTypeSatisfiesTargetTypeCand ( t , target , apos , _, _)
1396+ )
1397+ }
1398+
13621399 private newtype TRelevantAccess =
13631400 MkRelevantAccess ( Access a , AccessPosition apos , AccessEnvironment e ) {
1364- exists ( Declaration target , Type t |
1365- accessTargetsWithArgRootType ( a , e , target , apos , t ) and
1366- argRootTypeSatisfiesTargetTypeCand ( t , target , apos , _, _)
1367- )
1401+ relevantAccessTarget ( a , apos , e , _)
13681402 }
13691403
13701404 private class RelevantAccess extends MkRelevantAccess {
@@ -1374,7 +1408,12 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
13741408
13751409 RelevantAccess ( ) { this = MkRelevantAccess ( a , apos , e ) }
13761410
1377- RelevantTarget getTarget ( ) { result = MkRelevantTarget ( a .getTarget ( e ) , apos ) }
1411+ RelevantTarget getTarget ( ) {
1412+ exists ( Declaration target |
1413+ relevantAccessTarget ( a , apos , e , target ) and
1414+ result = MkRelevantTarget ( target , apos )
1415+ )
1416+ }
13781417
13791418 pragma [ nomagic]
13801419 Type getTypeAt ( TypePath path ) { result = a .getInferredType ( e , apos , path ) }
@@ -1437,7 +1476,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
14371476 pragma [ only_bind_into ] ( apos ) , e ) ,
14381477 MkRelevantTarget ( target , pragma [ only_bind_into ] ( apos ) ) , pathToTp .appendInverse ( path ) ,
14391478 t ) and
1440- not exists ( getTypeArgument ( a , target , tp , _ ) )
1479+ hasNotTypeArgument ( a , target , tp )
14411480 )
14421481 }
14431482 }
@@ -1595,7 +1634,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
15951634 private predicate typeConstraintBaseTypeMatch (
15961635 Access a , AccessEnvironment e , Declaration target , TypePath path , Type t , TypeParameter tp
15971636 ) {
1598- not exists ( getTypeArgument ( a , target , tp , _ ) ) and
1637+ hasNotTypeArgument ( a , target , tp ) and
15991638 exists ( TypeMention constraint , TypeParameter constrainedTp , TypePath pathToTp |
16001639 typeParameterConstraintHasTypeParameter ( target , constrainedTp , constraint , pathToTp , tp ) and
16011640 AccessConstraint:: satisfiesConstraint ( a , e , target , constrainedTp , constraint ,
0 commit comments