Merge pull request #19193 from hvitved/rust/path-resolution-where-clause

Rust: Take `where` clauses into account in path resolution
This commit is contained in:
Tom Hvitved
2025-04-23 13:00:58 +02:00
committed by GitHub
6 changed files with 175 additions and 70 deletions

View File

@@ -581,9 +581,21 @@ private class BlockExprItemNode extends ItemNode instanceof BlockExpr {
}
class TypeParamItemNode extends ItemNode instanceof TypeParam {
private WherePred getAWherePred() {
exists(ItemNode declaringItem |
this = resolveTypeParamPathTypeRepr(result.getTypeRepr()) and
result = declaringItem.getADescendant() and
this = declaringItem.getADescendant()
)
}
pragma[nomagic]
Path getABoundPath() {
result = super.getTypeBoundList().getABound().getTypeRepr().(PathTypeRepr).getPath()
exists(TypeBoundList tbl | result = tbl.getABound().getTypeRepr().(PathTypeRepr).getPath() |
tbl = super.getTypeBoundList()
or
tbl = this.getAWherePred().getTypeBoundList()
)
}
pragma[nomagic]
@@ -605,11 +617,7 @@ class TypeParamItemNode extends ItemNode instanceof TypeParam {
Stages::PathResolutionStage::ref() and
exists(this.getABoundPath())
or
exists(ItemNode declaringItem, WherePred wp |
this = resolveTypeParamPathTypeRepr(wp.getTypeRepr()) and
wp = declaringItem.getADescendant() and
this = declaringItem.getADescendant()
)
exists(this.getAWherePred())
}
/**

View File

@@ -18,7 +18,7 @@ private module ResolveTest implements TestSig {
private predicate commmentAt(string text, string filepath, int line) {
exists(Comment c |
c.getLocation().hasLocationInfo(filepath, line, _, _, _) and
c.getCommentText() = text
c.getCommentText().trim() = text
)
}

View File

@@ -547,6 +547,76 @@ mod m23 {
} // I108
}
mod m24 {
trait TraitA {
fn trait_a_method(&self); // I110
} // I111
trait TraitB {
fn trait_b_method(&self); // I112
} // I113
#[rustfmt::skip]
struct GenericStruct<T> { // I114
data: T, // $ item=I114
} // I115
#[rustfmt::skip]
impl<T> // I1151
GenericStruct<T> // $ item=I115 item=I1151
where
T: TraitA // $ item=I111 item=I1151
{
fn call_trait_a(&self) {
self.data.trait_a_method(); // $ item=I110
} // I116
}
#[rustfmt::skip]
impl<T> // I1161
GenericStruct<T> // $ item=I115 item=I1161
where
T: TraitB, // $ item=I113 item=I1161
T: TraitA, // $ item=I111 item=I1161
{
fn call_both(&self) {
self.data.trait_a_method(); // $ item=I110
self.data.trait_b_method(); // $ item=I112
} // I117
}
struct Implementor; // I118
#[rustfmt::skip]
impl TraitA for Implementor { // $ item=I111 item=I118
fn trait_a_method(&self) {
println!("TraitA method called");
} // I119
}
#[rustfmt::skip]
impl TraitB for Implementor { // $ item=I113 item=I118
fn trait_b_method(&self) {
println!("TraitB method called");
} // I120
}
#[rustfmt::skip]
pub fn f() {
let impl_obj = Implementor; // $ item=I118
let generic = GenericStruct { data: impl_obj }; // $ item=I115
generic.call_trait_a(); // $ MISSING: item=I116
generic.call_both(); // $ MISSING: item=I117
// Access through where clause type parameter constraint
GenericStruct::<Implementor>::call_trait_a(&generic); // $ item=I116 item=I118
// Type that satisfies multiple trait bounds in where clause
GenericStruct::<Implementor>::call_both(&generic); // $ item=I117 item=I118
} // I121
}
fn main() {
my::nested::nested1::nested2::f(); // $ item=I4
my::f(); // $ item=I38
@@ -575,4 +645,5 @@ fn main() {
nested_f(); // $ item=I201
m18::m19::m20::g(); // $ item=I103
m23::f(); // $ item=I108
m24::f(); // $ item=I121
}

View File

@@ -28,6 +28,7 @@ mod
| main.rs:497:5:503:5 | mod m22 |
| main.rs:505:5:520:5 | mod m33 |
| main.rs:523:1:548:1 | mod m23 |
| main.rs:550:1:618:1 | mod m24 |
| my2/mod.rs:1:1:1:16 | mod nested2 |
| my2/mod.rs:12:1:12:12 | mod my3 |
| my2/mod.rs:14:1:15:10 | mod mymod |
@@ -61,7 +62,7 @@ resolvePath
| main.rs:30:17:30:21 | super | main.rs:18:5:36:5 | mod m2 |
| main.rs:30:17:30:24 | ...::f | main.rs:19:9:21:9 | fn f |
| main.rs:33:17:33:17 | f | main.rs:19:9:21:9 | fn f |
| main.rs:40:9:40:13 | super | main.rs:1:1:578:2 | SourceFile |
| main.rs:40:9:40:13 | super | main.rs:1:1:649:2 | SourceFile |
| main.rs:40:9:40:17 | ...::m1 | main.rs:13:1:37:1 | mod m1 |
| main.rs:40:9:40:21 | ...::m2 | main.rs:18:5:36:5 | mod m2 |
| main.rs:40:9:40:24 | ...::g | main.rs:23:9:27:9 | fn g |
@@ -73,7 +74,7 @@ resolvePath
| main.rs:61:17:61:19 | Foo | main.rs:59:9:59:21 | struct Foo |
| main.rs:64:13:64:15 | Foo | main.rs:53:5:53:17 | struct Foo |
| main.rs:66:5:66:5 | f | main.rs:55:5:62:5 | fn f |
| main.rs:68:5:68:8 | self | main.rs:1:1:578:2 | SourceFile |
| main.rs:68:5:68:8 | self | main.rs:1:1:649:2 | SourceFile |
| main.rs:68:5:68:11 | ...::i | main.rs:71:1:83:1 | fn i |
| main.rs:74:13:74:15 | Foo | main.rs:48:1:48:13 | struct Foo |
| main.rs:81:17:81:19 | Foo | main.rs:77:9:79:9 | struct Foo |
@@ -87,7 +88,7 @@ resolvePath
| main.rs:87:57:87:66 | ...::g | my2/nested2.rs:7:9:9:9 | fn g |
| main.rs:87:80:87:86 | nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 |
| main.rs:100:5:100:22 | f_defined_in_macro | main.rs:99:18:99:42 | fn f_defined_in_macro |
| main.rs:117:13:117:17 | super | main.rs:1:1:578:2 | SourceFile |
| main.rs:117:13:117:17 | super | main.rs:1:1:649:2 | SourceFile |
| main.rs:117:13:117:21 | ...::m5 | main.rs:103:1:107:1 | mod m5 |
| main.rs:118:9:118:9 | f | main.rs:104:5:106:5 | fn f |
| main.rs:118:9:118:9 | f | main.rs:110:5:112:5 | fn f |
@@ -240,63 +241,88 @@ resolvePath
| main.rs:535:7:535:10 | Self | main.rs:531:5:531:13 | struct S |
| main.rs:537:11:537:11 | S | main.rs:531:5:531:13 | struct S |
| main.rs:545:17:545:17 | S | main.rs:531:5:531:13 | struct S |
| main.rs:551:5:551:6 | my | main.rs:1:1:1:7 | mod my |
| main.rs:551:5:551:14 | ...::nested | my.rs:1:1:1:15 | mod nested |
| main.rs:551:5:551:23 | ...::nested1 | my/nested.rs:1:1:17:1 | mod nested1 |
| main.rs:551:5:551:32 | ...::nested2 | my/nested.rs:2:5:11:5 | mod nested2 |
| main.rs:551:5:551:35 | ...::f | my/nested.rs:3:9:5:9 | fn f |
| main.rs:552:5:552:6 | my | main.rs:1:1:1:7 | mod my |
| main.rs:552:5:552:9 | ...::f | my.rs:5:1:7:1 | fn f |
| main.rs:553:5:553:11 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 |
| main.rs:553:5:553:20 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 |
| main.rs:553:5:553:29 | ...::nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 |
| main.rs:553:5:553:32 | ...::f | my2/nested2.rs:3:9:5:9 | fn f |
| main.rs:554:5:554:5 | f | my2/nested2.rs:3:9:5:9 | fn f |
| main.rs:555:5:555:5 | g | my2/nested2.rs:7:9:9:9 | fn g |
| main.rs:556:5:556:9 | crate | main.rs:0:0:0:0 | Crate(main@0.0.1) |
| main.rs:556:5:556:12 | ...::h | main.rs:50:1:69:1 | fn h |
| main.rs:557:5:557:6 | m1 | main.rs:13:1:37:1 | mod m1 |
| main.rs:557:5:557:10 | ...::m2 | main.rs:18:5:36:5 | mod m2 |
| main.rs:557:5:557:13 | ...::g | main.rs:23:9:27:9 | fn g |
| main.rs:558:5:558:6 | m1 | main.rs:13:1:37:1 | mod m1 |
| main.rs:558:5:558:10 | ...::m2 | main.rs:18:5:36:5 | mod m2 |
| main.rs:558:5:558:14 | ...::m3 | main.rs:29:9:35:9 | mod m3 |
| main.rs:558:5:558:17 | ...::h | main.rs:30:27:34:13 | fn h |
| main.rs:559:5:559:6 | m4 | main.rs:39:1:46:1 | mod m4 |
| main.rs:559:5:559:9 | ...::i | main.rs:42:5:45:5 | fn i |
| main.rs:560:5:560:5 | h | main.rs:50:1:69:1 | fn h |
| main.rs:561:5:561:11 | f_alias | my2/nested2.rs:3:9:5:9 | fn f |
| main.rs:562:5:562:11 | g_alias | my2/nested2.rs:7:9:9:9 | fn g |
| main.rs:563:5:563:5 | j | main.rs:97:1:101:1 | fn j |
| main.rs:564:5:564:6 | m6 | main.rs:109:1:120:1 | mod m6 |
| main.rs:564:5:564:9 | ...::g | main.rs:114:5:119:5 | fn g |
| main.rs:565:5:565:6 | m7 | main.rs:122:1:137:1 | mod m7 |
| main.rs:565:5:565:9 | ...::f | main.rs:129:5:136:5 | fn f |
| main.rs:566:5:566:6 | m8 | main.rs:139:1:193:1 | mod m8 |
| main.rs:566:5:566:9 | ...::g | main.rs:177:5:192:5 | fn g |
| main.rs:567:5:567:6 | m9 | main.rs:195:1:203:1 | mod m9 |
| main.rs:567:5:567:9 | ...::f | main.rs:198:5:202:5 | fn f |
| main.rs:568:5:568:7 | m11 | main.rs:226:1:263:1 | mod m11 |
| main.rs:568:5:568:10 | ...::f | main.rs:231:5:234:5 | fn f |
| main.rs:569:5:569:7 | m15 | main.rs:294:1:348:1 | mod m15 |
| main.rs:569:5:569:10 | ...::f | main.rs:335:5:347:5 | fn f |
| main.rs:570:5:570:7 | m16 | main.rs:350:1:442:1 | mod m16 |
| main.rs:570:5:570:10 | ...::f | main.rs:417:5:441:5 | fn f |
| main.rs:571:5:571:7 | m17 | main.rs:444:1:474:1 | mod m17 |
| main.rs:571:5:571:10 | ...::f | main.rs:468:5:473:5 | fn f |
| main.rs:572:5:572:11 | nested6 | my2/nested2.rs:14:5:18:5 | mod nested6 |
| main.rs:572:5:572:14 | ...::f | my2/nested2.rs:15:9:17:9 | fn f |
| main.rs:573:5:573:11 | nested8 | my2/nested2.rs:22:5:26:5 | mod nested8 |
| main.rs:573:5:573:14 | ...::f | my2/nested2.rs:23:9:25:9 | fn f |
| main.rs:574:5:574:7 | my3 | my2/mod.rs:12:1:12:12 | mod my3 |
| main.rs:574:5:574:10 | ...::f | my2/my3/mod.rs:1:1:5:1 | fn f |
| main.rs:575:5:575:12 | nested_f | my/my4/my5/mod.rs:1:1:3:1 | fn f |
| main.rs:576:5:576:7 | m18 | main.rs:476:1:494:1 | mod m18 |
| main.rs:576:5:576:12 | ...::m19 | main.rs:481:5:493:5 | mod m19 |
| main.rs:576:5:576:17 | ...::m20 | main.rs:486:9:492:9 | mod m20 |
| main.rs:576:5:576:20 | ...::g | main.rs:487:13:491:13 | fn g |
| main.rs:577:5:577:7 | m23 | main.rs:523:1:548:1 | mod m23 |
| main.rs:577:5:577:10 | ...::f | main.rs:543:5:547:5 | fn f |
| main.rs:561:15:561:15 | T | main.rs:560:26:560:26 | T |
| main.rs:566:9:566:24 | GenericStruct::<...> | main.rs:559:5:562:5 | struct GenericStruct |
| main.rs:566:23:566:23 | T | main.rs:565:10:565:10 | T |
| main.rs:568:9:568:9 | T | main.rs:565:10:565:10 | T |
| main.rs:568:12:568:17 | TraitA | main.rs:551:5:553:5 | trait TraitA |
| main.rs:577:9:577:24 | GenericStruct::<...> | main.rs:559:5:562:5 | struct GenericStruct |
| main.rs:577:23:577:23 | T | main.rs:576:10:576:10 | T |
| main.rs:579:9:579:9 | T | main.rs:576:10:576:10 | T |
| main.rs:579:12:579:17 | TraitB | main.rs:555:5:557:5 | trait TraitB |
| main.rs:580:9:580:9 | T | main.rs:576:10:576:10 | T |
| main.rs:580:12:580:17 | TraitA | main.rs:551:5:553:5 | trait TraitA |
| main.rs:591:10:591:15 | TraitA | main.rs:551:5:553:5 | trait TraitA |
| main.rs:591:21:591:31 | Implementor | main.rs:588:5:588:23 | struct Implementor |
| main.rs:598:10:598:15 | TraitB | main.rs:555:5:557:5 | trait TraitB |
| main.rs:598:21:598:31 | Implementor | main.rs:588:5:588:23 | struct Implementor |
| main.rs:606:24:606:34 | Implementor | main.rs:588:5:588:23 | struct Implementor |
| main.rs:607:23:607:35 | GenericStruct | main.rs:559:5:562:5 | struct GenericStruct |
| main.rs:613:9:613:36 | GenericStruct::<...> | main.rs:559:5:562:5 | struct GenericStruct |
| main.rs:613:9:613:50 | ...::call_trait_a | main.rs:570:9:572:9 | fn call_trait_a |
| main.rs:613:25:613:35 | Implementor | main.rs:588:5:588:23 | struct Implementor |
| main.rs:616:9:616:36 | GenericStruct::<...> | main.rs:559:5:562:5 | struct GenericStruct |
| main.rs:616:9:616:47 | ...::call_both | main.rs:582:9:585:9 | fn call_both |
| main.rs:616:25:616:35 | Implementor | main.rs:588:5:588:23 | struct Implementor |
| main.rs:621:5:621:6 | my | main.rs:1:1:1:7 | mod my |
| main.rs:621:5:621:14 | ...::nested | my.rs:1:1:1:15 | mod nested |
| main.rs:621:5:621:23 | ...::nested1 | my/nested.rs:1:1:17:1 | mod nested1 |
| main.rs:621:5:621:32 | ...::nested2 | my/nested.rs:2:5:11:5 | mod nested2 |
| main.rs:621:5:621:35 | ...::f | my/nested.rs:3:9:5:9 | fn f |
| main.rs:622:5:622:6 | my | main.rs:1:1:1:7 | mod my |
| main.rs:622:5:622:9 | ...::f | my.rs:5:1:7:1 | fn f |
| main.rs:623:5:623:11 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 |
| main.rs:623:5:623:20 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 |
| main.rs:623:5:623:29 | ...::nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 |
| main.rs:623:5:623:32 | ...::f | my2/nested2.rs:3:9:5:9 | fn f |
| main.rs:624:5:624:5 | f | my2/nested2.rs:3:9:5:9 | fn f |
| main.rs:625:5:625:5 | g | my2/nested2.rs:7:9:9:9 | fn g |
| main.rs:626:5:626:9 | crate | main.rs:0:0:0:0 | Crate(main@0.0.1) |
| main.rs:626:5:626:12 | ...::h | main.rs:50:1:69:1 | fn h |
| main.rs:627:5:627:6 | m1 | main.rs:13:1:37:1 | mod m1 |
| main.rs:627:5:627:10 | ...::m2 | main.rs:18:5:36:5 | mod m2 |
| main.rs:627:5:627:13 | ...::g | main.rs:23:9:27:9 | fn g |
| main.rs:628:5:628:6 | m1 | main.rs:13:1:37:1 | mod m1 |
| main.rs:628:5:628:10 | ...::m2 | main.rs:18:5:36:5 | mod m2 |
| main.rs:628:5:628:14 | ...::m3 | main.rs:29:9:35:9 | mod m3 |
| main.rs:628:5:628:17 | ...::h | main.rs:30:27:34:13 | fn h |
| main.rs:629:5:629:6 | m4 | main.rs:39:1:46:1 | mod m4 |
| main.rs:629:5:629:9 | ...::i | main.rs:42:5:45:5 | fn i |
| main.rs:630:5:630:5 | h | main.rs:50:1:69:1 | fn h |
| main.rs:631:5:631:11 | f_alias | my2/nested2.rs:3:9:5:9 | fn f |
| main.rs:632:5:632:11 | g_alias | my2/nested2.rs:7:9:9:9 | fn g |
| main.rs:633:5:633:5 | j | main.rs:97:1:101:1 | fn j |
| main.rs:634:5:634:6 | m6 | main.rs:109:1:120:1 | mod m6 |
| main.rs:634:5:634:9 | ...::g | main.rs:114:5:119:5 | fn g |
| main.rs:635:5:635:6 | m7 | main.rs:122:1:137:1 | mod m7 |
| main.rs:635:5:635:9 | ...::f | main.rs:129:5:136:5 | fn f |
| main.rs:636:5:636:6 | m8 | main.rs:139:1:193:1 | mod m8 |
| main.rs:636:5:636:9 | ...::g | main.rs:177:5:192:5 | fn g |
| main.rs:637:5:637:6 | m9 | main.rs:195:1:203:1 | mod m9 |
| main.rs:637:5:637:9 | ...::f | main.rs:198:5:202:5 | fn f |
| main.rs:638:5:638:7 | m11 | main.rs:226:1:263:1 | mod m11 |
| main.rs:638:5:638:10 | ...::f | main.rs:231:5:234:5 | fn f |
| main.rs:639:5:639:7 | m15 | main.rs:294:1:348:1 | mod m15 |
| main.rs:639:5:639:10 | ...::f | main.rs:335:5:347:5 | fn f |
| main.rs:640:5:640:7 | m16 | main.rs:350:1:442:1 | mod m16 |
| main.rs:640:5:640:10 | ...::f | main.rs:417:5:441:5 | fn f |
| main.rs:641:5:641:7 | m17 | main.rs:444:1:474:1 | mod m17 |
| main.rs:641:5:641:10 | ...::f | main.rs:468:5:473:5 | fn f |
| main.rs:642:5:642:11 | nested6 | my2/nested2.rs:14:5:18:5 | mod nested6 |
| main.rs:642:5:642:14 | ...::f | my2/nested2.rs:15:9:17:9 | fn f |
| main.rs:643:5:643:11 | nested8 | my2/nested2.rs:22:5:26:5 | mod nested8 |
| main.rs:643:5:643:14 | ...::f | my2/nested2.rs:23:9:25:9 | fn f |
| main.rs:644:5:644:7 | my3 | my2/mod.rs:12:1:12:12 | mod my3 |
| main.rs:644:5:644:10 | ...::f | my2/my3/mod.rs:1:1:5:1 | fn f |
| main.rs:645:5:645:12 | nested_f | my/my4/my5/mod.rs:1:1:3:1 | fn f |
| main.rs:646:5:646:7 | m18 | main.rs:476:1:494:1 | mod m18 |
| main.rs:646:5:646:12 | ...::m19 | main.rs:481:5:493:5 | mod m19 |
| main.rs:646:5:646:17 | ...::m20 | main.rs:486:9:492:9 | mod m20 |
| main.rs:646:5:646:20 | ...::g | main.rs:487:13:491:13 | fn g |
| main.rs:647:5:647:7 | m23 | main.rs:523:1:548:1 | mod m23 |
| main.rs:647:5:647:10 | ...::f | main.rs:543:5:547:5 | fn f |
| main.rs:648:5:648:7 | m24 | main.rs:550:1:618:1 | mod m24 |
| main.rs:648:5:648:10 | ...::f | main.rs:604:5:617:5 | fn f |
| my2/mod.rs:5:5:5:11 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 |
| my2/mod.rs:5:5:5:20 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 |
| my2/mod.rs:5:5:5:29 | ...::nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 |
@@ -312,7 +338,7 @@ resolvePath
| my2/my3/mod.rs:3:5:3:5 | g | my2/mod.rs:3:1:6:1 | fn g |
| my2/my3/mod.rs:4:5:4:5 | h | main.rs:50:1:69:1 | fn h |
| my2/my3/mod.rs:7:5:7:9 | super | my2/mod.rs:1:1:17:30 | SourceFile |
| my2/my3/mod.rs:7:5:7:16 | ...::super | main.rs:1:1:578:2 | SourceFile |
| my2/my3/mod.rs:7:5:7:16 | ...::super | main.rs:1:1:649:2 | SourceFile |
| my2/my3/mod.rs:7:5:7:19 | ...::h | main.rs:50:1:69:1 | fn h |
| my2/my3/mod.rs:8:5:8:9 | super | my2/mod.rs:1:1:17:30 | SourceFile |
| my2/my3/mod.rs:8:5:8:12 | ...::g | my2/mod.rs:3:1:6:1 | fn g |

View File

@@ -623,7 +623,7 @@ mod function_trait_bounds_2 {
where
T1: Into<T2>,
{
x.into()
x.into() // $ method=into
}
pub fn f() {

View File

@@ -31,7 +31,7 @@ module VariableAccessTest implements TestSig {
private predicate commmentAt(string text, string filepath, int line) {
exists(Comment c |
c.getLocation().hasLocationInfo(filepath, line, _, _, _) and
c.getCommentText() = text
c.getCommentText().trim() = text
)
}