Skip to content

Commit 2bfb8d4

Browse files
committed
Rust: Remove {get,has}Trait from Call
1 parent f829afd commit 2bfb8d4

File tree

2 files changed

+66
-50
lines changed

2 files changed

+66
-50
lines changed

rust/ql/lib/codeql/rust/elements/internal/CallImpl.qll

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,6 @@ module Impl {
3434
* called in Rust.
3535
*/
3636
abstract class Call extends ExprImpl::Expr {
37-
/** Gets the trait targeted by this call, if any. */
38-
abstract Trait getTrait();
39-
40-
/** Holds if this call targets a trait. */
41-
predicate hasTrait() { exists(this.getTrait()) }
42-
4337
/** Gets the name of the method called if this call is a method call. */
4438
abstract string getMethodName();
4539

@@ -75,18 +69,6 @@ module Impl {
7569
qualifier = path.getQualifier()
7670
}
7771

78-
private predicate callHasTraitQualifier(CallExpr call, Trait qualifier) {
79-
exists(RelevantPath qualifierPath |
80-
callHasQualifier(call, _, qualifierPath) and
81-
qualifier = resolvePath(qualifierPath) and
82-
// When the qualifier is `Self` and resolves to a trait, it's inside a
83-
// trait method's default implementation. This is not a dispatch whose
84-
// target is inferred from the type of the receiver, but should always
85-
// resolve to the function in the trait block as path resolution does.
86-
not qualifierPath.isUnqualified("Self")
87-
)
88-
}
89-
9072
/** Holds if the call expression dispatches to a method. */
9173
private predicate callIsMethodCall(
9274
CallExpr call, Path qualifier, string methodName, boolean selfIsRef
@@ -107,8 +89,6 @@ module Impl {
10789

10890
override string getMethodName() { none() }
10991

110-
override Trait getTrait() { callHasTraitQualifier(this, result) }
111-
11292
override Expr getArgument(ArgumentPosition pos) {
11393
result = super.getArgList().getArg(pos.asPosition())
11494
}
@@ -129,8 +109,6 @@ module Impl {
129109

130110
override string getMethodName() { result = methodName }
131111

132-
override Trait getTrait() { callHasTraitQualifier(this, result) }
133-
134112
override Expr getArgument(ArgumentPosition pos) {
135113
pos.isSelf() and result = super.getArgList().getArg(0)
136114
or
@@ -141,8 +119,6 @@ module Impl {
141119
private class MethodCallExprCall extends Call instanceof MethodCallExpr {
142120
override string getMethodName() { result = super.getIdentifier().getText() }
143121

144-
override Trait getTrait() { none() }
145-
146122
override Expr getArgument(ArgumentPosition pos) {
147123
pos.isSelf() and result = this.(MethodCallExpr).getReceiver()
148124
or
@@ -159,8 +135,6 @@ module Impl {
159135

160136
override string getMethodName() { result = methodName }
161137

162-
override Trait getTrait() { result = trait }
163-
164138
override Expr getArgument(ArgumentPosition pos) {
165139
pos.isSelf() and result = super.getOperand(0)
166140
or
@@ -171,8 +145,6 @@ module Impl {
171145
private class IndexCall extends Call instanceof IndexExpr {
172146
override string getMethodName() { result = "index" }
173147

174-
override Trait getTrait() { result.getCanonicalPath() = "core::ops::index::Index" }
175-
176148
override Expr getArgument(ArgumentPosition pos) {
177149
pos.isSelf() and result = super.getBase()
178150
or

rust/ql/lib/codeql/rust/internal/TypeInference.qll

Lines changed: 66 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)