Skip to content

Commit 10d13df

Browse files
committed
wip
1 parent de320f2 commit 10d13df

File tree

2 files changed

+25
-9
lines changed

2 files changed

+25
-9
lines changed

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

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2445,37 +2445,53 @@ private module AssocFunctionResolution {
24452445
* resolve to a function in an `impl` block for the type of the receiver.
24462446
*/
24472447
pragma[nomagic]
2448-
predicate hasNoInherentTarget() {
2448+
predicate hasNoInherentTarget0() {
24492449
afc_.hasTrait()
24502450
or
24512451
exists(
24522452
TypePath strippedTypePath, Type strippedType, string name, int arity,
2453-
TypeOption typeQualifier, TypeOption traitQualifier, boolean hasReceiver
2453+
TypeOption typeQualifier, TypeOption traitQualifier, boolean hasReceiver,
2454+
boolean targetMustBeMethod
24542455
|
24552456
// Calls to inherent functions are always of the form `x.m(...)` or `Foo::bar(...)`,
24562457
// where `Foo` is a type. In case `bar` is a method, we can use both the type qualifier
24572458
// and the type of the first argument to rule out candidates
2458-
selfPosAdj_.isTypeQualifier() and hasReceiver = false
2459+
selfPosAdj_.isTypeQualifier() and targetMustBeMethod = false
24592460
or
2460-
selfPosAdj_.asPosition() = 0 and hasReceiver = true
2461+
selfPosAdj_.asPosition() = 0 and targetMustBeMethod = true
24612462
|
2462-
afc_.hasSyntacticInfo(name, arity, typeQualifier, traitQualifier, _) and
2463+
afc_.hasSyntacticInfo(name, arity, typeQualifier, traitQualifier, hasReceiver) and
2464+
(if hasReceiver = true then targetMustBeMethod = true else any()) and
24632465
this.hasSignature(_, selfPosAdj_, strippedTypePath, strippedType, name, arity) and
24642466
forall(Impl i |
24652467
i.isInherent() and
24662468
(
24672469
assocFunctionInfoNonBlanketLikeCheck(_, name, arity, selfPosAdj_, i, _,
2468-
strippedTypePath, strippedType, typeQualifier, traitQualifier, hasReceiver)
2470+
strippedTypePath, strippedType, typeQualifier, traitQualifier, targetMustBeMethod)
24692471
or
24702472
assocFunctionInfoNonBlanketLikeTypeParamCheck(_, name, arity, selfPosAdj_, i, _,
2471-
strippedTypePath, typeQualifier, traitQualifier, hasReceiver)
2473+
strippedTypePath, typeQualifier, traitQualifier, targetMustBeMethod)
24722474
)
24732475
|
24742476
this.hasIncompatibleInherentTarget(i)
24752477
)
24762478
)
24772479
}
24782480

2481+
pragma[nomagic]
2482+
predicate hasNoInherentTarget() {
2483+
this.hasNoInherentTarget0() and
2484+
if exists(getNonTypeParameterTypeQualifier(afc_))
2485+
then
2486+
exists(FunctionPosition selfPosAdj |
2487+
selfPosAdj.isTypeQualifier() and
2488+
MkAssocFunctionCallCand(afc_, selfPosAdj, _, _)
2489+
.(AssocFunctionCallCand)
2490+
.hasNoInherentTarget0()
2491+
)
2492+
else any()
2493+
}
2494+
24792495
pragma[nomagic]
24802496
private predicate selfArgIsInstantiationOf(ImplOrTraitItemNode i, string name, int arity) {
24812497
SelfArgIsInstantiationOf::argIsInstantiationOf(this, i, _) and

rust/ql/test/library-tests/type-inference/overloading.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ mod inherent_before_trait {
421421
// <S<i32>_as_Trait>::foo
422422
fn foo(&self) {
423423
S::foo(self); // $ MISSING: target=S<i32>::foo
424-
S::<i32>::foo(self); // $ MISSING: target=S<i32>::foo
424+
S::<i32>::foo(self); // $ target=S<i32>::foo
425425
self.foo() // $ target=<S<i32>_as_Trait>::foo
426426
}
427427

@@ -437,7 +437,7 @@ mod inherent_before_trait {
437437
// <S<i64>_as_Trait>::foo
438438
fn foo(&self) {
439439
// `S::foo(self);` is not valid
440-
S::<i64>::foo(self); // $ MISSING: target=<S<i64>_as_Trait>::foo
440+
S::<i64>::foo(self); // $ target=<S<i64>_as_Trait>::foo
441441
self.foo() // $ target=<S<i64>_as_Trait>::foo
442442
}
443443

0 commit comments

Comments
 (0)