Rust: Path resolution for inherited functions

This commit is contained in:
Tom Hvitved
2025-02-18 12:18:48 +01:00
parent f3a393f9da
commit ab74d903fd
5 changed files with 48 additions and 6 deletions

View File

@@ -130,6 +130,16 @@ abstract class ItemNode extends AstNode {
call = this.getASuccessorRec(_) and
result = call.(ItemNode).getASuccessorRec(name)
)
or
// an inherited function, either from a trait bound or from an `impl` block
exists(ItemNode node |
result = node.(ItemNode).getASuccessorRec(name) and
result instanceof Function
|
node = this.(TraitItemNode).resolveABound()
or
this = node.(ImplItemNode).resolveSelfTy()
)
}
/** Gets a successor named `name` of this item, if any. */
@@ -269,6 +279,13 @@ private class StructItemNode extends ItemNode instanceof Struct {
}
class TraitItemNode extends ImplOrTraitItemNode instanceof Trait {
pragma[nomagic]
Path getABoundPath() {
result = super.getTypeBoundList().getABound().getTypeRepr().(PathTypeRepr).getPath()
}
ItemNode resolveABound() { result = resolvePath(this.getABoundPath()) }
override string getName() { result = Trait.super.getName().getText() }
override Namespace getNamespace() { result.isType() }

View File

@@ -42,6 +42,15 @@ edges
| main.rs:103:13:103:30 | mn.data_through(...) | main.rs:103:9:103:9 | b | provenance | |
| main.rs:103:29:103:29 | a | main.rs:79:28:79:33 | ...: i64 | provenance | |
| main.rs:103:29:103:29 | a | main.rs:103:13:103:30 | mn.data_through(...) | provenance | |
| main.rs:109:9:109:9 | a | main.rs:110:26:110:26 | a | provenance | |
| main.rs:109:13:109:21 | source(...) | main.rs:109:9:109:9 | a | provenance | |
| main.rs:110:26:110:26 | a | main.rs:67:23:67:28 | ...: i64 | provenance | |
| main.rs:115:9:115:9 | a | main.rs:116:39:116:39 | a | provenance | |
| main.rs:115:13:115:22 | source(...) | main.rs:115:9:115:9 | a | provenance | |
| main.rs:116:9:116:9 | b | main.rs:117:10:117:10 | b | provenance | |
| main.rs:116:13:116:40 | ...::data_through(...) | main.rs:116:9:116:9 | b | provenance | |
| main.rs:116:39:116:39 | a | main.rs:79:28:79:33 | ...: i64 | provenance | |
| main.rs:116:39:116:39 | a | main.rs:116:13:116:40 | ...::data_through(...) | provenance | |
| main.rs:128:12:128:17 | ...: i64 | main.rs:129:24:129:24 | n | provenance | |
| main.rs:129:9:129:26 | MyInt {...} [MyInt] | main.rs:128:28:130:5 | { ... } [MyInt] | provenance | |
| main.rs:129:24:129:24 | n | main.rs:129:9:129:26 | MyInt {...} [MyInt] | provenance | |
@@ -130,6 +139,15 @@ nodes
| main.rs:103:13:103:30 | mn.data_through(...) | semmle.label | mn.data_through(...) |
| main.rs:103:29:103:29 | a | semmle.label | a |
| main.rs:104:10:104:10 | b | semmle.label | b |
| main.rs:109:9:109:9 | a | semmle.label | a |
| main.rs:109:13:109:21 | source(...) | semmle.label | source(...) |
| main.rs:110:26:110:26 | a | semmle.label | a |
| main.rs:115:9:115:9 | a | semmle.label | a |
| main.rs:115:13:115:22 | source(...) | semmle.label | source(...) |
| main.rs:116:9:116:9 | b | semmle.label | b |
| main.rs:116:13:116:40 | ...::data_through(...) | semmle.label | ...::data_through(...) |
| main.rs:116:39:116:39 | a | semmle.label | a |
| main.rs:117:10:117:10 | b | semmle.label | b |
| main.rs:128:12:128:17 | ...: i64 | semmle.label | ...: i64 |
| main.rs:128:28:130:5 | { ... } [MyInt] | semmle.label | { ... } [MyInt] |
| main.rs:129:9:129:26 | MyInt {...} [MyInt] | semmle.label | MyInt {...} [MyInt] |
@@ -179,6 +197,7 @@ subpaths
| main.rs:41:26:44:5 | { ... } | main.rs:30:17:30:22 | ...: i64 | main.rs:30:32:32:1 | { ... } | main.rs:41:13:44:6 | pass_through(...) |
| main.rs:55:26:55:26 | a | main.rs:51:21:51:26 | ...: i64 | main.rs:51:36:53:5 | { ... } | main.rs:55:13:55:27 | pass_through(...) |
| main.rs:103:29:103:29 | a | main.rs:79:28:79:33 | ...: i64 | main.rs:79:43:85:5 | { ... } | main.rs:103:13:103:30 | mn.data_through(...) |
| main.rs:116:39:116:39 | a | main.rs:79:28:79:33 | ...: i64 | main.rs:79:43:85:5 | { ... } | main.rs:116:13:116:40 | ...::data_through(...) |
| main.rs:134:24:134:33 | source(...) | main.rs:128:12:128:17 | ...: i64 | main.rs:128:28:130:5 | { ... } [MyInt] | main.rs:134:13:134:34 | ...::new(...) [MyInt] |
| main.rs:187:49:187:49 | a [MyInt] | main.rs:175:18:175:21 | SelfParam [MyInt] | main.rs:175:48:177:5 | { ... } [MyInt] | main.rs:187:30:187:53 | ...::take_self(...) [MyInt] |
| main.rs:192:54:192:54 | b [MyInt] | main.rs:179:26:179:37 | ...: MyInt [MyInt] | main.rs:179:49:181:5 | { ... } [MyInt] | main.rs:192:30:192:55 | ...::take_second(...) [MyInt] |
@@ -191,8 +210,10 @@ testFailures
| main.rs:45:10:45:10 | a | main.rs:43:9:43:18 | source(...) | main.rs:45:10:45:10 | a | $@ | main.rs:43:9:43:18 | source(...) | source(...) |
| main.rs:56:10:56:10 | b | main.rs:49:13:49:22 | source(...) | main.rs:56:10:56:10 | b | $@ | main.rs:49:13:49:22 | source(...) | source(...) |
| main.rs:68:14:68:14 | n | main.rs:96:13:96:21 | source(...) | main.rs:68:14:68:14 | n | $@ | main.rs:96:13:96:21 | source(...) | source(...) |
| main.rs:68:14:68:14 | n | main.rs:109:13:109:21 | source(...) | main.rs:68:14:68:14 | n | $@ | main.rs:109:13:109:21 | source(...) | source(...) |
| main.rs:91:10:91:10 | a | main.rs:75:13:75:21 | source(...) | main.rs:91:10:91:10 | a | $@ | main.rs:75:13:75:21 | source(...) | source(...) |
| main.rs:104:10:104:10 | b | main.rs:102:13:102:21 | source(...) | main.rs:104:10:104:10 | b | $@ | main.rs:102:13:102:21 | source(...) | source(...) |
| main.rs:117:10:117:10 | b | main.rs:115:13:115:22 | source(...) | main.rs:117:10:117:10 | b | $@ | main.rs:115:13:115:22 | source(...) | source(...) |
| main.rs:136:10:136:10 | m | main.rs:134:24:134:33 | source(...) | main.rs:136:10:136:10 | m | $@ | main.rs:134:24:134:33 | source(...) | source(...) |
| main.rs:188:10:188:10 | c | main.rs:185:28:185:36 | source(...) | main.rs:188:10:188:10 | c | $@ | main.rs:185:28:185:36 | source(...) | source(...) |
| main.rs:193:10:193:10 | c | main.rs:191:28:191:37 | source(...) | main.rs:193:10:193:10 | c | $@ | main.rs:191:28:191:37 | source(...) | source(...) |

View File

@@ -65,7 +65,7 @@ struct MyFlag {
impl MyFlag {
fn data_in(&self, n: i64) {
sink(n); // $ hasValueFlow=1 MISSING: hasValueFlow=8
sink(n); // $ hasValueFlow=1 hasValueFlow=8
}
fn get_data(&self) -> i64 {
@@ -114,7 +114,7 @@ fn data_through_method_called_as_function() {
let mn = MyFlag { flag: true };
let a = source(12);
let b = MyFlag::data_through(&mn, a);
sink(b); // $ MISSING: hasValueFlow=12
sink(b); // $ hasValueFlow=12
}
use std::ops::Add;

View File

@@ -178,7 +178,7 @@ mod m8 {
pub fn g() {
let x = MyStruct {}; // $ item=I50
MyTrait::f(&x); // $ item=I48
MyStruct::f(&x); // $ MISSING: item=I53
MyStruct::f(&x); // $ item=I53
<MyStruct as // $ item=I50
MyTrait // $ MISSING: item=I47
> // $ MISSING: item=52
@@ -187,7 +187,7 @@ mod m8 {
x.f(); // $ MISSING: item=I53
let x = MyStruct {}; // $ item=I50
x.g(); // $ MISSING: item=I54
MyStruct::h(&x); // $ MISSING: item=I74
MyStruct::h(&x); // $ item=I74
x.h(); // $ MISSING: item=I74
} // I55
} // I46
@@ -303,7 +303,7 @@ mod m15 {
: Trait1 { // $ item=I79
fn f(&self) {
println!("m15::Trait2::f");
Self::g(self); // $ MISSING: item=I80
Self::g(self); // $ item=I80
self.g(); // $ MISSING: item=I80
}
} // I82
@@ -342,7 +342,7 @@ mod m15 {
<S // $ item=I81
as Trait2 // MISSING: item=I82
>::f(&x); // $ MISSING: item=I78
S::g(&x); // $ MISSING: item=I77
S::g(&x); // $ item=I77
x.g(); // $ MISSING: item=I77
} // I75
}

View File

@@ -95,11 +95,13 @@ resolvePath
| main.rs:180:9:180:15 | MyTrait | main.rs:140:5:148:5 | trait MyTrait |
| main.rs:180:9:180:18 | ...::f | main.rs:141:9:141:20 | fn f |
| main.rs:181:9:181:16 | MyStruct | main.rs:150:5:150:22 | struct MyStruct |
| main.rs:181:9:181:19 | ...::f | main.rs:157:33:162:9 | fn f |
| main.rs:182:10:182:17 | MyStruct | main.rs:150:5:150:22 | struct MyStruct |
| main.rs:182:10:182:17 | MyStruct | main.rs:150:5:150:22 | struct MyStruct |
| main.rs:186:17:186:24 | MyStruct | main.rs:150:5:150:22 | struct MyStruct |
| main.rs:188:17:188:24 | MyStruct | main.rs:150:5:150:22 | struct MyStruct |
| main.rs:190:9:190:16 | MyStruct | main.rs:150:5:150:22 | struct MyStruct |
| main.rs:190:9:190:19 | ...::h | main.rs:170:21:174:9 | fn h |
| main.rs:199:19:199:22 | self | main.rs:195:1:203:1 | mod m9 |
| main.rs:199:19:199:32 | ...::MyStruct | main.rs:196:5:196:26 | struct MyStruct |
| main.rs:201:9:201:12 | self | main.rs:195:1:203:1 | mod m9 |
@@ -132,6 +134,7 @@ resolvePath
| main.rs:289:13:289:13 | f | main.rs:280:5:280:17 | fn f |
| main.rs:303:9:303:14 | Trait1 | main.rs:295:5:299:5 | trait Trait1 |
| main.rs:306:13:306:16 | Self | main.rs:301:5:309:5 | trait Trait2 |
| main.rs:306:13:306:19 | ...::g | main.rs:298:9:298:20 | fn g |
| main.rs:314:10:314:15 | Trait1 | main.rs:295:5:299:5 | trait Trait1 |
| main.rs:315:11:315:11 | S | main.rs:311:5:311:13 | struct S |
| main.rs:318:13:318:16 | Self | main.rs:313:5:325:5 | impl Trait1 for S { ... } |
@@ -144,6 +147,7 @@ resolvePath
| main.rs:342:10:342:10 | S | main.rs:311:5:311:13 | struct S |
| main.rs:342:10:342:10 | S | main.rs:311:5:311:13 | struct S |
| main.rs:345:9:345:9 | S | main.rs:311:5:311:13 | struct S |
| main.rs:345:9:345:12 | ...::g | main.rs:322:9:324:9 | fn g |
| main.rs:351:5:351:6 | my | main.rs:1:1:1:7 | mod my |
| main.rs:351:5:351:14 | ...::nested | my.rs:1:1:1:15 | mod nested |
| main.rs:351:5:351:23 | ...::nested1 | my/nested.rs:1:1:17:1 | mod nested1 |