@@ -2669,6 +2669,21 @@ private predicate inferMethodCallType =
26692669 * "calls" to tuple variants and tuple structs.
26702670 */
26712671private module NonMethodResolution {
2672+ pragma [ nomagic]
2673+ private predicate traitFunctionResolutionDependsOnArgument0 (
2674+ TraitItemNode trait , NonMethodFunction traitFunction , FunctionPosition pos , ImplItemNode impl ,
2675+ NonMethodFunction implFunction , TypePath path , TypeParameter traitTp
2676+ ) {
2677+ implFunction = impl .getAnAssocItem ( ) and
2678+ implFunction .implements ( traitFunction ) and
2679+ FunctionOverloading:: traitTypeParameterOccurrence ( trait , traitFunction , _, pos , path , traitTp ) and
2680+ (
2681+ traitTp = TSelfTypeParameter ( trait )
2682+ or
2683+ FunctionOverloading:: functionResolutionDependsOnArgument ( impl , implFunction , traitTp , pos )
2684+ )
2685+ }
2686+
26722687 /**
26732688 * Holds if resolving the function `implFunction` in `impl` requires inspecting
26742689 * the type of applied _arguments_ or possibly knowing the return type.
@@ -2685,13 +2700,44 @@ private module NonMethodResolution {
26852700 TraitItemNode trait , NonMethodFunction traitFunction , FunctionPosition pos , ImplItemNode impl ,
26862701 NonMethodFunction implFunction , TypePath path , TypeParameter traitTp
26872702 ) {
2688- implFunction = impl .getAnAssocItem ( ) and
2689- implFunction .implements ( traitFunction ) and
2690- FunctionOverloading:: traitTypeParameterOccurrence ( trait , traitFunction , _, pos , path , traitTp ) and
2691- (
2692- traitTp = TSelfTypeParameter ( trait )
2703+ traitFunctionResolutionDependsOnArgument0 ( trait , traitFunction , pos , impl , implFunction , path ,
2704+ traitTp ) and
2705+ // Exclude functions where we cannot resolve all relevant type mentions; this allows
2706+ // for blanket implementations to be applied in those cases
2707+ forall ( TypeParameter traitTp0 |
2708+ traitFunctionResolutionDependsOnArgument0 ( trait , traitFunction , _, impl , implFunction , _,
2709+ traitTp0 )
2710+ |
2711+ exists ( FunctionPosition pos0 , TypePath path0 |
2712+ traitFunctionResolutionDependsOnArgument0 ( trait , traitFunction , pos0 , impl , implFunction ,
2713+ path0 , traitTp0 ) and
2714+ exists ( getAssocFunctionTypeInclNonMethodSelfAt ( implFunction , impl , pos0 , path0 ) )
2715+ )
2716+ )
2717+ }
2718+
2719+ /**
2720+ * Holds if `f` inside `i` either implements trait function `traitFunction` inside `trait`
2721+ * or is equal to `traitFunction`, and the type of `f` at `pos` and `path` is `t`, which
2722+ * corresponds to the `Self` type parameter of `trait`.
2723+ */
2724+ pragma [ nomagic]
2725+ private predicate traitFunctionHasSelfType (
2726+ TraitItemNode trait , NonMethodFunction traitFunction , FunctionPosition pos , TypePath path ,
2727+ Type t , ImplOrTraitItemNode i , NonMethodFunction f
2728+ ) {
2729+ exists ( ImplItemNode impl , NonMethodFunction implFunction , AssocFunctionType aft |
2730+ traitFunctionResolutionDependsOnArgument ( trait , traitFunction , pos , impl , implFunction , path ,
2731+ TSelfTypeParameter ( trait ) ) and
2732+ aft .appliesTo ( f , i , pos ) and
2733+ t = aft .getTypeAt ( path )
2734+ |
2735+ i = trait and
2736+ f = traitFunction
26932737 or
2694- FunctionOverloading:: functionResolutionDependsOnArgument ( impl , implFunction , traitTp , pos )
2738+ i = impl and
2739+ f = implFunction and
2740+ not BlanketImplementation:: isBlanketLike ( i , _, _)
26952741 )
26962742 }
26972743
@@ -2848,10 +2894,25 @@ private module NonMethodResolution {
28482894 predicate hasNoCompatibleNonBlanketTarget ( ) {
28492895 this .resolveCallTargetBlanketLikeCand ( _, _, _, _) and
28502896 not exists ( this .resolveCallTargetViaPathResolution ( ) ) and
2851- forall ( ImplOrTraitItemNode i , Function f |
2852- this .( NonMethodArgsAreInstantiationsOfNonBlanketInput:: Call ) .hasTargetCand ( i , f )
2853- |
2897+ forall ( ImplOrTraitItemNode i , Function f | f = this .resolveCallTargetNonBlanketCand ( i ) |
28542898 NonMethodArgsAreInstantiationsOfNonBlanket:: argsAreNotInstantiationsOf ( this , i , f )
2899+ ) and
2900+ (
2901+ not this .hasTraitResolved ( _, _)
2902+ or
2903+ exists (
2904+ TraitItemNode trait , NonMethodFunction resolved , FunctionPosition pos , TypePath path ,
2905+ Type t
2906+ |
2907+ this .( NonMethodArgsAreInstantiationsOfNonBlanketInput:: Call )
2908+ .hasTraitResolvedSelfType ( trait , resolved , pos , path , t )
2909+ |
2910+ forall ( ImplOrTraitItemNode i , Function f |
2911+ traitFunctionHasSelfType ( trait , resolved , pos , path , t , i , f )
2912+ |
2913+ NonMethodArgsAreInstantiationsOfNonBlanket:: argsAreNotInstantiationsOf ( this , i , f )
2914+ )
2915+ )
28552916 )
28562917 }
28572918
@@ -2994,29 +3055,30 @@ private module NonMethodResolution {
29943055 result = getArgType ( this , pos , path , _)
29953056 }
29963057
3058+ /**
3059+ * Holds if this call is of the form `Trait::function(args)`, and the type at `pos` and
3060+ * `path` matches the `Self` type parameter of `Trait`.
3061+ */
3062+ pragma [ nomagic]
3063+ predicate hasTraitResolvedSelfType (
3064+ TraitItemNode trait , NonMethodFunction function , FunctionPosition pos , TypePath path , Type t
3065+ ) {
3066+ this .hasTraitResolved ( trait , function ) and
3067+ FunctionOverloading:: traitTypeParameterOccurrence ( trait , function , _, pos , path ,
3068+ TSelfTypeParameter ( trait ) ) and
3069+ t = substituteLookupTraits ( this .getArgType ( pos , path ) ) and
3070+ t != TUnknownType ( )
3071+ }
3072+
29973073 predicate hasTargetCand ( ImplOrTraitItemNode i , Function f ) {
29983074 f = this .resolveCallTargetNonBlanketCand ( i )
29993075 or
3000- exists ( TraitItemNode trait , NonMethodFunction resolved , ImplItemNode i1 , Function f1 |
3001- this .hasTraitResolved ( trait , resolved ) and
3002- traitFunctionResolutionDependsOnArgument ( trait , resolved , _, i1 , f1 , _, _) and
3003- not BlanketImplementation:: isBlanketLike ( i , _, _)
3076+ exists (
3077+ TraitItemNode trait , NonMethodFunction resolved , FunctionPosition pos , TypePath path ,
3078+ Type t
30043079 |
3005- f = resolved and
3006- i = trait
3007- or
3008- f = f1 and
3009- i = i1 and
3010- // Exclude functions where we cannot resolve all relevant type mentions; this allows
3011- // for blanket implementations to be applied in those cases
3012- forall ( TypeParameter traitTp |
3013- traitFunctionResolutionDependsOnArgument ( trait , resolved , _, i1 , f1 , _, traitTp )
3014- |
3015- exists ( FunctionPosition pos , TypePath path |
3016- traitFunctionResolutionDependsOnArgument ( trait , resolved , pos , i1 , f1 , path , traitTp ) and
3017- exists ( getAssocFunctionTypeInclNonMethodSelfAt ( f , i , pos , path ) )
3018- )
3019- )
3080+ this .hasTraitResolvedSelfType ( trait , resolved , pos , path , t ) and
3081+ traitFunctionHasSelfType ( trait , resolved , pos , path , t , i , f )
30203082 )
30213083 }
30223084 }
0 commit comments