Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
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 @@ -8,21 +8,31 @@ module Impl {
TPositionalArgumentPosition(int i) {
i in [0 .. max([any(ParamList l).getNumberOfParams(), any(ArgList l).getNumberOfArgs()]) - 1]
} or
TSelfArgumentPosition()
TSelfArgumentPosition() or
TTypeQualifierArgumentPosition()

/** An argument position in a call. */
class ArgumentPosition extends TArgumentPosition {
/** Gets the index of the argument in the call, if this is a positional argument. */
int asPosition() { this = TPositionalArgumentPosition(result) }

/** Holds if this call position is a self argument. */
predicate isSelf() { this instanceof TSelfArgumentPosition }
predicate isSelf() { this = TSelfArgumentPosition() }

/**
* Holds if this call position is a type qualifier, that is, not an actual
* argument, but rather an annotation that is needed to resolve the call target,
* just like actual arguments may be need to resolve the call target.
*/
predicate isTypeQualifier() { this = TTypeQualifierArgumentPosition() }

/** Gets a string representation of this argument position. */
string toString() {
result = this.asPosition().toString()
or
this.isSelf() and result = "self"
or
this.isTypeQualifier() and result = "type qualifier"
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,19 @@ private predicate hasFirstNonTrivialTraitBound(TypeParamItemNode tp, Trait trait
*/
pragma[nomagic]
predicate isBlanketLike(ImplItemNode i, TypePath blanketSelfPath, TypeParam blanketTypeParam) {
blanketTypeParam = i.getBlanketImplementationTypeParam() and
blanketSelfPath.isEmpty()
or
exists(TypeMention tm, Type root, TypeParameter tp |
tm = i.(Impl).getSelfTy() and
complexSelfRoot(root, tp) and
tm.getType() = root and
tm.getTypeAt(blanketSelfPath) = TTypeParamTypeParameter(blanketTypeParam) and
blanketSelfPath = TypePath::singleton(tp) and
hasFirstNonTrivialTraitBound(blanketTypeParam, _)
i.(Impl).hasTrait() and
(
blanketTypeParam = i.getBlanketImplementationTypeParam() and
blanketSelfPath.isEmpty()
or
exists(TypeMention tm, Type root, TypeParameter tp |
tm = i.(Impl).getSelfTy() and
complexSelfRoot(root, tp) and
tm.getType() = root and
tm.getTypeAt(blanketSelfPath) = TTypeParamTypeParameter(blanketTypeParam) and
blanketSelfPath = TypePath::singleton(tp) and
hasFirstNonTrivialTraitBound(blanketTypeParam, _)
)
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ predicate traitTypeParameterOccurrence(
TypeParameter traitTp
) {
f = trait.getAssocItem(functionName) and
traitTp = getAssocFunctionTypeInclNonMethodSelfAt(f, trait, pos, path) and
traitTp = getAssocFunctionTypeAt(f, trait, pos, path) and
traitTp = trait.(TraitTypeAbstraction).getATypeParameter()
}

Expand Down Expand Up @@ -124,7 +124,7 @@ private predicate functionResolutionDependsOnArgumentCand(
implHasSibling(impl, trait) and
traitTypeParameterOccurrence(trait, _, functionName, pos, path, traitTp) and
f = impl.getASuccessor(functionName) and
not pos.isSelf()
not pos.isSelfOrTypeQualifier()
)
}

Expand All @@ -141,7 +141,7 @@ pragma[nomagic]
private Type getAssocFunctionNonTypeParameterTypeAt(
ImplItemNode impl, Function f, FunctionPosition pos, TypePath path
) {
result = getAssocFunctionTypeInclNonMethodSelfAt(f, impl, pos, path) and
result = getAssocFunctionTypeAt(f, impl, pos, path) and
not result instanceof TypeParameter
}

Expand Down
46 changes: 20 additions & 26 deletions rust/ql/lib/codeql/rust/internal/typeinference/FunctionType.qll
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,26 @@ class FunctionPosition extends TFunctionPosition {

ArgumentPosition asArgumentPosition() { this = TArgumentFunctionPosition(result) }

predicate isTypeQualifier() { this.asArgumentPosition().isTypeQualifier() }

predicate isSelfOrTypeQualifier() { this.isSelf() or this.isTypeQualifier() }

predicate isReturn() { this = TReturnFunctionPosition() }

/** Gets the corresponding position when function call syntax is used. */
FunctionPosition getFunctionCallAdjusted() {
(this.isReturn() or this.isTypeQualifier()) and
result = this
or
this.isSelf() and result.asPosition() = 0
or
result.asPosition() = this.asPosition() + 1
}

/** Gets the corresponding position when `f` is invoked via a function call. */
bindingset[f]
FunctionPosition getFunctionCallAdjusted(Function f) {
this.isReturn() and
result = this
or
if f.hasSelfParam()
then
this.isSelf() and result.asPosition() = 0
or
result.asPosition() = this.asPosition() + 1
else result = this
if f.hasSelfParam() then result = this.getFunctionCallAdjusted() else result = this
}

TypeMention getTypeMention(Function f) {
Expand Down Expand Up @@ -82,9 +88,9 @@ private newtype TAssocFunctionType =
// through `i`. This ensures that `parent` is either a supertrait of `i` or
// `i` in an `impl` block implementing `parent`.
(parent = i or BaseTypes::rootTypesSatisfaction(_, TTrait(parent), i, _, _)) and
// We always include the `self` position, even for non-methods, where it is used
// We always include the type qualifer position, even for non-methods, where it is used
// to match type qualifiers against the `impl` or trait type, such as in `Vec::new`.
(exists(pos.getTypeMention(f)) or pos.isSelf())
(exists(pos.getTypeMention(f)) or pos.isTypeQualifier())
}

bindingset[abs, constraint, tp]
Expand Down Expand Up @@ -116,21 +122,9 @@ Type getAssocFunctionTypeAt(Function f, ImplOrTraitItemNode i, FunctionPosition
else result = getTraitConstraintTypeAt(i, constraint, tp, suffix)
)
)
}

/**
* Same as `getAssocFunctionTypeAt`, but also includes types at the `self` position
* for non-methods.
*/
pragma[nomagic]
Type getAssocFunctionTypeInclNonMethodSelfAt(
Function f, ImplOrTraitItemNode i, FunctionPosition pos, TypePath path
) {
result = getAssocFunctionTypeAt(f, i, pos, path)
or
f = i.getASuccessor(_) and
not f.hasSelfParam() and
pos.isSelf() and
pos.isTypeQualifier() and
result = resolveImplOrTraitType(i, path)
}

Expand Down Expand Up @@ -192,7 +186,7 @@ class AssocFunctionType extends MkAssocFunctionType {
Type getTypeAt(TypePath path) {
exists(Function f, FunctionPosition pos, ImplOrTraitItemNode i, Type t |
this.appliesTo(f, i, pos) and
t = getAssocFunctionTypeInclNonMethodSelfAt(f, i, pos, path)
t = getAssocFunctionTypeAt(f, i, pos, path)
|
not t instanceof SelfTypeParameter and
result = t
Expand All @@ -205,7 +199,7 @@ class AssocFunctionType extends MkAssocFunctionType {
exists(Function f, ImplOrTraitItemNode i, FunctionPosition pos | this.appliesTo(f, i, pos) |
result = pos.getTypeMention(f)
or
pos.isSelf() and
pos.isSelfOrTypeQualifier() and
not f.hasSelfParam() and
result = [i.(Impl).getSelfTy().(AstNode), i.(Trait).getName()]
)
Expand Down
Loading