Skip to content

Commit 72103ad

Browse files
committed
Rust: Fix spurious path resolution
The annotated impl block was filtered away, but it's children where not. This caused the associated type `Foo` to appear as if it was an item in the scope outside of the impl block.
1 parent 60ceb89 commit 72103ad

File tree

3 files changed

+20
-3
lines changed

3 files changed

+20
-3
lines changed

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,24 @@ private ItemNode getAChildSuccessor(ItemNode item, string name, SuccessorKind ki
7878
)
7979
}
8080

81+
/**
82+
* Holds if `n` is superceded by an attribute macro expansion. That is, `n` is
83+
* an item or a transitive child of an item with an attribute macro expansion.
84+
*/
85+
predicate supercededByAttributeMacroExpansion(AstNode n) {
86+
n.(Item).hasAttributeMacroExpansion()
87+
or
88+
exists(AstNode parent |
89+
n.getParentNode() = parent and
90+
supercededByAttributeMacroExpansion(parent) and
91+
// Don't exclude expansions themselves as they supercede other nodes.
92+
not n = parent.(Item).getAttributeMacroExpansion() and
93+
// Don't consider attributes themselves to be superceded. E.g., in `#[a] fn
94+
// f() {}` the macro expansion supercedes `fn f() {}` but not `#[a]`.
95+
not n instanceof Attr
96+
)
97+
}
98+
8199
/**
82100
* An item that may be referred to by a path, and which is a node in
83101
* the _item graph_.
@@ -158,7 +176,7 @@ private ItemNode getAChildSuccessor(ItemNode item, string name, SuccessorKind ki
158176
abstract class ItemNode extends Locatable {
159177
ItemNode() {
160178
// Exclude items that are superceded by the expansion of an attribute macro.
161-
not this.(Item).hasAttributeMacroExpansion()
179+
not supercededByAttributeMacroExpansion(this)
162180
}
163181

164182
/** Gets the (original) name of this item. */

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -784,7 +784,7 @@ mod impl_with_attribute_macro {
784784

785785
pub fn test() {
786786
// This should resolve to the struct, not the associated type.
787-
let _x: Foo; // $ item=IFoo SPURIOUS: item=IATrait_i64_Foo
787+
let _x: Foo; // $ item=IFoo
788788
} // impl_with_attribute_macro::test
789789
}
790790

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,6 @@ resolvePath
356356
| main.rs:779:21:779:23 | i64 | {EXTERNAL LOCATION} | struct i64 |
357357
| main.rs:781:11:781:13 | i64 | {EXTERNAL LOCATION} | struct i64 |
358358
| main.rs:787:17:787:19 | Foo | main.rs:772:5:772:15 | struct Foo |
359-
| main.rs:787:17:787:19 | Foo | main.rs:779:27:782:9 | type Foo |
360359
| main.rs:792:5:792:6 | my | main.rs:1:1:1:7 | mod my |
361360
| main.rs:792:5:792:14 | ...::nested | my.rs:1:1:1:15 | mod nested |
362361
| main.rs:792:5:792:23 | ...::nested1 | my/nested.rs:1:1:17:1 | mod nested1 |

0 commit comments

Comments
 (0)