Skip to content

Commit 8f0aced

Browse files
committed
Rust: Path resolution for trait items with default implementations
1 parent 1be903c commit 8f0aced

File tree

3 files changed

+49
-6
lines changed

3 files changed

+49
-6
lines changed

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

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,15 +132,28 @@ abstract class ItemNode extends AstNode {
132132
)
133133
or
134134
// a trait has access to the associated items of its supertraits
135-
result = this.(TraitItemNode).resolveABound().getASuccessorRec(name) and
136-
result instanceof AssocItemNode
135+
this =
136+
any(TraitItemNode trait |
137+
result = trait.resolveABound().getASuccessorRec(name) and
138+
result instanceof AssocItemNode and
139+
not trait.declares(name)
140+
)
137141
or
138142
// items made available by an implementation where `this` is the implementing type
139143
exists(ItemNode node |
140144
this = node.(ImplItemNode).resolveSelfTy() and
141145
result = node.getASuccessorRec(name) and
142146
result instanceof AssocItemNode
143147
)
148+
or
149+
// trait items with default implementations made available in an implementation
150+
exists(ImplItemNode impl, ItemNode trait |
151+
this = impl and
152+
trait = impl.resolveTraitTy() and
153+
result = trait.getASuccessorRec(name) and
154+
result.(AssocItemNode).hasImplementation() and
155+
not impl.declares(name)
156+
)
144157
}
145158

146159
/** Gets a successor named `name` of this item, if any. */
@@ -194,11 +207,16 @@ private class SourceFileItemNode extends ModuleLikeNode, SourceFile {
194207
}
195208

196209
/** An item that can occur in a trait or an `impl` block. */
197-
abstract private class AssocItemNode extends ItemNode { }
210+
abstract private class AssocItemNode extends ItemNode, AssocItem {
211+
/** Holds if this associated item has an implementation. */
212+
abstract predicate hasImplementation();
213+
}
198214

199215
private class ConstItemNode extends AssocItemNode instanceof Const {
200216
override string getName() { result = Const.super.getName().getText() }
201217

218+
override predicate hasImplementation() { super.hasBody() }
219+
202220
override Namespace getNamespace() { result.isValue() }
203221

204222
override Visibility getVisibility() { result = Const.super.getVisibility() }
@@ -222,9 +240,11 @@ private class VariantItemNode extends ItemNode instanceof Variant {
222240
override Visibility getVisibility() { result = Variant.super.getVisibility() }
223241
}
224242

225-
private class FunctionItemNode extends AssocItemNode instanceof Function {
243+
class FunctionItemNode extends AssocItemNode instanceof Function {
226244
override string getName() { result = Function.super.getName().getText() }
227245

246+
override predicate hasImplementation() { super.hasBody() }
247+
228248
override Namespace getNamespace() { result.isValue() }
229249

230250
override Visibility getVisibility() { result = Function.super.getVisibility() }
@@ -245,7 +265,19 @@ abstract private class ImplOrTraitItemNode extends ItemNode {
245265
}
246266

247267
class ImplItemNode extends ImplOrTraitItemNode instanceof Impl {
248-
ItemNode resolveSelfTy() { result = resolvePath(super.getSelfTy().(PathTypeRepr).getPath()) }
268+
Path getSelfPath() { result = super.getSelfTy().(PathTypeRepr).getPath() }
269+
270+
Path getTraitPath() { result = super.getTrait().(PathTypeRepr).getPath() }
271+
272+
ItemNode resolveSelfTy() { result = resolvePath(this.getSelfPath()) }
273+
274+
TraitItemNode resolveTraitTy() { result = resolvePath(this.getTraitPath()) }
275+
276+
/** Holds if this `impl` block declares an associated item named `name`. */
277+
pragma[nomagic]
278+
predicate declares(string name) {
279+
name = super.getAssocItemList().getAnAssocItem().(AssocItemNode).getName()
280+
}
249281

250282
override string getName() { result = "(impl)" }
251283

@@ -259,6 +291,8 @@ class ImplItemNode extends ImplOrTraitItemNode instanceof Impl {
259291
private class MacroCallItemNode extends AssocItemNode instanceof MacroCall {
260292
override string getName() { result = "(macro call)" }
261293

294+
override predicate hasImplementation() { none() }
295+
262296
override Namespace getNamespace() { none() }
263297

264298
override Visibility getVisibility() { none() }
@@ -293,6 +327,12 @@ class TraitItemNode extends ImplOrTraitItemNode instanceof Trait {
293327

294328
ItemNode resolveABound() { result = resolvePath(this.getABoundPath()) }
295329

330+
/** Holds if this trait declares an associated item named `name`. */
331+
pragma[nomagic]
332+
predicate declares(string name) {
333+
name = super.getAssocItemList().getAnAssocItem().(AssocItemNode).getName()
334+
}
335+
296336
override string getName() { result = Trait.super.getName().getText() }
297337

298338
override Namespace getNamespace() { result.isType() }
@@ -303,6 +343,8 @@ class TraitItemNode extends ImplOrTraitItemNode instanceof Trait {
303343
class TypeAliasItemNode extends AssocItemNode instanceof TypeAlias {
304344
override string getName() { result = TypeAlias.super.getName().getText() }
305345

346+
override predicate hasImplementation() { super.hasTypeRepr() }
347+
306348
override Namespace getNamespace() { result.isType() }
307349

308350
override Visibility getVisibility() { result = TypeAlias.super.getVisibility() }

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ mod m16 {
430430
>::f(&x); // $ MISSING: item=I93
431431
S::g(&x); // $ item=I92
432432
x.g(); // $ MISSING: item=I92
433-
S::h(&x); // $ MISSING: item=I96
433+
S::h(&x); // $ item=I96
434434
x.h(); // $ MISSING: item=I96
435435
S::c; // $ item=I95
436436
<S // $ item=I90

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ resolvePath
187187
| main.rs:431:9:431:9 | S | main.rs:384:5:384:13 | struct S |
188188
| main.rs:431:9:431:12 | ...::g | main.rs:397:9:400:9 | fn g |
189189
| main.rs:433:9:433:9 | S | main.rs:384:5:384:13 | struct S |
190+
| main.rs:433:9:433:12 | ...::h | main.rs:360:9:363:9 | fn h |
190191
| main.rs:435:9:435:9 | S | main.rs:384:5:384:13 | struct S |
191192
| main.rs:435:9:435:12 | ...::c | main.rs:402:9:403:9 | Const |
192193
| main.rs:436:10:436:10 | S | main.rs:384:5:384:13 | struct S |

0 commit comments

Comments
 (0)