Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 23 additions & 5 deletions rust/ql/lib/utils/test/PathResolutionInlineExpectationsTest.qll
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ private import codeql.rust.internal.typeinference.TypeInference
private import utils.test.InlineExpectationsTest

private module ResolveTest implements TestSig {
string getARelevantTag() { result = "item" }
string getARelevantTag() { result = ["item", "target", "item_no_target"] }

private predicate itemAt(ItemNode i, string filepath, int line) {
i.getLocation().hasLocationInfo(filepath, _, _, line, _)
Expand Down Expand Up @@ -36,19 +36,37 @@ private module ResolveTest implements TestSig {
)
}

private Item getCallExprTarget(Path p) {
exists(CallExpr ce |
p = ce.getFunction().(PathExpr).getPath() and
result = ce.getResolvedTarget()
)
}

predicate hasActualResult(Location location, string element, string tag, string value) {
exists(AstNode n |
exists(AstNode n, ItemNode i |
not n = any(Path parent).getQualifier() and
location = n.getLocation() and
n.fromSource() and
not location.getFile().getAbsolutePath().matches("%proc_macro.rs") and
not n.isFromMacroExpansion() and
element = n.toString() and
tag = "item"
item(i, value)
|
item(resolvePath(n), value)
i = resolvePath(n) and
(
if exists(getCallExprTarget(n)) and not i = getCallExprTarget(n)
then tag = "item_no_target"
else tag = "item"
)
or
item(n.(MethodCallExpr).getStaticTarget(), value)
tag = "target" and
(
i = n.(MethodCallExpr).getStaticTarget()
or
i = getCallExprTarget(n) and
not i = resolvePath(n)
)
)
}
}
Expand Down
62 changes: 31 additions & 31 deletions rust/ql/test/library-tests/path-resolution/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,18 +189,18 @@ mod m8 {
#[rustfmt::skip]
pub fn g() {
let x = MyStruct {}; // $ item=I50
MyTrait::f(&x); // $ item=I48
MyTrait::f(&x); // $ item_no_target=I48 target=I53
MyStruct::f(&x); // $ item=I53
<MyStruct as // $ item=I50
MyTrait // $ item=I47
> // $ MISSING: item=52
::f(&x); // $ item=I48
::f(&x); // $ item_no_target=I48 target=I53
let x = MyStruct {}; // $ item=I50
x.f(); // $ item=I53
x.f(); // $ target=I53
let x = MyStruct {}; // $ item=I50
x.g(); // $ item=I54
x.g(); // $ target=I54
MyStruct::h(&x); // $ item=I74
x.h(); // $ item=I74
x.h(); // $ target=I74
} // I55
} // I46

Expand Down Expand Up @@ -316,7 +316,7 @@ mod m15 {
fn f(&self) {
println!("m15::Trait2::f"); // $ item=println
Self::g(self); // $ item=I80
self.g(); // $ item=I80
self.g(); // $ target=I80
} // Trait2::f
} // I82

Expand All @@ -331,7 +331,7 @@ mod m15 {
fn f(&self, tt: TT) { // $ item=ITT
Self::g(self); // $ item=I80
TT::g(&tt); // $ item=I80
self.g(); // $ item=I80
self.g(); // $ target=I80
}
} // ITrait3

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

fn g(&self) {
Expand All @@ -365,12 +365,12 @@ mod m15 {
let x = S; // $ item=I81
<S // $ item=I81
as Trait1 // $ item=I79
>::f(&x); // $ item=Trait1::f
>::f(&x); // $ item_no_target=Trait1::f target=I76
<S // $ item=I81
as Trait2 // $ item=I82
>::f(&x); // $ item=Trait2::f
>::f(&x); // $ item_no_target=Trait2::f target=I78
S::g(&x); // $ item=I77
x.g(); // $ item=I77
x.g(); // $ target=I77
} // I75
}

Expand All @@ -383,12 +383,12 @@ mod m16 {
; // Trait1::f

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

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

const c: T // $ item=I84
Expand All @@ -405,7 +405,7 @@ mod m16 {
fn f(&self) -> T { // $ item=I87
println!("m16::Trait2::f"); // $ item=println
Self::g(self); // $ item=I85
self.g(); // $ item=I85
self.g(); // $ target=I85
Self::c // $ item=I94
} // Trait2::f
} // I89
Expand All @@ -420,7 +420,7 @@ mod m16 {
fn f(&self) -> S { // $ item=I90
println!("m16::<S as Trait1<S>>::f"); // $ item=println
Self::g(self); // $ item=I92
self.g() // $ item=I92
self.g() // $ target=I92
} // I91

fn g(&self) -> S { // $ item=I90
Expand Down Expand Up @@ -452,16 +452,16 @@ mod m16 {
as Trait1<
S // $ item=I90
> // $ item=I86
>::f(&x); // $ item=Trait1::f
>::f(&x); // $ item_no_target=Trait1::f target=I91
<S // $ item=I90
as Trait2<
S // $ item=I90
> // $ item=I89
>::f(&x); // $ item=Trait2::f
>::f(&x); // $ item_no_target=Trait2::f target=I93
S::g(&x); // $ item=I92
x.g(); // $ item=I92
x.g(); // $ target=I92
S::h(&x); // $ item=I96
x.h(); // $ item=I96
x.h(); // $ target=I96
S::c; // $ item=I95
<S // $ item=I90
as Trait1<
Expand Down Expand Up @@ -564,13 +564,13 @@ mod m16 {
#[rustfmt::skip]
fn foo() {
S3::<i32>:: // $ item=i32
Assoc(); // $ item=S3i32AssocFunc $ SPURIOUS: item=S3boolAssocFunc (the spurious target is later filtered away by type inference)
Assoc(); // $ item=S3i32AssocFunc item_no_target=S3boolAssocFunc

S3::<bool>:: // $ item=bool
f1(); // $ item=S3boolf1 $ SPURIOUS: item=S3i32f1 (the spurious target is later filtered away by type inference)
f1(); // $ item=S3boolf1 item_no_target=S3i32f1

S3::<i32>:: // $ item=i32
f1(); // $ item=S3i32f1 $ SPURIOUS: item=S3boolf1 (the spurious target is later filtered away by type inference)
f1(); // $ item=S3i32f1 item_no_target=S3boolf1
}
}

Expand Down Expand Up @@ -628,7 +628,7 @@ mod trait_visibility {
{
// The `Bar` trait is not visible, but we can refer to its method
// with a full path.
m::Bar::a_method(&x); // $ item=Bar::a_method
m::Bar::a_method(&x); // $ item_no_target=Bar::a_method target=X_Bar::a_method
}
} // trait_visibility::f
}
Expand All @@ -652,7 +652,7 @@ mod m17 {
fn g<T: // I5
MyTrait // $ item=I2
>(x: T) { // $ item=I5
x.f(); // $ item=I1
x.f(); // $ target=I1
T::f(&x); // $ item=I1
MyTrait::f(&x); // $ item=I1
} // I6
Expand Down Expand Up @@ -735,7 +735,7 @@ mod m23 {
#[rustfmt::skip]
pub fn f() {
let x = S; // $ item=I4
x.f(); // $ item=I5
x.f(); // $ target=I5
} // I108
}

Expand All @@ -760,7 +760,7 @@ mod m24 {
T: TraitA // $ item=I111 item=I1151
{
fn call_trait_a(&self) {
self.data.trait_a_method(); // $ item=I110
self.data.trait_a_method(); // $ target=I110
} // I116
}

Expand All @@ -772,8 +772,8 @@ mod m24 {
T: TraitA, // $ item=I111 item=I1161
{
fn call_both(&self) {
self.data.trait_a_method(); // $ item=I110
self.data.trait_b_method(); // $ item=I112
self.data.trait_a_method(); // $ target=I110
self.data.trait_b_method(); // $ target=I112
} // I117
}

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

generic.call_trait_a(); // $ item=I116
generic.call_both(); // $ item=I117
generic.call_trait_a(); // $ target=I116
generic.call_both(); // $ target=I117

// Access through where clause type parameter constraint
GenericStruct::<Implementor>::call_trait_a(&generic); // $ item=I116 item=I118
Expand Down Expand Up @@ -1132,7 +1132,7 @@ fn main() {
zelf::h(); // $ item=I25
z_changed(); // $ item=I122
AStruct::z_on_type(); // $ item=I124
AStruct {}.z_on_instance(); // $ item=I123 item=I125
AStruct {}.z_on_instance(); // $ item=I123 target=I125
impl_with_attribute_macro::test(); // $ item=impl_with_attribute_macro::test
patterns::test(); // $ item=patterns::test
}
2 changes: 1 addition & 1 deletion rust/ql/test/library-tests/path-resolution/my.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ fn int_div(
) -> Result<i32> // $ item=my::Result $ item=i32
{
if y == 0 {
return Err("Div by zero".to_string()); // $ item=Err item=to_string
return Err("Div by zero".to_string()); // $ item=Err target=to_string
}
Ok(x / y) // $ item=Ok
}
Loading