Skip to content
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
28 changes: 10 additions & 18 deletions rust/ql/lib/codeql/rust/internal/typeinference/FunctionType.qll
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,16 @@ 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 `f` is invoked via a function call. */
bindingset[f]
FunctionPosition getFunctionCallAdjusted(Function f) {
this.isReturn() and
(this.isReturn() or this.isTypeQualifier()) and
result = this
or
if f.hasSelfParam()
Expand Down Expand Up @@ -82,9 +86,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 +120,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 +184,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 +197,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
Loading