@@ -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