@@ -2440,42 +2440,61 @@ private module AssocFunctionResolution {
24402440 SelfArgIsNotInstantiationOfInherent:: argIsNotInstantiationOf ( this , impl , _, _)
24412441 }
24422442
2443- /**
2444- * Holds if this function call has no inherent target, i.e., it does not
2445- * resolve to a function in an `impl` block for the type of the receiver.
2446- */
24472443 pragma [ nomagic]
2448- predicate hasNoInherentTarget ( ) {
2449- afc_ .hasTrait ( )
2450- or
2444+ predicate hasNoInherentTargetCheck ( ) {
24512445 exists (
24522446 TypePath strippedTypePath , Type strippedType , string name , int arity ,
2453- TypeOption typeQualifier , TypeOption traitQualifier , boolean hasReceiver
2447+ TypeOption typeQualifier , TypeOption traitQualifier , boolean hasReceiver ,
2448+ boolean targetMustBeMethod
24542449 |
24552450 // Calls to inherent functions are always of the form `x.m(...)` or `Foo::bar(...)`,
24562451 // where `Foo` is a type. In case `bar` is a method, we can use both the type qualifier
24572452 // and the type of the first argument to rule out candidates
2458- selfPosAdj_ .isTypeQualifier ( ) and hasReceiver = false
2453+ selfPosAdj_ .isTypeQualifier ( ) and targetMustBeMethod = false
24592454 or
2460- selfPosAdj_ .asPosition ( ) = 0 and hasReceiver = true
2455+ selfPosAdj_ .asPosition ( ) = 0 and targetMustBeMethod = true
24612456 |
2462- afc_ .hasSyntacticInfo ( name , arity , typeQualifier , traitQualifier , _) and
2457+ afc_ .hasSyntacticInfo ( name , arity , typeQualifier , traitQualifier , hasReceiver ) and
2458+ ( if hasReceiver = true then targetMustBeMethod = true else any ( ) ) and
24632459 this .hasSignature ( _, selfPosAdj_ , strippedTypePath , strippedType , name , arity ) and
24642460 forall ( Impl i |
24652461 i .isInherent ( ) and
24662462 (
24672463 assocFunctionInfoNonBlanketLikeCheck ( _, name , arity , selfPosAdj_ , i , _,
2468- strippedTypePath , strippedType , typeQualifier , traitQualifier , hasReceiver )
2464+ strippedTypePath , strippedType , typeQualifier , traitQualifier , targetMustBeMethod )
24692465 or
24702466 assocFunctionInfoNonBlanketLikeTypeParamCheck ( _, name , arity , selfPosAdj_ , i , _,
2471- strippedTypePath , typeQualifier , traitQualifier , hasReceiver )
2467+ strippedTypePath , typeQualifier , traitQualifier , targetMustBeMethod )
24722468 )
24732469 |
24742470 this .hasIncompatibleInherentTarget ( i )
24752471 )
24762472 )
24772473 }
24782474
2475+ /**
2476+ * Holds if this function call has no inherent target, i.e., it does not
2477+ * resolve to a function in an `impl` block for the type of the receiver.
2478+ */
2479+ pragma [ nomagic]
2480+ predicate hasNoInherentTarget ( ) {
2481+ afc_ .hasTrait ( )
2482+ or
2483+ this .hasNoInherentTargetCheck ( ) and
2484+ if exists ( getNonTypeParameterTypeQualifier ( afc_ ) ) and not selfPosAdj_ .isTypeQualifier ( )
2485+ then
2486+ // If this call is of the form `Foo::bar(x)` and we are resolving with respect to the type
2487+ // of `x`, then we additionally need to check that the type qualifier does not give rise
2488+ // to an inherent target
2489+ exists ( FunctionPosition typeQualifierPos |
2490+ typeQualifierPos .isTypeQualifier ( ) and
2491+ MkAssocFunctionCallCand ( afc_ , typeQualifierPos , _, _)
2492+ .( AssocFunctionCallCand )
2493+ .hasNoInherentTargetCheck ( )
2494+ )
2495+ else any ( )
2496+ }
2497+
24792498 pragma [ nomagic]
24802499 private predicate selfArgIsInstantiationOf ( ImplOrTraitItemNode i , string name , int arity ) {
24812500 SelfArgIsInstantiationOf:: argIsInstantiationOf ( this , i , _) and
0 commit comments