@@ -1096,10 +1096,10 @@ private module AssocFunctionResolution {
10961096 }
10971097
10981098 pragma [ nomagic]
1099- predicate resolutionDependsOnReturnType ( ) {
1099+ predicate resolutionDependsOnReturnType ( TypePath path ) {
11001100 exists ( AssocFunctionCallCand afcc |
11011101 afcc = MkAssocFunctionCallCand ( this , _, _, _) and
1102- afcc .resolutionDependsOnReturnType ( )
1102+ afcc .resolutionDependsOnReturnType ( path )
11031103 )
11041104 }
11051105
@@ -1578,23 +1578,65 @@ private module AssocFunctionResolution {
15781578 pragma [ nomagic]
15791579 AssocFunctionDeclaration resolveCallTarget ( ImplOrTraitItemNode i ) {
15801580 result = this .resolveCallTargetCand ( i ) and
1581- not FunctionOverloading:: functionResolutionDependsOnArgument ( i , result , _, _)
1581+ not FunctionOverloading:: functionResolutionDependsOnArgument ( i , result , _, _, _ )
15821582 or
15831583 OverloadedCallArgsAreInstantiationsOf:: argsAreInstantiationsOf ( this , i , result )
15841584 }
15851585
15861586 pragma [ nomagic]
1587- predicate resolutionDependsOnReturnType ( ) {
1588- exists (
1589- ImplOrTraitItemNode i , AssocFunctionDeclaration target , TypeParameter tp ,
1590- FunctionPosition pos
1591- |
1587+ private predicate hasUnknownTypeAtPos ( int pos , TypePath path ) {
1588+ exists ( FunctionPosition pos0 |
1589+ inferType ( afc_ .getNodeAt ( pos0 ) , path ) = TUnknownType ( ) and
1590+ pos = pos0 .asPosition ( )
1591+ )
1592+ }
1593+
1594+ pragma [ nomagic]
1595+ private predicate resolutionDependsOnReturnTypeCand (
1596+ ImplOrTraitItemNode i , AssocFunctionDeclaration target , TypeParameter traitTp , TypePath path
1597+ ) {
1598+ exists ( FunctionPosition pos |
15921599 target = this .resolveCallTargetCand ( i ) and
1593- FunctionOverloading:: functionResolutionDependsOnArgument ( i , target , tp , pos ) and
1600+ FunctionOverloading:: functionResolutionDependsOnArgument ( i , target , traitTp , pos , path ) and
15941601 pos .isReturn ( )
15951602 )
15961603 }
15971604
1605+ pragma [ nomagic]
1606+ private predicate resolutionDependsOnPositionalAndReturnTypeCand (
1607+ ImplOrTraitItemNode i , AssocFunctionDeclaration target , TypePath path , int pos0 ,
1608+ TypePath prefix
1609+ ) {
1610+ exists ( TypeParameter traitTp , TypePath path0 |
1611+ this .resolutionDependsOnReturnTypeCand ( i , target , traitTp , path ) and
1612+ FunctionOverloading:: functionResolutionDependsOnPositionalArgumentCand ( i , target , _,
1613+ traitTp , pos0 , path0 ) and
1614+ prefix = path0 .getAPrefix ( )
1615+ )
1616+ }
1617+
1618+ /**
1619+ * Holds if resolving this call requires contextual information about the
1620+ * return type at `path`.
1621+ */
1622+ pragma [ nomagic]
1623+ predicate resolutionDependsOnReturnType ( TypePath path ) {
1624+ exists ( ImplOrTraitItemNode i , AssocFunctionDeclaration target |
1625+ exists ( TypeParameter traitTp |
1626+ this .resolutionDependsOnReturnTypeCand ( i , target , traitTp , path ) and
1627+ not FunctionOverloading:: functionResolutionDependsOnPositionalArgumentCand ( i , target , _,
1628+ traitTp , _, _)
1629+ )
1630+ or
1631+ // when `traitTp` is also mentioned in a parameter, require that typing of the
1632+ // corresponding argument also needs contextual typing
1633+ exists ( int pos0 , TypePath prefix |
1634+ this .resolutionDependsOnPositionalAndReturnTypeCand ( i , target , path , pos0 , prefix ) and
1635+ this .hasUnknownTypeAtPos ( pos0 , prefix )
1636+ )
1637+ )
1638+ }
1639+
15981640 string toString ( ) {
15991641 result = afc_ + " at " + selfPos_ + " [" + derefChain .toString ( ) + "; " + borrow + "]"
16001642 }
@@ -1819,7 +1861,7 @@ private module AssocFunctionResolution {
18191861 ArgsAreInstantiationsOfInputSig
18201862 {
18211863 predicate toCheck ( ImplOrTraitItemNode i , Function f , TypeParameter traitTp , FunctionPosition pos ) {
1822- FunctionOverloading:: functionResolutionDependsOnArgument ( i , f , traitTp , pos )
1864+ FunctionOverloading:: functionResolutionDependsOnArgument ( i , f , traitTp , pos , _ )
18231865 }
18241866
18251867 class Call extends AssocFunctionCallCand {
@@ -3043,12 +3085,10 @@ private module Input3 implements InputSig3 {
30433085 private Type inferUnknownType ( AstNode n , TypePath path ) {
30443086 result = TUnknownType ( ) and
30453087 (
3088+ n .( AssocFunctionResolution:: AssocFunctionCall ) .resolutionDependsOnReturnType ( path )
3089+ or
30463090 path .isEmpty ( ) and
3047- (
3048- n .( AssocFunctionResolution:: AssocFunctionCall ) .resolutionDependsOnReturnType ( )
3049- or
3050- isPanicMacroCall ( n )
3051- )
3091+ isPanicMacroCall ( n )
30523092 or
30533093 n .( ArrayListExpr ) .getNumberOfExprs ( ) = 0 and
30543094 path = TypePath:: singleton ( getArrayTypeParameter ( ) )
0 commit comments