@@ -1361,6 +1361,14 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
13611361 module MatchingWithEnvironment< MatchingWithEnvironmentInputSig Input> {
13621362 private import Input
13631363
1364+ pragma [ nomagic]
1365+ private TypeParameter getDeclTypeParameter ( Declaration decl , TypeArgumentPosition tapos ) {
1366+ exists ( TypeParameterPosition tppos |
1367+ result = decl .getTypeParameter ( tppos ) and
1368+ typeArgumentParameterPositionMatch ( tapos , tppos )
1369+ )
1370+ }
1371+
13641372 /**
13651373 * Gets the type of the type argument at `path` in `a` that corresponds to
13661374 * the type parameter `tp` in `target`, if any.
@@ -1372,10 +1380,9 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
13721380 bindingset [ a, target]
13731381 pragma [ inline_late]
13741382 private Type getTypeArgument ( Access a , Declaration target , TypeParameter tp , TypePath path ) {
1375- exists ( TypeArgumentPosition tapos , TypeParameterPosition tppos |
1383+ exists ( TypeArgumentPosition tapos |
13761384 result = a .getTypeArgument ( tapos , path ) and
1377- tp = target .getTypeParameter ( tppos ) and
1378- typeArgumentParameterPositionMatch ( tapos , tppos ) and
1385+ tp = getDeclTypeParameter ( target , tapos ) and
13791386 not result instanceof UnknownType //and path.isEmpty())
13801387 )
13811388 }
@@ -2036,13 +2043,6 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
20362043 */
20372044 default predicate cacheRevRef ( ) { none ( ) }
20382045
2039- /**
2040- * Point this predicate to the `inferType` predicate from the output of this module.
2041- *
2042- * Needed to be able to refer to `inferType` in default signature implementations.
2043- */
2044- Type inferType ( AstNode n , TypePath path ) ;
2045-
20462046 /** A boolean type. */
20472047 class BoolType extends Type ;
20482048
@@ -2293,9 +2293,10 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
22932293 /**
22942294 * Gets the inferred certain type of `n` at `path`.
22952295 *
2296- * This predicate will be included directly in the exposed `inferTypeCertain` predicate.
2296+ * This predicate should include the `inferTypeCertain` predicate from the
2297+ * output of this module, as well as any language-specific additions.
22972298 */
2298- default Type inferTypeCertainSpecific ( AstNode n , TypePath path ) { none ( ) }
2299+ Type inferTypeCertain ( AstNode n , TypePath path ) ;
22992300
23002301 /**
23012302 * Holds if `n1` having type `t` at `path1` implies that `n2` has type `t` at `path2`,
@@ -2304,19 +2305,20 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
23042305 predicate inferStep ( AstNode n1 , TypePath path1 , AstNode n2 , TypePath path2 ) ;
23052306
23062307 /**
2307- * Gets the top-down inferred type of `n` at `path`.
2308+ * Gets the inferred certain type of `n` at `path`.
23082309 *
2309- * Type information is only propagated into nodes with an explicitly unknown
2310- * type .
2310+ * This predicate should include the `inferType` predicate from the output of this module,
2311+ * as well as any language-specific additions .
23112312 */
2312- default Type inferTypeTopDown ( AstNode n , TypePath path ) { none ( ) }
2313+ Type inferType ( AstNode n , TypePath path ) ;
23132314
23142315 /**
2315- * Gets the inferred type of `n` at `path`.
2316+ * Gets the top-down inferred type of `n` at `path`.
23162317 *
2317- * This predicate will be included directly in the exposed `inferType` predicate.
2318+ * Type information is only propagated into nodes with an explicitly unknown
2319+ * type.
23182320 */
2319- Type inferTypeSpecific ( AstNode n , TypePath path ) ;
2321+ default Type inferTypeTopDown ( AstNode n , TypePath path ) { none ( ) }
23202322 }
23212323
23222324 module Make3< InputSig3 Input3> {
@@ -2371,12 +2373,12 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
23712373 Type inferTypeCertain ( AstNode n , TypePath path ) {
23722374 (
23732375 CachedStage:: ref ( ) and
2376+ result = Input3:: inferTypeCertain ( n , path )
2377+ or
23742378 result = inferAnnotatedType ( n , path )
23752379 or
23762380 result = inferTypeFromStepCertain ( n , path )
23772381 or
2378- result = inferTypeCertainSpecific ( n , path )
2379- or
23802382 result = inferLogicalOperationType ( n , path )
23812383 or
23822384 infersCertainTypeAt ( n , path , result .getATypeParameter ( ) )
@@ -2403,6 +2405,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
24032405 private predicate infersCertainTypeAt ( AstNode n , TypePath prefix , TypeParameter tp ) {
24042406 exists ( TypePath path |
24052407 hasInferredCertainType ( n , path ) and
2408+ not path .isEmpty ( ) and // implied by `isSnoc` below, but improves performance slightly
24062409 path .isSnoc ( prefix , tp )
24072410 )
24082411 }
@@ -2481,6 +2484,8 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
24812484 }
24822485
24832486 private Type inferType0 ( AstNode n , TypePath path ) {
2487+ result = Input3:: inferType ( n , path )
2488+ or
24842489 result = inferAnnotatedType ( n , path )
24852490 or
24862491 exists ( LocalVariableDeclaration decl |
@@ -2499,8 +2504,6 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
24992504 result = TopDownTyping< inferCallArgumentTypeTopDown / 2 > :: inferType ( n , path )
25002505 or
25012506 result = TopDownTyping< inferTypeTopDown / 2 > :: inferType ( n , path )
2502- or
2503- result = inferTypeSpecific ( n , path )
25042507 }
25052508
25062509 /**
@@ -2521,26 +2524,26 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
25212524 not Certain:: certainTypeConflict ( n , prefix , path , result )
25222525 )
25232526 or
2524- hasUnknownCertainTypeAt ( n , path ) and
2525- result instanceof UnknownType
2526- or
2527- infersTypeAt ( n , path , result .getATypeParameter ( ) )
2528- }
2529-
2530- private predicate hasUnknownCertainTypeAt ( AstNode n , TypePath path ) {
2527+ // If `n` has an explicitly unknown type at `prefix` and at the same time a certain
2528+ // type at `prefix.suffix`, then extend the unknown type information to any path
2529+ // extending `prefix.suffix` where there is no certain type information
25312530 exists ( TypePath prefix , TypePath suffix , Type certain , TypeParameter tp |
25322531 inferType0 ( n , prefix ) instanceof UnknownType and
25332532 certain = inferTypeCertain ( n , prefix .appendInverse ( suffix ) ) and
25342533 tp = certain .getATypeParameter ( ) and
25352534 path = prefix .append ( suffix ) .append ( TypePath:: singleton ( tp ) ) and
2536- not exists ( inferTypeCertain ( n , path ) )
2535+ not exists ( inferTypeCertain ( n , path ) ) and
2536+ result instanceof UnknownType
25372537 )
2538+ or
2539+ infersTypeAt ( n , path , result .getATypeParameter ( ) )
25382540 }
25392541
25402542 pragma [ nomagic]
25412543 private predicate infersTypeAt ( AstNode n , TypePath prefix , TypeParameter tp ) {
25422544 exists ( TypePath path |
25432545 exists ( inferType ( n , path ) ) and
2546+ not path .isEmpty ( ) and // implied by `isSnoc` below, but improves performance slightly
25442547 path .isSnoc ( prefix , tp )
25452548 )
25462549 }
0 commit comments