@@ -961,6 +961,24 @@ private Type getCallExprTypeQualifier(CallExpr ce, TypePath path) {
961961 )
962962}
963963
964+ /**
965+ * Gets the trait qualifier of function call `ce`, if any.
966+ *
967+ * For example, the trait qualifier of `Default::<i32>::default()` is `Default`.
968+ */
969+ pragma [ nomagic]
970+ private Trait getCallExprTraitQualifier ( CallExpr ce ) {
971+ exists ( RelevantPath qualifierPath |
972+ qualifierPath = getCallExprPathQualifier ( ce ) and
973+ result = resolvePath ( qualifierPath ) and
974+ // When the qualifier is `Self` and resolves to a trait, it's inside a
975+ // trait method's default implementation. This is not a dispatch whose
976+ // target is inferred from the type of the receiver, but should always
977+ // resolve to the function in the trait block as path resolution does.
978+ not qualifierPath .isUnqualified ( "Self" )
979+ )
980+ }
981+
964982/**
965983 * Provides functionality related to context-based typing of calls.
966984 */
@@ -1244,14 +1262,17 @@ private module MethodResolution {
12441262
12451263 pragma [ nomagic]
12461264 private predicate methodCallTraitCandidate ( Element mc , Trait trait ) {
1247- exists ( string name , int arity |
1248- mc .( MethodCall ) .hasNameAndArity ( name , arity ) and
1249- methodTraitInfo ( name , arity , trait )
1250- |
1251- not mc .( Call ) .hasTrait ( )
1252- or
1253- trait = mc .( Call ) .getTrait ( )
1254- )
1265+ mc =
1266+ any ( MethodCall mc0 |
1267+ exists ( string name , int arity |
1268+ mc0 .hasNameAndArity ( name , arity ) and
1269+ methodTraitInfo ( name , arity , trait )
1270+ |
1271+ not mc0 .hasTrait ( )
1272+ or
1273+ trait = mc0 .getTrait ( )
1274+ )
1275+ )
12551276 }
12561277
12571278 private module MethodTraitIsVisible = TraitIsVisible< methodCallTraitCandidate / 2 > ;
@@ -1296,7 +1317,7 @@ private module MethodResolution {
12961317 or
12971318 methodCallVisibleTraitCandidate ( mc , i )
12981319 or
1299- i .( ImplItemNode ) .resolveTraitTy ( ) = mc .( Call ) . getTrait ( )
1320+ i .( ImplItemNode ) .resolveTraitTy ( ) = mc .getTrait ( )
13001321 )
13011322 }
13021323
@@ -1323,7 +1344,7 @@ private module MethodResolution {
13231344 |
13241345 methodCallVisibleImplTraitCandidate ( mc , impl )
13251346 or
1326- impl .resolveTraitTy ( ) = mc .( Call ) . getTrait ( )
1347+ impl .resolveTraitTy ( ) = mc .getTrait ( )
13271348 )
13281349 }
13291350
@@ -1354,6 +1375,12 @@ private module MethodResolution {
13541375
13551376 abstract predicate supportsAutoDerefAndBorrow ( ) ;
13561377
1378+ /** Gets the trait targeted by this call, if any. */
1379+ abstract Trait getTrait ( ) ;
1380+
1381+ /** Holds if this call targets a trait. */
1382+ predicate hasTrait ( ) { exists ( this .getTrait ( ) ) }
1383+
13571384 AstNode getNodeAt ( FunctionPosition apos ) {
13581385 result = this .getArgument ( apos .asArgumentPosition ( ) )
13591386 or
@@ -1611,6 +1638,8 @@ private module MethodResolution {
16111638 }
16121639
16131640 override predicate supportsAutoDerefAndBorrow ( ) { any ( ) }
1641+
1642+ override Trait getTrait ( ) { none ( ) }
16141643 }
16151644
16161645 private class MethodCallIndexExpr extends MethodCall , IndexExpr {
@@ -1629,6 +1658,8 @@ private module MethodResolution {
16291658 }
16301659
16311660 override predicate supportsAutoDerefAndBorrow ( ) { any ( ) }
1661+
1662+ override Trait getTrait ( ) { result .getCanonicalPath ( ) = "core::ops::index::Index" }
16321663 }
16331664
16341665 private class MethodCallCallExpr extends MethodCall , CallExpr {
@@ -1672,6 +1703,8 @@ private module MethodResolution {
16721703 }
16731704
16741705 override predicate supportsAutoDerefAndBorrow ( ) { none ( ) }
1706+
1707+ override Trait getTrait ( ) { result = getCallExprTraitQualifier ( this ) }
16751708 }
16761709
16771710 final class MethodCallOperation extends MethodCall , Operation {
@@ -1712,6 +1745,8 @@ private module MethodResolution {
17121745 }
17131746
17141747 override predicate supportsAutoDerefAndBorrow ( ) { none ( ) }
1748+
1749+ override Trait getTrait ( ) { this .isOverloaded ( result , _, _) }
17151750 }
17161751
17171752 pragma [ nomagic]
@@ -2282,14 +2317,17 @@ private module NonMethodResolution {
22822317
22832318 pragma [ nomagic]
22842319 private predicate blanketLikeCallTraitCandidate ( Element fc , Trait trait ) {
2285- exists ( string name , int arity |
2286- fc .( NonMethodCall ) .hasNameAndArity ( name , arity ) and
2287- functionInfoBlanketLikeRelevantPos ( _, name , arity , _, trait , _, _, _, _)
2288- |
2289- not fc .( Call ) .hasTrait ( )
2290- or
2291- trait = fc .( Call ) .getTrait ( )
2292- )
2320+ fc =
2321+ any ( NonMethodCall nmc |
2322+ exists ( string name , int arity |
2323+ nmc .hasNameAndArity ( name , arity ) and
2324+ functionInfoBlanketLikeRelevantPos ( _, name , arity , _, trait , _, _, _, _)
2325+ |
2326+ not nmc .hasTrait ( )
2327+ or
2328+ trait = nmc .getTrait ( )
2329+ )
2330+ )
22932331 }
22942332
22952333 private module BlanketTraitIsVisible = TraitIsVisible< blanketLikeCallTraitCandidate / 2 > ;
@@ -2331,9 +2369,15 @@ private module NonMethodResolution {
23312369 )
23322370 }
23332371
2372+ /** Gets the trait targeted by this call, if any. */
2373+ Trait getTrait ( ) { result = getCallExprTraitQualifier ( this ) }
2374+
2375+ /** Holds if this call targets a trait. */
2376+ predicate hasTrait ( ) { exists ( this .getTrait ( ) ) }
2377+
23342378 pragma [ nomagic]
23352379 NonMethodFunction resolveAssocCallTargetCand ( ImplItemNode i ) {
2336- not this .( Call ) . hasTrait ( ) and
2380+ not this .hasTrait ( ) and
23372381 result = this .getPathResolutionResolved ( ) and
23382382 result = i .getASuccessor ( _)
23392383 or
@@ -2366,15 +2410,15 @@ private module NonMethodResolution {
23662410 pragma [ nomagic]
23672411 predicate hasTraitResolved ( TraitItemNode trait , NonMethodFunction resolved ) {
23682412 resolved = this .getPathResolutionResolved ( ) and
2369- trait = this .( Call ) . getTrait ( )
2413+ trait = this .getTrait ( )
23702414 }
23712415
23722416 /**
23732417 * Gets the target of this call, which can be resolved using only path resolution.
23742418 */
23752419 pragma [ nomagic]
23762420 ItemNode resolveCallTargetViaPathResolution ( ) {
2377- not this .( Call ) . hasTrait ( ) and
2421+ not this .hasTrait ( ) and
23782422 result = this .getPathResolutionResolved ( ) and
23792423 not FunctionOverloading:: functionResolutionDependsOnArgument ( _, result , _, _, _)
23802424 }
@@ -2399,7 +2443,7 @@ private module NonMethodResolution {
23992443
24002444 pragma [ nomagic]
24012445 NonMethodFunction resolveTraitFunctionViaPathResolution ( TraitItemNode trait ) {
2402- this .( Call ) . hasTrait ( ) and
2446+ this .hasTrait ( ) and
24032447 result = this .getPathResolutionResolved ( ) and
24042448 result = trait .getASuccessor ( _)
24052449 }
0 commit comments