Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class CallableScopeTree extends StandardTree, PreOrderTree, PostOrderTree, Scope

override AstNode getChildNode(int i) {
i = 0 and
result = this.getParamList().getSelfParam()
result = this.getSelfParam()
or
result = this.getParam(i - 1)
or
Expand Down
2 changes: 1 addition & 1 deletion rust/ql/lib/codeql/rust/elements/internal/CallImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ module Impl {
f = resolvePath(path) and
path.getSegment().getIdentifier().getText() = methodName and
exists(SelfParam self |
self = f.getParamList().getSelfParam() and
self = f.getSelfParam() and
if self.isRef() then selfIsRef = true else selfIsRef = false
)
)
Expand Down
10 changes: 10 additions & 0 deletions rust/ql/lib/codeql/rust/elements/internal/CallableImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,15 @@ module Impl {
*/
class Callable extends Generated::Callable {
override Param getParam(int index) { result = this.getParamList().getParam(index) }

/**
* Gets the self parameter of this callable, if it exists.
*/
SelfParam getSelfParam() { result = this.getParamList().getSelfParam() }

/**
* Holds if `getSelfParam()` exists.
*/
predicate hasSelfParam() { exists(this.getSelfParam()) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ module Impl {
text = name.getText() and
// exclude self parameters from functions without a body as these are
// trait method declarations without implementations
not exists(Function f | not f.hasBody() and f.getParamList().getSelfParam() = sp)
not exists(Function f | not f.hasBody() and f.getSelfParam() = sp)
)
or
exists(IdentPat pat |
Expand Down
40 changes: 36 additions & 4 deletions rust/ql/lib/codeql/rust/internal/PathResolution.qll
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

private import rust
private import codeql.rust.elements.internal.generated.ParentChild
private import codeql.rust.elements.internal.CallExprImpl::Impl as CallExprImpl
private import codeql.rust.internal.CachedStages
private import codeql.rust.frameworks.stdlib.Builtins as Builtins
private import codeql.util.Option
Expand Down Expand Up @@ -604,7 +605,13 @@ private class EnumItemNode extends TypeItemNode instanceof Enum {
}
}

private class VariantItemNode extends ItemNode instanceof Variant {
/** An item that can be called with arguments. */
abstract class CallableItemNode extends ItemNode {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's a bit confusing that CallableItemNode is a function or a struct, when we already have Callable which is a function or a closure. Could we name it something different? Maybe HasParameters?

/** Gets the number of parameters of this item. */
abstract int getNumberOfParameters();
}

private class VariantItemNode extends CallableItemNode instanceof Variant {
override string getName() { result = Variant.super.getName().getText() }

override Namespace getNamespace() {
Expand All @@ -617,6 +624,10 @@ private class VariantItemNode extends ItemNode instanceof Variant {

override Visibility getVisibility() { result = super.getEnum().getVisibility() }

override int getNumberOfParameters() {
result = super.getFieldList().(TupleFieldList).getNumberOfFields()
}

override predicate hasCanonicalPath(Crate c) { this.hasCanonicalPathPrefix(c) }

bindingset[c]
Expand All @@ -638,7 +649,7 @@ private class VariantItemNode extends ItemNode instanceof Variant {
}
}

class FunctionItemNode extends AssocItemNode instanceof Function {
class FunctionItemNode extends AssocItemNode, CallableItemNode instanceof Function {
override string getName() { result = Function.super.getName().getText() }

override predicate hasImplementation() { Function.super.hasImplementation() }
Expand All @@ -648,6 +659,13 @@ class FunctionItemNode extends AssocItemNode instanceof Function {
override TypeParam getTypeParam(int i) { result = super.getGenericParamList().getTypeParam(i) }

override Visibility getVisibility() { result = Function.super.getVisibility() }

override int getNumberOfParameters() {
exists(int arr |
arr = super.getNumberOfParams() and
if super.hasSelfParam() then result = arr + 1 else result = arr
)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about adding this to Callable instead as it's not tied to path resolution?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok; calling it getNumberOfParamsInclSelf?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds very clear 👍

}

abstract class ImplOrTraitItemNode extends ItemNode {
Expand Down Expand Up @@ -712,8 +730,10 @@ final class ImplItemNode extends ImplOrTraitItemNode instanceof Impl {
TypeParamItemNode getBlanketImplementationTypeParam() { result = this.resolveSelfTy() }

/**
* Holds if this impl block is a blanket implementation. That is, the
* Holds if this impl block is a [blanket implementation][1]. That is, the
* implementation targets a generic parameter of the impl block.
*
* [1]: https://doc.rust-lang.org/book/ch10-02-traits.html#using-trait-bounds-to-conditionally-implement-methods
*/
predicate isBlanketImplementation() { exists(this.getBlanketImplementationTypeParam()) }

Expand Down Expand Up @@ -865,7 +885,7 @@ private class ImplItemNodeImpl extends ImplItemNode {
TraitItemNode resolveTraitTyCand() { result = resolvePathCand(this.getTraitPath()) }
}

private class StructItemNode extends TypeItemNode instanceof Struct {
private class StructItemNode extends TypeItemNode, CallableItemNode instanceof Struct {
override string getName() { result = Struct.super.getName().getText() }

override Namespace getNamespace() {
Expand All @@ -877,6 +897,10 @@ private class StructItemNode extends TypeItemNode instanceof Struct {

override Visibility getVisibility() { result = Struct.super.getVisibility() }

override int getNumberOfParameters() {
result = super.getFieldList().(TupleFieldList).getNumberOfFields()
}

override TypeParam getTypeParam(int i) { result = super.getGenericParamList().getTypeParam(i) }

override predicate hasCanonicalPath(Crate c) { this.hasCanonicalPathPrefix(c) }
Expand Down Expand Up @@ -1687,6 +1711,14 @@ private ItemNode resolvePathCand(RelevantPath path) {
or
not pathUsesNamespace(path, _) and
not path = any(MacroCall mc).getPath()
) and
(
not path = CallExprImpl::getFunctionPath(_)
or
exists(CallExpr ce |
path = CallExprImpl::getFunctionPath(ce) and
result.(CallableItemNode).getNumberOfParameters() = ce.getNumberOfArgs()
)
)
}

Expand Down
12 changes: 6 additions & 6 deletions rust/ql/lib/codeql/rust/internal/TypeInference.qll
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ module Consistency {
// Suppress the inconsistency if `n` is a self parameter and the type
// mention for the self type has multiple types for a path.
not exists(ImplItemNode impl, TypePath selfTypePath |
n = impl.getAnAssocItem().(Function).getParamList().getSelfParam() and
n = impl.getAnAssocItem().(Function).getSelfParam() and
strictcount(impl.(Impl).getSelfTy().(TypeMention).resolveTypeAt(selfTypePath)) > 1
)
}
Expand Down Expand Up @@ -948,7 +948,7 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
)
or
exists(SelfParam self |
self = pragma[only_bind_into](this.getParamList().getSelfParam()) and
self = pragma[only_bind_into](this.getSelfParam()) and
dpos.isSelf() and
result = inferAnnotatedType(self, path) // `self` parameter with type annotation
)
Expand All @@ -972,7 +972,7 @@ private module CallExprBaseMatchingInput implements MatchingInputSig {
exists(ImplOrTraitItemNode i |
this = i.getAnAssocItem() and
dpos.isSelf() and
not this.getParamList().hasSelfParam()
not this.hasSelfParam()
|
result = TSelfTypeParameter(i) and
path.isEmpty()
Expand Down Expand Up @@ -1900,7 +1900,7 @@ private predicate methodCandidate(Type type, string name, int arity, Impl impl)
type = impl.getSelfTy().(TypeMention).resolveType() and
exists(Function f |
f = impl.(ImplItemNode).getASuccessor(name) and
f.getParamList().hasSelfParam() and
f.hasSelfParam() and
arity = f.getParamList().getNumberOfParams()
)
}
Expand Down Expand Up @@ -2222,7 +2222,7 @@ private module BlanketImplementation {
) {
isCanonicalImpl(impl) and
blanketImplementationTraitBound(impl, traitBound) and
f.getParamList().hasSelfParam() and
f.hasSelfParam() and
arity = f.getParamList().getNumberOfParams() and
(
f = impl.getAssocItem(name)
Expand Down Expand Up @@ -2332,7 +2332,7 @@ private Function resolveMethodCallTarget(MethodCall mc) {
pragma[nomagic]
private predicate assocFuncResolutionDependsOnArgument(Function f, Impl impl, int pos) {
functionResolutionDependsOnArgument(impl, _, f, pos, _, _) and
not f.getParamList().hasSelfParam()
not f.hasSelfParam()
}

private class FunctionCallExpr extends CallImpl::CallExprCall {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,2 @@
multipleCallTargets
| test_cipher.rs:20:27:20:48 | ...::new(...) |
| test_cipher.rs:26:27:26:48 | ...::new(...) |
| test_cipher.rs:29:27:29:48 | ...::new(...) |
| test_cipher.rs:36:30:36:59 | ...::new(...) |
| test_cipher.rs:39:30:39:63 | ...::new(...) |
| test_cipher.rs:114:23:114:50 | ...::new(...) |

This file was deleted.

Loading