Skip to content

Commit 4bd25e7

Browse files
committed
Rust: Distinguish path resolution expectations from type inference expectations
1 parent 32aaac2 commit 4bd25e7

File tree

3 files changed

+55
-37
lines changed

3 files changed

+55
-37
lines changed

rust/ql/lib/utils/test/PathResolutionInlineExpectationsTest.qll

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ private import codeql.rust.internal.typeinference.TypeInference
88
private import utils.test.InlineExpectationsTest
99

1010
private module ResolveTest implements TestSig {
11-
string getARelevantTag() { result = "item" }
11+
string getARelevantTag() { result = ["item", "target", "item_only"] }
1212

1313
private predicate itemAt(ItemNode i, string filepath, int line) {
1414
i.getLocation().hasLocationInfo(filepath, _, _, line, _)
@@ -36,19 +36,37 @@ private module ResolveTest implements TestSig {
3636
)
3737
}
3838

39+
private Item getCallExprTarget(Path p) {
40+
exists(CallExpr ce |
41+
p = ce.getFunction().(PathExpr).getPath() and
42+
result = ce.getResolvedTarget()
43+
)
44+
}
45+
3946
predicate hasActualResult(Location location, string element, string tag, string value) {
40-
exists(AstNode n |
47+
exists(AstNode n, ItemNode i |
4148
not n = any(Path parent).getQualifier() and
4249
location = n.getLocation() and
4350
n.fromSource() and
4451
not location.getFile().getAbsolutePath().matches("%proc_macro.rs") and
4552
not n.isFromMacroExpansion() and
4653
element = n.toString() and
47-
tag = "item"
54+
item(i, value)
4855
|
49-
item(resolvePath(n), value)
56+
i = resolvePath(n) and
57+
(
58+
if exists(getCallExprTarget(n)) and not i = getCallExprTarget(n)
59+
then tag = "item_only"
60+
else tag = "item"
61+
)
5062
or
51-
item(n.(MethodCallExpr).getStaticTarget(), value)
63+
tag = "target" and
64+
(
65+
i = n.(MethodCallExpr).getStaticTarget()
66+
or
67+
i = getCallExprTarget(n) and
68+
not i = resolvePath(n)
69+
)
5270
)
5371
}
5472
}

rust/ql/test/library-tests/path-resolution/main.rs

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -189,18 +189,18 @@ mod m8 {
189189
#[rustfmt::skip]
190190
pub fn g() {
191191
let x = MyStruct {}; // $ item=I50
192-
MyTrait::f(&x); // $ item=I48
192+
MyTrait::f(&x); // $ item_only=I48 target=I53
193193
MyStruct::f(&x); // $ item=I53
194194
<MyStruct as // $ item=I50
195195
MyTrait // $ item=I47
196196
> // $ MISSING: item=52
197-
::f(&x); // $ item=I48
197+
::f(&x); // $ item_only=I48 target=I53
198198
let x = MyStruct {}; // $ item=I50
199-
x.f(); // $ item=I53
199+
x.f(); // $ target=I53
200200
let x = MyStruct {}; // $ item=I50
201-
x.g(); // $ item=I54
201+
x.g(); // $ target=I54
202202
MyStruct::h(&x); // $ item=I74
203-
x.h(); // $ item=I74
203+
x.h(); // $ target=I74
204204
} // I55
205205
} // I46
206206

@@ -316,7 +316,7 @@ mod m15 {
316316
fn f(&self) {
317317
println!("m15::Trait2::f"); // $ item=println
318318
Self::g(self); // $ item=I80
319-
self.g(); // $ item=I80
319+
self.g(); // $ target=I80
320320
} // Trait2::f
321321
} // I82
322322

@@ -331,7 +331,7 @@ mod m15 {
331331
fn f(&self, tt: TT) { // $ item=ITT
332332
Self::g(self); // $ item=I80
333333
TT::g(&tt); // $ item=I80
334-
self.g(); // $ item=I80
334+
self.g(); // $ target=I80
335335
}
336336
} // ITrait3
337337

@@ -343,7 +343,7 @@ mod m15 {
343343
fn f(&self) {
344344
println!("m15::<S as Trait1>::f"); // $ item=println
345345
Self::g(self); // $ item=I77
346-
self.g(); // $ item=I77
346+
self.g(); // $ target=I77
347347
} // I76
348348

349349
fn g(&self) {
@@ -365,12 +365,12 @@ mod m15 {
365365
let x = S; // $ item=I81
366366
<S // $ item=I81
367367
as Trait1 // $ item=I79
368-
>::f(&x); // $ item=Trait1::f
368+
>::f(&x); // $ item_only=Trait1::f target=I76
369369
<S // $ item=I81
370370
as Trait2 // $ item=I82
371-
>::f(&x); // $ item=Trait2::f
371+
>::f(&x); // $ item_only=Trait2::f target=I78
372372
S::g(&x); // $ item=I77
373-
x.g(); // $ item=I77
373+
x.g(); // $ target=I77
374374
} // I75
375375
}
376376

@@ -383,12 +383,12 @@ mod m16 {
383383
; // Trait1::f
384384

385385
fn g(&self) -> T {// $ item=I84
386-
self.f() // $ item=Trait1::f
386+
self.f() // $ target=Trait1::f
387387
} // I85
388388

389389
fn h(&self) -> T { // $ item=I84
390390
Self::g(&self); // $ item=I85
391-
self.g() // $ item=I85
391+
self.g() // $ target=I85
392392
} // I96
393393

394394
const c: T // $ item=I84
@@ -405,7 +405,7 @@ mod m16 {
405405
fn f(&self) -> T { // $ item=I87
406406
println!("m16::Trait2::f"); // $ item=println
407407
Self::g(self); // $ item=I85
408-
self.g(); // $ item=I85
408+
self.g(); // $ target=I85
409409
Self::c // $ item=I94
410410
} // Trait2::f
411411
} // I89
@@ -420,7 +420,7 @@ mod m16 {
420420
fn f(&self) -> S { // $ item=I90
421421
println!("m16::<S as Trait1<S>>::f"); // $ item=println
422422
Self::g(self); // $ item=I92
423-
self.g() // $ item=I92
423+
self.g() // $ target=I92
424424
} // I91
425425

426426
fn g(&self) -> S { // $ item=I90
@@ -452,16 +452,16 @@ mod m16 {
452452
as Trait1<
453453
S // $ item=I90
454454
> // $ item=I86
455-
>::f(&x); // $ item=Trait1::f
455+
>::f(&x); // $ item_only=Trait1::f target=I91
456456
<S // $ item=I90
457457
as Trait2<
458458
S // $ item=I90
459459
> // $ item=I89
460-
>::f(&x); // $ item=Trait2::f
460+
>::f(&x); // $ item_only=Trait2::f target=I93
461461
S::g(&x); // $ item=I92
462-
x.g(); // $ item=I92
462+
x.g(); // $ target=I92
463463
S::h(&x); // $ item=I96
464-
x.h(); // $ item=I96
464+
x.h(); // $ target=I96
465465
S::c; // $ item=I95
466466
<S // $ item=I90
467467
as Trait1<
@@ -564,13 +564,13 @@ mod m16 {
564564
#[rustfmt::skip]
565565
fn foo() {
566566
S3::<i32>:: // $ item=i32
567-
Assoc(); // $ item=S3i32AssocFunc $ SPURIOUS: item=S3boolAssocFunc (the spurious target is later filtered away by type inference)
567+
Assoc(); // $ item=S3i32AssocFunc item_only=S3boolAssocFunc
568568

569569
S3::<bool>:: // $ item=bool
570-
f1(); // $ item=S3boolf1 $ SPURIOUS: item=S3i32f1 (the spurious target is later filtered away by type inference)
570+
f1(); // $ item=S3boolf1 item_only=S3i32f1
571571

572572
S3::<i32>:: // $ item=i32
573-
f1(); // $ item=S3i32f1 $ SPURIOUS: item=S3boolf1 (the spurious target is later filtered away by type inference)
573+
f1(); // $ item=S3i32f1 item_only=S3boolf1
574574
}
575575
}
576576

@@ -628,7 +628,7 @@ mod trait_visibility {
628628
{
629629
// The `Bar` trait is not visible, but we can refer to its method
630630
// with a full path.
631-
m::Bar::a_method(&x); // $ item=Bar::a_method
631+
m::Bar::a_method(&x); // $ item_only=Bar::a_method target=X_Bar::a_method
632632
}
633633
} // trait_visibility::f
634634
}
@@ -652,7 +652,7 @@ mod m17 {
652652
fn g<T: // I5
653653
MyTrait // $ item=I2
654654
>(x: T) { // $ item=I5
655-
x.f(); // $ item=I1
655+
x.f(); // $ target=I1
656656
T::f(&x); // $ item=I1
657657
MyTrait::f(&x); // $ item=I1
658658
} // I6
@@ -735,7 +735,7 @@ mod m23 {
735735
#[rustfmt::skip]
736736
pub fn f() {
737737
let x = S; // $ item=I4
738-
x.f(); // $ item=I5
738+
x.f(); // $ target=I5
739739
} // I108
740740
}
741741

@@ -760,7 +760,7 @@ mod m24 {
760760
T: TraitA // $ item=I111 item=I1151
761761
{
762762
fn call_trait_a(&self) {
763-
self.data.trait_a_method(); // $ item=I110
763+
self.data.trait_a_method(); // $ target=I110
764764
} // I116
765765
}
766766

@@ -772,8 +772,8 @@ mod m24 {
772772
T: TraitA, // $ item=I111 item=I1161
773773
{
774774
fn call_both(&self) {
775-
self.data.trait_a_method(); // $ item=I110
776-
self.data.trait_b_method(); // $ item=I112
775+
self.data.trait_a_method(); // $ target=I110
776+
self.data.trait_b_method(); // $ target=I112
777777
} // I117
778778
}
779779

@@ -798,8 +798,8 @@ mod m24 {
798798
let impl_obj = Implementor; // $ item=I118
799799
let generic = GenericStruct { data: impl_obj }; // $ item=I115
800800

801-
generic.call_trait_a(); // $ item=I116
802-
generic.call_both(); // $ item=I117
801+
generic.call_trait_a(); // $ target=I116
802+
generic.call_both(); // $ target=I117
803803

804804
// Access through where clause type parameter constraint
805805
GenericStruct::<Implementor>::call_trait_a(&generic); // $ item=I116 item=I118
@@ -1132,7 +1132,7 @@ fn main() {
11321132
zelf::h(); // $ item=I25
11331133
z_changed(); // $ item=I122
11341134
AStruct::z_on_type(); // $ item=I124
1135-
AStruct {}.z_on_instance(); // $ item=I123 item=I125
1135+
AStruct {}.z_on_instance(); // $ item=I123 target=I125
11361136
impl_with_attribute_macro::test(); // $ item=impl_with_attribute_macro::test
11371137
patterns::test(); // $ item=patterns::test
11381138
}

rust/ql/test/library-tests/path-resolution/my.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ fn int_div(
3030
) -> Result<i32> // $ item=my::Result $ item=i32
3131
{
3232
if y == 0 {
33-
return Err("Div by zero".to_string()); // $ item=Err item=to_string
33+
return Err("Div by zero".to_string()); // $ item=Err target=to_string
3434
}
3535
Ok(x / y) // $ item=Ok
3636
}

0 commit comments

Comments
 (0)