@@ -955,7 +955,7 @@ private module ContextTyping {
955955 */
956956 bindingset [ this , i, target]
957957 predicate isContextTypedAt (
958- ImplOrTraitItemNode i , Function target , TypePath path , FunctionPosition pos
958+ ImplOrTraitItemNode i , Function target , FunctionPosition pos , TypePath path
959959 ) {
960960 exists ( TypeParameter tp |
961961 assocFunctionReturnContextTypedAt ( i , target , pos , path , tp ) and
@@ -2090,6 +2090,17 @@ private module MethodCallMatchingInput implements MatchingWithEnvironmentInputSi
20902090 }
20912091
20922092 Declaration getTarget ( string derefChainBorrow ) { result = this .getTarget ( _, derefChainBorrow ) }
2093+
2094+ /**
2095+ * Holds if the return type of this call at `path` may have to be inferred
2096+ * from the context.
2097+ */
2098+ pragma [ nomagic]
2099+ predicate isContextTypedAt ( string derefChainBorrow , FunctionPosition pos , TypePath path ) {
2100+ exists ( ImplOrTraitItemNode i |
2101+ this .isContextTypedAt ( i , this .getTarget ( i , derefChainBorrow ) , pos , path )
2102+ )
2103+ }
20932104 }
20942105}
20952106
@@ -2105,10 +2116,8 @@ private Type inferMethodCallType0(
21052116 (
21062117 result = MethodCallMatching:: inferAccessType ( a , derefChainBorrow , apos , path0 )
21072118 or
2108- exists ( ImplOrTraitItemNode i |
2109- a .isContextTypedAt ( i , a .getTarget ( i , derefChainBorrow ) , path0 , apos ) and
2110- result = TContextType ( )
2111- )
2119+ a .isContextTypedAt ( derefChainBorrow , apos , path0 ) and
2120+ result = TContextType ( )
21122121 )
21132122 |
21142123 if
@@ -2585,6 +2594,35 @@ private module NonMethodCallMatchingInput implements MatchingInputSig {
25852594 Declaration getTarget ( ) {
25862595 result = this .resolveCallTarget ( ) // potential mutual recursion; resolving some associated function calls requires resolving types
25872596 }
2597+
2598+ /**
2599+ * Holds if the return type of this call at `path` may have to be inferred
2600+ * from the context.
2601+ */
2602+ pragma [ nomagic]
2603+ predicate isContextTypedAt ( FunctionPosition pos , TypePath path ) {
2604+ exists ( ImplOrTraitItemNode i |
2605+ this .isContextTypedAt ( i ,
2606+ [
2607+ this .resolveCallTargetViaPathResolution ( ) .( NonMethodFunction ) ,
2608+ this .resolveCallTargetViaTypeInference ( i ) ,
2609+ this .resolveTraitFunctionViaPathResolution ( i )
2610+ ] , pos , path )
2611+ )
2612+ or
2613+ // Tuple declarations, such as `None`, may also be context typed
2614+ exists ( TupleDeclaration td , TypeParameter tp |
2615+ td = this .resolveCallTargetViaPathResolution ( ) and
2616+ pos .isReturn ( ) and
2617+ tp = td .getReturnType ( path ) and
2618+ not tp = td .getParameterType ( _, _) and
2619+ // check that no explicit type arguments have been supplied for `tp`
2620+ not exists ( TypeArgumentPosition tapos |
2621+ exists ( this .getTypeArgument ( tapos , _) ) and
2622+ TTypeParamTypeParameter ( tapos .asTypeParam ( ) ) = tp
2623+ )
2624+ )
2625+ }
25882626 }
25892627}
25902628
@@ -2597,15 +2635,8 @@ private Type inferNonMethodCallType0(
25972635 exists ( NonMethodCallMatchingInput:: Access a | n = a .getNodeAt ( apos ) |
25982636 result = NonMethodCallMatching:: inferAccessType ( a , apos , path )
25992637 or
2600- exists ( ImplOrTraitItemNode i |
2601- a .isContextTypedAt ( i ,
2602- [
2603- a .resolveCallTargetViaPathResolution ( ) .( NonMethodFunction ) ,
2604- a .resolveCallTargetViaTypeInference ( i ) ,
2605- a .resolveTraitFunctionViaPathResolution ( i )
2606- ] , path , apos ) and
2607- result = TContextType ( )
2608- )
2638+ a .isContextTypedAt ( apos , path ) and
2639+ result = TContextType ( )
26092640 )
26102641}
26112642
0 commit comments