Skip to content

Commit 99b498b

Browse files
committed
Rust: Resolve Self paths in type definitions
1 parent 95afe61 commit 99b498b

File tree

3 files changed

+17
-26
lines changed

3 files changed

+17
-26
lines changed

rust/ql/lib/codeql/rust/internal/PathResolution.qll

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,15 @@ private ItemNode getAChildSuccessor(ItemNode item, string name, SuccessorKind ki
119119
if result.isPublic()
120120
then kind.isBoth()
121121
else kind.isInternal()
122+
or
123+
// `Self` has scoping rules similar to type parameters and can be considered
124+
// an implicit type parameter child of the introducing item.
125+
// - https://doc.rust-lang.org/stable/reference/paths.html#r-paths.qualifiers.type-self
126+
// - https://doc.rust-lang.org/stable/reference/names/scopes.html#r-names.scopes.self
127+
(item instanceof TypeItemTypeItemNode or item instanceof ImplOrTraitItemNode) and
128+
name = "Self" and
129+
kind.isInternal() and
130+
result = item
122131
}
123132

124133
private module UseOption = Option<Use>;
@@ -405,9 +414,6 @@ abstract class ItemNode extends Locatable {
405414
this instanceof SourceFile and
406415
builtin(name, result)
407416
or
408-
name = "Self" and
409-
this = result.(ImplOrTraitItemNode).getAnItemInSelfScope()
410-
or
411417
name = "crate" and
412418
this = result.(CrateItemNode).getASourceFile()
413419
)
@@ -718,26 +724,12 @@ class FunctionItemNode extends AssocItemNode, ParameterizableItemNode instanceof
718724
}
719725

720726
abstract class ImplOrTraitItemNode extends ItemNode {
721-
/** Gets an item that may refer to this node using `Self`. */
722-
pragma[nomagic]
723-
ItemNode getAnItemInSelfScope() {
724-
result = this
725-
or
726-
result.getImmediateParent() = this
727-
or
728-
exists(ItemNode mid |
729-
mid = this.getAnItemInSelfScope() and
730-
result.getImmediateParent() = mid and
731-
not mid instanceof ImplOrTraitItemNode
732-
)
733-
}
734-
735727
/** Gets a `Self` path that refers to this item. */
736728
cached
737729
Path getASelfPath() {
738730
Stages::PathResolutionStage::ref() and
739731
isUnqualifiedSelfPath(result) and
740-
result = this.getAnItemInSelfScope().getADescendant()
732+
this = unqualifiedPathLookup(result, _, _)
741733
}
742734

743735
/** Gets an associated item belonging to this trait or `impl` block. */
@@ -1610,11 +1602,7 @@ private predicate unqualifiedPathLookup(ItemNode ancestor, string name, Namespac
16101602
// lookup in an outer scope, but only if the item is not declared in inner scope
16111603
exists(ItemNode mid |
16121604
unqualifiedPathLookup(mid, name, ns, encl) and
1613-
not declares(mid, ns, name) and
1614-
not (
1615-
name = "Self" and
1616-
mid = any(ImplOrTraitItemNode i).getAnItemInSelfScope()
1617-
)
1605+
not declares(mid, ns, name)
16181606
|
16191607
ancestor = getOuterScope(mid)
16201608
or

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,12 +1060,12 @@ mod self_constructors {
10601060
mod self_types {
10611061
struct NonEmptyListStruct<T> {
10621062
head: T, // $ item=T
1063-
tail: Option<Box<Self>>, // $ item=Option item=Box MISSING: item=NonEmptyListStruct
1063+
tail: Option<Box<Self>>, // $ item=Option item=Box item=NonEmptyListStruct
10641064
}
10651065

10661066
enum NonEmptyListEnum<T> {
10671067
Single(T), // $ item=T
1068-
Cons(T, Box<Self>), // $ item=T item=Box MISSING: item=NonEmptyListEnum
1068+
Cons(T, Box<Self>), // $ item=T item=Box item=NonEmptyListEnum
10691069
}
10701070

10711071
#[rustfmt::skip]
@@ -1075,7 +1075,7 @@ mod self_types {
10751075
: Copy // $ item=Copy
10761076
> {
10771077
single: T, // $ item=T
1078-
cons: (T, &'a Self), // $ item=T MISSING: item=NonEmptyListUnion
1078+
cons: (T, &'a Self), // $ item=T item=NonEmptyListUnion
10791079
}
10801080
}
10811081

rust/ql/test/library-tests/path-resolution/path-resolution.expected

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,12 +536,15 @@ resolvePath
536536
| main.rs:1062:15:1062:15 | T | main.rs:1061:31:1061:31 | T |
537537
| main.rs:1063:15:1063:31 | Option::<...> | {EXTERNAL LOCATION} | enum Option |
538538
| main.rs:1063:22:1063:30 | Box::<...> | {EXTERNAL LOCATION} | struct Box |
539+
| main.rs:1063:26:1063:29 | Self | main.rs:1061:5:1064:5 | struct NonEmptyListStruct |
539540
| main.rs:1067:16:1067:16 | T | main.rs:1066:27:1066:27 | T |
540541
| main.rs:1068:14:1068:14 | T | main.rs:1066:27:1066:27 | T |
541542
| main.rs:1068:17:1068:25 | Box::<...> | {EXTERNAL LOCATION} | struct Box |
543+
| main.rs:1068:21:1068:24 | Self | main.rs:1066:5:1069:5 | enum NonEmptyListEnum |
542544
| main.rs:1075:13:1075:16 | Copy | {EXTERNAL LOCATION} | trait Copy |
543545
| main.rs:1077:17:1077:17 | T | main.rs:1074:9:1074:9 | T |
544546
| main.rs:1078:16:1078:16 | T | main.rs:1074:9:1074:9 | T |
547+
| main.rs:1078:23:1078:26 | Self | main.rs:1071:5:1079:5 | union NonEmptyListUnion |
545548
| main.rs:1083:5:1083:6 | my | main.rs:1:1:1:7 | mod my |
546549
| main.rs:1083:5:1083:14 | ...::nested | my.rs:1:1:1:15 | mod nested |
547550
| main.rs:1083:5:1083:23 | ...::nested1 | my/nested.rs:1:1:17:1 | mod nested1 |

0 commit comments

Comments
 (0)