mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
Rust: Path resolution for trait items with default implementations
This commit is contained in:
@@ -132,8 +132,12 @@ abstract class ItemNode extends AstNode {
|
||||
)
|
||||
or
|
||||
// a trait has access to the associated items of its supertraits
|
||||
result = this.(TraitItemNode).resolveABound().getASuccessorRec(name) and
|
||||
result instanceof AssocItemNode
|
||||
this =
|
||||
any(TraitItemNode trait |
|
||||
result = trait.resolveABound().getASuccessorRec(name) and
|
||||
result instanceof AssocItemNode and
|
||||
not trait.declares(name)
|
||||
)
|
||||
or
|
||||
// items made available by an implementation where `this` is the implementing type
|
||||
exists(ItemNode node |
|
||||
@@ -141,6 +145,15 @@ abstract class ItemNode extends AstNode {
|
||||
result = node.getASuccessorRec(name) and
|
||||
result instanceof AssocItemNode
|
||||
)
|
||||
or
|
||||
// trait items with default implementations made available in an implementation
|
||||
exists(ImplItemNode impl, ItemNode trait |
|
||||
this = impl and
|
||||
trait = impl.resolveTraitTy() and
|
||||
result = trait.getASuccessorRec(name) and
|
||||
result.(AssocItemNode).hasImplementation() and
|
||||
not impl.declares(name)
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets a successor named `name` of this item, if any. */
|
||||
@@ -194,11 +207,16 @@ private class SourceFileItemNode extends ModuleLikeNode, SourceFile {
|
||||
}
|
||||
|
||||
/** An item that can occur in a trait or an `impl` block. */
|
||||
abstract private class AssocItemNode extends ItemNode { }
|
||||
abstract private class AssocItemNode extends ItemNode, AssocItem {
|
||||
/** Holds if this associated item has an implementation. */
|
||||
abstract predicate hasImplementation();
|
||||
}
|
||||
|
||||
private class ConstItemNode extends AssocItemNode instanceof Const {
|
||||
override string getName() { result = Const.super.getName().getText() }
|
||||
|
||||
override predicate hasImplementation() { super.hasBody() }
|
||||
|
||||
override Namespace getNamespace() { result.isValue() }
|
||||
|
||||
override Visibility getVisibility() { result = Const.super.getVisibility() }
|
||||
@@ -222,9 +240,11 @@ private class VariantItemNode extends ItemNode instanceof Variant {
|
||||
override Visibility getVisibility() { result = Variant.super.getVisibility() }
|
||||
}
|
||||
|
||||
private class FunctionItemNode extends AssocItemNode instanceof Function {
|
||||
class FunctionItemNode extends AssocItemNode instanceof Function {
|
||||
override string getName() { result = Function.super.getName().getText() }
|
||||
|
||||
override predicate hasImplementation() { super.hasBody() }
|
||||
|
||||
override Namespace getNamespace() { result.isValue() }
|
||||
|
||||
override Visibility getVisibility() { result = Function.super.getVisibility() }
|
||||
@@ -245,7 +265,19 @@ abstract private class ImplOrTraitItemNode extends ItemNode {
|
||||
}
|
||||
|
||||
class ImplItemNode extends ImplOrTraitItemNode instanceof Impl {
|
||||
ItemNode resolveSelfTy() { result = resolvePath(super.getSelfTy().(PathTypeRepr).getPath()) }
|
||||
Path getSelfPath() { result = super.getSelfTy().(PathTypeRepr).getPath() }
|
||||
|
||||
Path getTraitPath() { result = super.getTrait().(PathTypeRepr).getPath() }
|
||||
|
||||
ItemNode resolveSelfTy() { result = resolvePath(this.getSelfPath()) }
|
||||
|
||||
TraitItemNode resolveTraitTy() { result = resolvePath(this.getTraitPath()) }
|
||||
|
||||
/** Holds if this `impl` block declares an associated item named `name`. */
|
||||
pragma[nomagic]
|
||||
predicate declares(string name) {
|
||||
name = super.getAssocItemList().getAnAssocItem().(AssocItemNode).getName()
|
||||
}
|
||||
|
||||
override string getName() { result = "(impl)" }
|
||||
|
||||
@@ -259,6 +291,8 @@ class ImplItemNode extends ImplOrTraitItemNode instanceof Impl {
|
||||
private class MacroCallItemNode extends AssocItemNode instanceof MacroCall {
|
||||
override string getName() { result = "(macro call)" }
|
||||
|
||||
override predicate hasImplementation() { none() }
|
||||
|
||||
override Namespace getNamespace() { none() }
|
||||
|
||||
override Visibility getVisibility() { none() }
|
||||
@@ -293,6 +327,12 @@ class TraitItemNode extends ImplOrTraitItemNode instanceof Trait {
|
||||
|
||||
ItemNode resolveABound() { result = resolvePath(this.getABoundPath()) }
|
||||
|
||||
/** Holds if this trait declares an associated item named `name`. */
|
||||
pragma[nomagic]
|
||||
predicate declares(string name) {
|
||||
name = super.getAssocItemList().getAnAssocItem().(AssocItemNode).getName()
|
||||
}
|
||||
|
||||
override string getName() { result = Trait.super.getName().getText() }
|
||||
|
||||
override Namespace getNamespace() { result.isType() }
|
||||
@@ -303,6 +343,8 @@ class TraitItemNode extends ImplOrTraitItemNode instanceof Trait {
|
||||
class TypeAliasItemNode extends AssocItemNode instanceof TypeAlias {
|
||||
override string getName() { result = TypeAlias.super.getName().getText() }
|
||||
|
||||
override predicate hasImplementation() { super.hasTypeRepr() }
|
||||
|
||||
override Namespace getNamespace() { result.isType() }
|
||||
|
||||
override Visibility getVisibility() { result = TypeAlias.super.getVisibility() }
|
||||
|
||||
@@ -430,7 +430,7 @@ mod m16 {
|
||||
>::f(&x); // $ MISSING: item=I93
|
||||
S::g(&x); // $ item=I92
|
||||
x.g(); // $ MISSING: item=I92
|
||||
S::h(&x); // $ MISSING: item=I96
|
||||
S::h(&x); // $ item=I96
|
||||
x.h(); // $ MISSING: item=I96
|
||||
S::c; // $ item=I95
|
||||
<S // $ item=I90
|
||||
|
||||
@@ -187,6 +187,7 @@ resolvePath
|
||||
| main.rs:431:9:431:9 | S | main.rs:384:5:384:13 | struct S |
|
||||
| main.rs:431:9:431:12 | ...::g | main.rs:397:9:400:9 | fn g |
|
||||
| main.rs:433:9:433:9 | S | main.rs:384:5:384:13 | struct S |
|
||||
| main.rs:433:9:433:12 | ...::h | main.rs:360:9:363:9 | fn h |
|
||||
| main.rs:435:9:435:9 | S | main.rs:384:5:384:13 | struct S |
|
||||
| main.rs:435:9:435:12 | ...::c | main.rs:402:9:403:9 | Const |
|
||||
| main.rs:436:10:436:10 | S | main.rs:384:5:384:13 | struct S |
|
||||
|
||||
Reference in New Issue
Block a user