diff --git a/rust/ql/lib/codeql/rust/elements/internal/InvocationExprImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/InvocationExprImpl.qll index d4f68329de94..acf82066f128 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/InvocationExprImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/InvocationExprImpl.qll @@ -8,7 +8,8 @@ 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 { @@ -16,13 +17,22 @@ module Impl { 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" } } diff --git a/rust/ql/lib/codeql/rust/internal/typeinference/BlanketImplementation.qll b/rust/ql/lib/codeql/rust/internal/typeinference/BlanketImplementation.qll index 51781a473057..db1402280d4d 100644 --- a/rust/ql/lib/codeql/rust/internal/typeinference/BlanketImplementation.qll +++ b/rust/ql/lib/codeql/rust/internal/typeinference/BlanketImplementation.qll @@ -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, _) + ) ) } diff --git a/rust/ql/lib/codeql/rust/internal/typeinference/FunctionOverloading.qll b/rust/ql/lib/codeql/rust/internal/typeinference/FunctionOverloading.qll index d96fd892c73e..0f65d21dcf71 100644 --- a/rust/ql/lib/codeql/rust/internal/typeinference/FunctionOverloading.qll +++ b/rust/ql/lib/codeql/rust/internal/typeinference/FunctionOverloading.qll @@ -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() } @@ -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() ) } @@ -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 } diff --git a/rust/ql/lib/codeql/rust/internal/typeinference/FunctionType.qll b/rust/ql/lib/codeql/rust/internal/typeinference/FunctionType.qll index 74d8385bdf20..d31dd407df68 100644 --- a/rust/ql/lib/codeql/rust/internal/typeinference/FunctionType.qll +++ b/rust/ql/lib/codeql/rust/internal/typeinference/FunctionType.qll @@ -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) { @@ -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] @@ -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) } @@ -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 @@ -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()] ) diff --git a/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll b/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll index a4812ad08786..3a968c5caf3c 100644 --- a/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll +++ b/rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll @@ -298,13 +298,11 @@ private class FunctionDeclaration extends Function { } pragma[nomagic] - Type getParameterTypeInclNonMethodSelf( - ImplOrTraitItemNodeOption i, FunctionPosition pos, TypePath path - ) { + Type getParameterType(ImplOrTraitItemNodeOption i, FunctionPosition pos, TypePath path) { i = parent and ( not pos.isReturn() and - result = getAssocFunctionTypeInclNonMethodSelfAt(this, i.asSome(), pos, path) + result = getAssocFunctionTypeAt(this, i.asSome(), pos, path) or i.isNone() and result = this.getParam(pos.asPosition()).getTypeRepr().(TypeMention).getTypeAt(path) @@ -315,7 +313,7 @@ private class FunctionDeclaration extends Function { i = parent and ( result = - getAssocFunctionTypeAt(this, i.asSome(), any(FunctionPosition pos | pos.isReturn()), path) + getAssocFunctionTypeAt(this, i.asSome(), any(FunctionPosition ret | ret.isReturn()), path) or i.isNone() and result = getReturnTypeMention(this).getTypeAt(path) @@ -345,6 +343,10 @@ private class FunctionDeclaration extends Function { } } +private class AssocFunction extends FunctionDeclaration { + AssocFunction() { this.isAssoc(_) } +} + pragma[nomagic] private TypeMention getCallExprTypeMentionArgument(CallExpr ce, TypeArgumentPosition apos) { exists(Path p, int i | p = CallExprImpl::getFunctionPath(ce) | @@ -778,13 +780,6 @@ private predicate typeEquality(AstNode n1, TypePath prefix1, AstNode n2, TypePat prefix1 = TypePath::singleton(getArrayTypeParameter()) and prefix2.isEmpty() or - exists(Struct s | - n2 = [n1.(RangeExpr).getStart(), n1.(RangeExpr).getEnd()] and - prefix1 = TypePath::singleton(TTypeParamTypeParameter(s.getGenericParamList().getATypeParam())) and - prefix2.isEmpty() and - s = getRangeType(n1) - ) - or exists(ClosureExpr ce, int index | n1 = ce and n2 = ce.getParam(index).getPat() and @@ -829,6 +824,12 @@ private predicate lubCoercion(AstNode parent, AstNode child, TypePath prefix) { bodyReturns(parent, child) and strictcount(Expr e | bodyReturns(parent, e)) > 1 and prefix.isEmpty() + or + exists(Struct s | + child = [parent.(RangeExpr).getStart(), parent.(RangeExpr).getEnd()] and + prefix = TypePath::singleton(TTypeParamTypeParameter(s.getGenericParamList().getATypeParam())) and + s = getRangeType(parent) + ) } /** @@ -1031,10 +1032,10 @@ private module StructExprMatchingInput implements MatchingInputSig { private module StructExprMatching = Matching; pragma[nomagic] -private Type inferStructExprType0(AstNode n, boolean isReturn, TypePath path) { +private Type inferStructExprType0(AstNode n, FunctionPosition pos, TypePath path) { exists(StructExprMatchingInput::Access a, StructExprMatchingInput::AccessPosition apos | n = a.getNodeAt(apos) and - if apos.isStructPos() then isReturn = true else isReturn = false + if apos.isStructPos() then pos.isReturn() else pos.asPosition() = 0 // the actual position doesn't matter, as long as it is positional | result = StructExprMatching::inferAccessType(a, apos, path) or @@ -1113,6 +1114,26 @@ private Trait getCallExprTraitQualifier(CallExpr ce) { * Provides functionality related to context-based typing of calls. */ private module ContextTyping { + /** + * Holds if `f` mentions type parameter `tp` at some non-return position, + * possibly via a constraint on another mentioned type parameter. + */ + pragma[nomagic] + private predicate assocFunctionMentionsTypeParameterAtNonRetPos( + ImplOrTraitItemNode i, Function f, TypeParameter tp + ) { + exists(FunctionPosition nonRetPos | + not nonRetPos.isReturn() and + not nonRetPos.isTypeQualifier() and + tp = getAssocFunctionTypeAt(f, i, nonRetPos, _) + ) + or + exists(TypeParameter mid | + assocFunctionMentionsTypeParameterAtNonRetPos(i, f, mid) and + tp = getATypeParameterConstraint(mid, _) + ) + } + /** * Holds if the return type of the function `f` inside `i` at `path` is type * parameter `tp`, and `tp` does not appear in the type of any parameter of @@ -1129,12 +1150,7 @@ private module ContextTyping { ) { pos.isReturn() and tp = getAssocFunctionTypeAt(f, i, pos, path) and - not exists(FunctionPosition nonResPos | not nonResPos.isReturn() | - tp = getAssocFunctionTypeAt(f, i, nonResPos, _) - or - // `Self` types in traits implicitly mention all type parameters of the trait - getAssocFunctionTypeAt(f, i, nonResPos, _) = TSelfTypeParameter(i) - ) + not assocFunctionMentionsTypeParameterAtNonRetPos(i, f, tp) } /** @@ -1184,7 +1200,7 @@ private module ContextTyping { pragma[nomagic] private predicate hasUnknownType(AstNode n) { hasUnknownTypeAt(n, _) } - signature Type inferCallTypeSig(AstNode n, boolean isReturn, TypePath path); + signature Type inferCallTypeSig(AstNode n, FunctionPosition pos, TypePath path); /** * Given a predicate `inferCallType` for inferring the type of a call at a given @@ -1194,19 +1210,31 @@ private module ContextTyping { */ module CheckContextTyping { pragma[nomagic] - private Type inferCallTypeFromContextCand(AstNode n, TypePath prefix, TypePath path) { - result = inferCallType(n, false, path) and + private Type inferCallNonReturnType(AstNode n, FunctionPosition pos, TypePath path) { + result = inferCallType(n, pos, path) and + not pos.isReturn() + } + + pragma[nomagic] + private Type inferCallNonReturnType( + AstNode n, FunctionPosition pos, TypePath prefix, TypePath path + ) { + result = inferCallNonReturnType(n, pos, path) and hasUnknownType(n) and prefix = path.getAPrefix() } pragma[nomagic] Type check(AstNode n, TypePath path) { - result = inferCallType(n, true, path) + result = inferCallType(n, any(FunctionPosition pos | pos.isReturn()), path) or - exists(TypePath prefix | - result = inferCallTypeFromContextCand(n, prefix, path) and + exists(FunctionPosition pos, TypePath prefix | + result = inferCallNonReturnType(n, pos, prefix, path) and hasUnknownTypeAt(n, prefix) + | + // Never propagate type information directly into the receiver, since its type + // must already have been known in order to resolve the call + if pos.isSelf() then not prefix.isEmpty() else any() ) } } @@ -1222,7 +1250,7 @@ private predicate assocFunctionInfo( AssocFunctionType t ) { f = i.getASuccessor(name) and - arity = f.getParamList().getNumberOfParams() and + arity = f.getNumberOfParamsInclSelf() and t.appliesTo(f, i, pos) } @@ -1235,7 +1263,7 @@ private predicate assocFunctionInfo( * is the type parameter used in the blanket implementation. */ pragma[nomagic] -private predicate functionInfoBlanketLike( +private predicate assocFunctionInfoBlanketLike( Function f, string name, int arity, ImplItemNode impl, Trait trait, FunctionPosition pos, AssocFunctionType t, TypePath blanketPath, TypeParam blanketTypeParam ) { @@ -1303,7 +1331,7 @@ private class BorrowKind extends TBorrowKind { } /** - * Provides logic for resolving calls to methods. + * Provides logic for resolving calls to associated functions. * * When resolving a method call, a list of [candidate receiver types][1] is constructed * @@ -1337,194 +1365,257 @@ private class BorrowKind extends TBorrowKind { * * [1]: https://doc.rust-lang.org/reference/expressions/method-call-expr.html#r-expr.method.candidate-receivers */ -private module MethodResolution { +private module AssocFunctionResolution { + /** + * Holds if the non-method trait function `f` mentions the implicit `Self` type + * parameter at `pos`. + */ + pragma[nomagic] + private predicate traitSelfTypeParameterOccurrence( + TraitItemNode trait, NonMethodFunction f, FunctionPosition pos + ) { + FunctionOverloading::traitTypeParameterOccurrence(trait, f, _, pos, _, TSelfTypeParameter(trait)) + } + /** - * Holds if method `m` with the name `name` and the arity `arity` exists in - * `i`, and the type of the `self` parameter is `selfType`. + * Holds if the non-method function `f` implements a trait function that mentions + * the implicit `Self` type parameter at `pos`. + */ + pragma[nomagic] + private predicate traitImplSelfTypeParameterOccurrence( + ImplItemNode impl, NonMethodFunction f, FunctionPosition pos + ) { + exists(NonMethodFunction traitFunction | + f = impl.getAnAssocItem() and + f.implements(traitFunction) and + traitSelfTypeParameterOccurrence(_, traitFunction, pos) + ) + } + + /** + * Holds if function `f` with the name `name` and the arity `arity` exists in + * `i`, and the type at `selfPos` is `selfType`. * * `strippedTypePath` points to the type `strippedType` inside `selfType`, * which is the (possibly complex-stripped) root type of `selfType`. For example, - * if `m` has a `&self` parameter, then `strippedTypePath` is `getRefSharedTypeParameter()` + * if `f` has a `&self` parameter, then `strippedTypePath` is `getRefSharedTypeParameter()` * and `strippedType` is the type inside the reference. + * + * `selfPosAdj` is the function-call adjusted version of `selfPos`. */ pragma[nomagic] - private predicate methodInfo( - Method m, string name, int arity, ImplOrTraitItemNode i, AssocFunctionType selfType, - TypePath strippedTypePath, Type strippedType + private predicate assocFunctionInfo( + Function f, string name, int arity, FunctionPosition selfPos, FunctionPosition selfPosAdj, + ImplOrTraitItemNode i, AssocFunctionType selfType, TypePath strippedTypePath, Type strippedType ) { - exists(FunctionPosition pos | - assocFunctionInfo(m, name, arity, i, pos, selfType) and - strippedType = selfType.getTypeAt(strippedTypePath) and - isComplexRootStripped(strippedTypePath, strippedType) and - pos.isSelf() + assocFunctionInfo(f, name, arity, i, selfPos, selfType) and + strippedType = selfType.getTypeAt(strippedTypePath) and + ( + isComplexRootStripped(strippedTypePath, strippedType) + or + selfPos.isTypeQualifier() and strippedTypePath.isEmpty() + ) and + selfPosAdj = selfPos.getFunctionCallAdjusted(f) and + ( + selfPos.isSelfOrTypeQualifier() + or + traitSelfTypeParameterOccurrence(i, f, selfPos) + or + traitImplSelfTypeParameterOccurrence(i, f, selfPos) ) } pragma[nomagic] - private predicate methodInfoTypeParam( - Method m, string name, int arity, ImplOrTraitItemNode i, AssocFunctionType selfType, - TypePath strippedTypePath, TypeParam tp + private predicate assocFunctionInfoTypeParam( + Function f, string name, int arity, FunctionPosition selfPos, FunctionPosition selfPosAdj, + ImplOrTraitItemNode i, AssocFunctionType selfType, TypePath strippedTypePath, TypeParam tp ) { - methodInfo(m, name, arity, i, selfType, strippedTypePath, TTypeParamTypeParameter(tp)) + assocFunctionInfo(f, name, arity, selfPos, selfPosAdj, i, selfType, strippedTypePath, + TTypeParamTypeParameter(tp)) } /** - * Same as `methodInfo`, but restricted to non-blanket implementations, and - * allowing for any `strippedType` when the corresponding type inside `m` is + * Same as `assocFunctionInfo`, but restricted to non-blanket implementations, and + * allowing for any `strippedType` when the corresponding type inside `f` is * a type parameter. */ pragma[inline] - private predicate methodInfoNonBlanket( - Method m, string name, int arity, ImplOrTraitItemNode i, AssocFunctionType selfType, - TypePath strippedTypePath, Type strippedType + private predicate assocFunctionInfoNonBlanket( + Function f, string name, int arity, FunctionPosition selfPos, FunctionPosition selfPosAdj, + ImplOrTraitItemNode i, AssocFunctionType selfType, TypePath strippedTypePath, Type strippedType ) { ( - methodInfo(m, name, arity, i, selfType, strippedTypePath, strippedType) or - methodInfoTypeParam(m, name, arity, i, selfType, strippedTypePath, _) + assocFunctionInfo(f, name, arity, selfPos, selfPosAdj, i, selfType, strippedTypePath, + strippedType) or + assocFunctionInfoTypeParam(f, name, arity, selfPos, selfPosAdj, i, selfType, strippedTypePath, + _) ) and not BlanketImplementation::isBlanketLike(i, _, _) } /** - * Holds if method `m` with the name `name` and the arity `arity` exists in - * blanket (like) implementation `impl` of `trait`, and the type of the `self` - * parameter is `selfType`. + * Holds if associated function `f` with the name `name` and the arity `arity` exists + * in blanket (like) implementation `impl` of `trait`, and the type at `selfPos` is + * `selfType`. * * `blanketPath` points to the type `blanketTypeParam` inside `selfType`, which * is the type parameter used in the blanket implementation. */ pragma[nomagic] - private predicate methodInfoBlanketLike( - Method m, string name, int arity, ImplItemNode impl, Trait trait, AssocFunctionType selfType, - TypePath blanketPath, TypeParam blanketTypeParam + private predicate assocFunctionSelfInfoBlanketLike( + Function f, string name, int arity, FunctionPosition selfPos, FunctionPosition selfPosAdj, + ImplItemNode impl, Trait trait, AssocFunctionType selfType, TypePath blanketPath, + TypeParam blanketTypeParam ) { - exists(FunctionPosition pos | - functionInfoBlanketLike(m, name, arity, impl, trait, pos, selfType, blanketPath, - blanketTypeParam) and - pos.isSelf() + assocFunctionInfoBlanketLike(f, name, arity, impl, trait, selfPos, selfType, blanketPath, + blanketTypeParam) and + selfPosAdj = selfPos.getFunctionCallAdjusted(f) and + ( + selfPos.isSelfOrTypeQualifier() + or + traitImplSelfTypeParameterOccurrence(impl, f, selfPos) ) } pragma[nomagic] - private predicate methodTraitInfo(string name, int arity, Trait trait) { + private predicate assocFunctionTraitInfo(string name, int arity, Trait trait) { exists(ImplItemNode i | - methodInfo(_, name, arity, i, _, _, _) and + assocFunctionInfo(_, name, arity, _, _, i, _, _, _) and trait = i.resolveTraitTy() ) or - methodInfo(_, name, arity, trait, _, _, _) + assocFunctionInfo(_, name, arity, _, _, trait, _, _, _) } pragma[nomagic] - private predicate methodCallTraitCandidate(Element mc, Trait trait) { - mc = - any(MethodCall mc0 | + private predicate assocFunctionCallTraitCandidate(Element afc, Trait trait) { + afc = + any(AssocFunctionCall afc0 | exists(string name, int arity | - mc0.hasNameAndArity(name, arity) and - methodTraitInfo(name, arity, trait) + afc0.hasNameAndArity(name, arity) and + assocFunctionTraitInfo(name, arity, trait) | - not mc0.hasTrait() + not afc0.hasTrait() or - trait = mc0.getTrait() + trait = afc0.getTrait() ) ) } - private module MethodTraitIsVisible = TraitIsVisible; + private module AssocFunctionTraitIsVisible = TraitIsVisible; - private predicate methodCallVisibleTraitCandidate = MethodTraitIsVisible::traitIsVisible/2; + private predicate callVisibleTraitCandidate = AssocFunctionTraitIsVisible::traitIsVisible/2; - bindingset[mc, impl] + bindingset[afc, impl] pragma[inline_late] - private predicate methodCallVisibleImplTraitCandidate(MethodCall mc, ImplItemNode impl) { - methodCallVisibleTraitCandidate(mc, impl.resolveTraitTy()) + private predicate callVisibleImplTraitCandidate(AssocFunctionCall afc, ImplItemNode impl) { + callVisibleTraitCandidate(afc, impl.resolveTraitTy()) } /** - * Holds if method call `mc` may target a method in `i` with `self` parameter having - * type `selfType`. + * Holds if call `afc` may target function `f` in `i` with type `selfType` at + * `selfPos`. * * `strippedTypePath` points to the type `strippedType` inside `selfType`, * which is the (possibly complex-stripped) root type of `selfType`. * - * This predicate only checks for matching method names and arities, and whether + * This predicate only checks for matching function names and arities, and whether * the trait being implemented by `i` (when `i` is not a trait itself) is visible - * at `mc`. + * at `afc`. */ - bindingset[mc, strippedTypePath, strippedType] + bindingset[afc, strippedTypePath, strippedType] pragma[inline_late] - private predicate methodCallNonBlanketCandidate( - MethodCall mc, Method m, ImplOrTraitItemNode i, AssocFunctionType self, - TypePath strippedTypePath, Type strippedType + private predicate nonBlanketCandidate( + AssocFunctionCall afc, Function f, FunctionPosition selfPos, FunctionPosition selfPosAdj, + ImplOrTraitItemNode i, AssocFunctionType selfType, TypePath strippedTypePath, Type strippedType ) { exists(string name, int arity | - mc.hasNameAndArity(name, arity) and - methodInfoNonBlanket(m, name, arity, i, self, strippedTypePath, strippedType) + afc.hasNameAndArity(name, arity) and + assocFunctionInfoNonBlanket(f, name, arity, selfPos, selfPosAdj, i, selfType, + strippedTypePath, strippedType) and + (if afc.hasReceiver() then f instanceof Method else any()) and + // In case of a (non-type-parameter) type qualifier, the `impl` block must match that type + forall(Type t | + t = getCallExprTypeQualifier(afc, TypePath::nil(), _) and + not t instanceof TypeParameter + | + t = resolveImplSelfTypeAt(i, TypePath::nil()) + ) | i = any(Impl impl | not impl.hasTrait() or - methodCallVisibleImplTraitCandidate(mc, impl) + callVisibleImplTraitCandidate(afc, impl) ) or - methodCallVisibleTraitCandidate(mc, i) + callVisibleTraitCandidate(afc, i) or - i.(ImplItemNode).resolveTraitTy() = mc.getTrait() + i.(ImplItemNode).resolveTraitTy() = afc.getTrait() ) } /** - * Holds if method call `mc` may target a method in blanket (like) implementation - * `impl` with `self` parameter having type `selfType`. + * Holds if call `afc` may target function `f` in blanket (like) implementation + * `impl` with type `selfType` at `selfPos`. * * `blanketPath` points to the type `blanketTypeParam` inside `selfType`, which * is the type parameter used in the blanket implementation. * - * This predicate only checks for matching method names and arities, and whether + * This predicate only checks for matching function names and arities, and whether * the trait being implemented by `i` (when `i` is not a trait itself) is visible - * at `mc`. + * at `afc`. */ - bindingset[mc] + bindingset[afc] pragma[inline_late] - private predicate methodCallBlanketLikeCandidate( - MethodCall mc, Method m, ImplItemNode impl, AssocFunctionType self, TypePath blanketPath, - TypeParam blanketTypeParam + private predicate blanketLikeCandidate( + AssocFunctionCall afc, Function f, FunctionPosition selfPos, FunctionPosition selfPosAdj, + ImplItemNode impl, AssocFunctionType self, TypePath blanketPath, TypeParam blanketTypeParam ) { exists(string name, int arity | - mc.hasNameAndArity(name, arity) and - methodInfoBlanketLike(m, name, arity, impl, _, self, blanketPath, blanketTypeParam) + afc.hasNameAndArity(name, arity) and + assocFunctionSelfInfoBlanketLike(f, name, arity, selfPos, selfPosAdj, impl, _, self, + blanketPath, blanketTypeParam) and + if afc.hasReceiver() then f instanceof Method else any() | - methodCallVisibleImplTraitCandidate(mc, impl) + callVisibleImplTraitCandidate(afc, impl) or - impl.resolveTraitTy() = mc.getTrait() + impl.resolveTraitTy() = afc.getTrait() ) } /** - * A (potential) method call. + * A (potential) call to an associated function. * * This is either: * - * 1. `MethodCallMethodCallExpr`: an actual method call, `x.m()`; - * 2. `MethodCallIndexExpr`: an index expression, `x[i]`, which is [syntactic sugar][1] + * 1. `AssocFunctionCallMethodCallExpr`: a method call, `x.m()`; + * 2. `AssocFunctionCallIndexExpr`: an index expression, `x[i]`, which is [syntactic sugar][1] * for `*x.index(i)`; - * 3. `MethodCallCallExpr`: a qualified function call, `Q::m(x)`, where `m` is a method; - * or - * 4. `MethodCallOperation`: an operation expression, `x + y`, which is syntactic sugar + * 3. `AssocFunctionCallCallExpr`: a qualified function call, `Q::f(x)`, where `f` is an associated + * function; or + * 4. `AssocFunctionCallOperation`: an operation expression, `x + y`, which is syntactic sugar * for `Add::add(x, y)`. * * Note that only in case 1 and 2 is auto-dereferencing and borrowing allowed. * - * Note also that only case 4 is a _potential_ method call; in all other cases, we are - * guaranteed that the target is a method. + * Note also that only case 3 is a _potential_ call; in all other cases, we are guaranteed that + * the target is an associated function. * * [1]: https://doc.rust-lang.org/std/ops/trait.Index.html */ - abstract class MethodCall extends Expr { + abstract class AssocFunctionCall extends Expr { abstract predicate hasNameAndArity(string name, int arity); - abstract Expr getArg(ArgumentPosition pos); + abstract Expr getNonReturnNodeAt(FunctionPosition apos); + + AstNode getNodeAt(FunctionPosition pos) { + result = this.getNonReturnNodeAt(pos) + or + result = this and pos.isReturn() + } + + predicate hasReceiver() { exists(this.getNodeAt(any(FunctionPosition self | self.isSelf()))) } abstract predicate supportsAutoDerefAndBorrow(); @@ -1534,154 +1625,165 @@ private module MethodResolution { /** Holds if this call targets a trait. */ predicate hasTrait() { exists(this.getTrait()) } - AstNode getNodeAt(FunctionPosition apos) { - result = this.getArg(apos.asArgumentPosition()) - or - result = this and apos.isReturn() - } - - Type getArgumentTypeAt(ArgumentPosition pos, TypePath path) { - result = inferType(this.getArg(pos), path) - } - - private Type getReceiverTypeAt(TypePath path) { - result = this.getArgumentTypeAt(any(ArgumentPosition pos | pos.isSelf()), path) + Type getTypeAt(FunctionPosition pos, TypePath path) { + result = inferType(this.getNodeAt(pos), path) } /** - * Same as `getACandidateReceiverTypeAt`, but without borrows. + * Same as `getTypeAt`, but without borrows. */ pragma[nomagic] - Type getACandidateReceiverTypeAtNoBorrow(DerefChain derefChain, TypePath path) { - result = this.getReceiverTypeAt(path) and + Type getTypeAtNoBorrow(FunctionPosition selfPos, DerefChain derefChain, TypePath path) { + result = this.getTypeAt(selfPos, path) and derefChain.isEmpty() or exists(DerefImplItemNode impl, DerefChain suffix | - result = ImplicitDeref::getDereferencedCandidateReceiverType(this, impl, suffix, path) and + result = + ImplicitDeref::getDereferencedCandidateReceiverType(this, selfPos, impl, suffix, path) and derefChain = DerefChain::cons(impl, suffix) ) } /** - * Holds if the method inside `i` with matching name and arity can be ruled + * Holds if the function inside `i` with matching name and arity can be ruled * out as a target of this call, because the candidate receiver type represented - * by `derefChain` and `borrow` is incompatible with the `self` parameter type. + * by `derefChain` and `borrow` is incompatible with the type at `selfPos`. * * The types are incompatible because they disagree on a concrete type somewhere * inside `root`. */ pragma[nomagic] private predicate hasIncompatibleTarget( - ImplOrTraitItemNode i, DerefChain derefChain, BorrowKind borrow, Type root + ImplOrTraitItemNode i, FunctionPosition selfPos, DerefChain derefChain, BorrowKind borrow, + Type root ) { exists(TypePath path | - ReceiverIsInstantiationOfSelfParam::argIsNotInstantiationOf(MkMethodCallCand(this, - derefChain, borrow), i, _, path) and + ArgIsInstantiationOfSelfParam::argIsNotInstantiationOf(this, i, selfPos, derefChain, borrow, + path) and path.isCons(root.getATypeParameter(), _) ) + or + exists(AssocFunctionType selfType | + ArgIsInstantiationOfSelfParam::argIsInstantiationOf(this, i, selfPos, derefChain, borrow, + selfType) and + CallArgsAreInstantiationsOf::argsAreNotInstantiationsOf(this, i, _) and + root = selfType.getTypeAt(TypePath::nil()) + ) } /** - * Holds if the method inside blanket-like implementation `impl` with matching name + * Holds if the function inside blanket-like implementation `impl` with matching name * and arity can be ruled out as a target of this call, either because the candidate - * receiver type represented by `derefChain` and `borrow` is incompatible with the `self` - * parameter type, or because the blanket constraint is not satisfied. + * receiver type represented by `derefChain` and `borrow` is incompatible with the type + * at `selfPos`, or because the blanket constraint is not satisfied. */ pragma[nomagic] private predicate hasIncompatibleBlanketLikeTarget( - ImplItemNode impl, DerefChain derefChain, BorrowKind borrow + ImplItemNode impl, FunctionPosition selfPos, DerefChain derefChain, BorrowKind borrow ) { - ReceiverIsNotInstantiationOfBlanketLikeSelfParam::argIsNotInstantiationOf(MkMethodCallCand(this, - derefChain, borrow), impl, _, _) + ArgIsNotInstantiationOfBlanketLikeSelfParam::argIsNotInstantiationOf(MkAssocFunctionCallCand(this, + selfPos, _, derefChain, borrow), impl, _, _) or - ReceiverSatisfiesBlanketLikeConstraint::dissatisfiesBlanketConstraint(MkMethodCallCand(this, - derefChain, borrow), impl) + ArgSatisfiesBlanketLikeConstraint::dissatisfiesBlanketConstraint(MkAssocFunctionCallCand(this, + selfPos, _, derefChain, borrow), impl) } /** - * Same as `getACandidateReceiverTypeAt`, but excludes pseudo types `!` and `unknown`. + * Same as `getTypeAt`, but excludes pseudo types `!` and `unknown`. */ pragma[nomagic] - Type getANonPseudoCandidateReceiverTypeAt( - DerefChain derefChain, BorrowKind borrow, TypePath path + Type getANonPseudoTypeAt( + FunctionPosition selfPos, DerefChain derefChain, BorrowKind borrow, TypePath path ) { - result = this.getACandidateReceiverTypeAt(derefChain, borrow, path) and + result = this.getTypeAt(selfPos, derefChain, borrow, path) and result != TNeverType() and result != TUnknownType() } pragma[nomagic] private Type getComplexStrippedType( - DerefChain derefChain, BorrowKind borrow, TypePath strippedTypePath + FunctionPosition selfPos, DerefChain derefChain, BorrowKind borrow, TypePath strippedTypePath ) { - result = this.getANonPseudoCandidateReceiverTypeAt(derefChain, borrow, strippedTypePath) and - isComplexRootStripped(strippedTypePath, result) + result = this.getANonPseudoTypeAt(selfPos, derefChain, borrow, strippedTypePath) and + ( + isComplexRootStripped(strippedTypePath, result) + or + selfPos.isTypeQualifier() and strippedTypePath.isEmpty() + ) } bindingset[derefChain, borrow, strippedTypePath, strippedType] private predicate hasNoCompatibleNonBlanketLikeTargetCheck( - DerefChain derefChain, BorrowKind borrow, TypePath strippedTypePath, Type strippedType + FunctionPosition selfPos, DerefChain derefChain, BorrowKind borrow, TypePath strippedTypePath, + Type strippedType ) { forall(ImplOrTraitItemNode i | - methodCallNonBlanketCandidate(this, _, i, _, strippedTypePath, strippedType) + nonBlanketCandidate(this, _, selfPos, _, i, _, strippedTypePath, strippedType) | - this.hasIncompatibleTarget(i, derefChain, borrow, strippedType) + this.hasIncompatibleTarget(i, selfPos, derefChain, borrow, strippedType) ) } bindingset[derefChain, borrow, strippedTypePath, strippedType] private predicate hasNoCompatibleTargetCheck( - DerefChain derefChain, BorrowKind borrow, TypePath strippedTypePath, Type strippedType + FunctionPosition selfPos, DerefChain derefChain, BorrowKind borrow, TypePath strippedTypePath, + Type strippedType ) { - this.hasNoCompatibleNonBlanketLikeTargetCheck(derefChain, borrow, strippedTypePath, + this.hasNoCompatibleNonBlanketLikeTargetCheck(selfPos, derefChain, borrow, strippedTypePath, strippedType) and - forall(ImplItemNode i | methodCallBlanketLikeCandidate(this, _, i, _, _, _) | - this.hasIncompatibleBlanketLikeTarget(i, derefChain, borrow) + forall(ImplItemNode i | blanketLikeCandidate(this, _, selfPos, _, i, _, _, _) | + this.hasIncompatibleBlanketLikeTarget(i, selfPos, derefChain, borrow) ) } bindingset[derefChain, borrow, strippedTypePath, strippedType] private predicate hasNoCompatibleNonBlanketTargetCheck( - DerefChain derefChain, BorrowKind borrow, TypePath strippedTypePath, Type strippedType + FunctionPosition selfPos, DerefChain derefChain, BorrowKind borrow, TypePath strippedTypePath, + Type strippedType ) { - this.hasNoCompatibleNonBlanketLikeTargetCheck(derefChain, borrow, strippedTypePath, + this.hasNoCompatibleNonBlanketLikeTargetCheck(selfPos, derefChain, borrow, strippedTypePath, strippedType) and forall(ImplItemNode i | - methodCallBlanketLikeCandidate(this, _, i, _, _, _) and not i.isBlanketImplementation() + blanketLikeCandidate(this, _, selfPos, _, i, _, _, _) and + not i.isBlanketImplementation() | - this.hasIncompatibleBlanketLikeTarget(i, derefChain, borrow) + this.hasIncompatibleBlanketLikeTarget(i, selfPos, derefChain, borrow) ) } // forex using recursion pragma[nomagic] private predicate hasNoCompatibleTargetNoBorrowToIndex( - DerefChain derefChain, TypePath strippedTypePath, Type strippedType, int n + FunctionPosition selfPos, DerefChain derefChain, TypePath strippedTypePath, Type strippedType, + int n ) { ( - this.supportsAutoDerefAndBorrow() + this.supportsAutoDerefAndBorrow() and + selfPos.isSelf() or // needed for the `hasNoCompatibleTarget` check in - // `ReceiverSatisfiesBlanketLikeConstraintInput::hasBlanketCandidate` + // `ArgSatisfiesBlanketLikeConstraintInput::hasBlanketCandidate` derefChain.isEmpty() ) and - strippedType = this.getComplexStrippedType(derefChain, TNoBorrowKind(), strippedTypePath) and + strippedType = + this.getComplexStrippedType(selfPos, derefChain, TNoBorrowKind(), strippedTypePath) and n = -1 or - this.hasNoCompatibleTargetNoBorrowToIndex(derefChain, strippedTypePath, strippedType, n - 1) and + this.hasNoCompatibleTargetNoBorrowToIndex(selfPos, derefChain, strippedTypePath, strippedType, + n - 1) and exists(Type t | t = getNthLookupType(strippedType, n) | - this.hasNoCompatibleTargetCheck(derefChain, TNoBorrowKind(), strippedTypePath, t) + this.hasNoCompatibleTargetCheck(selfPos, derefChain, TNoBorrowKind(), strippedTypePath, t) ) } /** * Holds if the candidate receiver type represented by `derefChain` does not - * have a matching method target. + * have a matching call target at `selfPos`. */ pragma[nomagic] - predicate hasNoCompatibleTargetNoBorrow(DerefChain derefChain) { + predicate hasNoCompatibleTargetNoBorrow(FunctionPosition selfPos, DerefChain derefChain) { exists(Type strippedType | - this.hasNoCompatibleTargetNoBorrowToIndex(derefChain, _, strippedType, + this.hasNoCompatibleTargetNoBorrowToIndex(selfPos, derefChain, _, strippedType, getLastLookupTypeIndex(strippedType)) ) } @@ -1689,33 +1791,39 @@ private module MethodResolution { // forex using recursion pragma[nomagic] private predicate hasNoCompatibleNonBlanketTargetNoBorrowToIndex( - DerefChain derefChain, TypePath strippedTypePath, Type strippedType, int n + FunctionPosition selfPos, DerefChain derefChain, TypePath strippedTypePath, Type strippedType, + int n ) { ( - this.supportsAutoDerefAndBorrow() + this.supportsAutoDerefAndBorrow() and + selfPos.isSelf() or // needed for the `hasNoCompatibleTarget` check in - // `ReceiverSatisfiesBlanketLikeConstraintInput::hasBlanketCandidate` + // `ArgSatisfiesBlanketLikeConstraintInput::hasBlanketCandidate` derefChain.isEmpty() ) and - strippedType = this.getComplexStrippedType(derefChain, TNoBorrowKind(), strippedTypePath) and + strippedType = + this.getComplexStrippedType(selfPos, derefChain, TNoBorrowKind(), strippedTypePath) and n = -1 or - this.hasNoCompatibleNonBlanketTargetNoBorrowToIndex(derefChain, strippedTypePath, + this.hasNoCompatibleNonBlanketTargetNoBorrowToIndex(selfPos, derefChain, strippedTypePath, strippedType, n - 1) and exists(Type t | t = getNthLookupType(strippedType, n) | - this.hasNoCompatibleNonBlanketTargetCheck(derefChain, TNoBorrowKind(), strippedTypePath, t) + this.hasNoCompatibleNonBlanketTargetCheck(selfPos, derefChain, TNoBorrowKind(), + strippedTypePath, t) ) } /** * Holds if the candidate receiver type represented by `derefChain` does not have - * a matching non-blanket method target. + * a matching non-blanket call target at `selfPos`. */ pragma[nomagic] - predicate hasNoCompatibleNonBlanketTargetNoBorrow(DerefChain derefChain) { + predicate hasNoCompatibleNonBlanketTargetNoBorrow( + FunctionPosition selfPos, DerefChain derefChain + ) { exists(Type strippedType | - this.hasNoCompatibleNonBlanketTargetNoBorrowToIndex(derefChain, _, strippedType, + this.hasNoCompatibleNonBlanketTargetNoBorrowToIndex(selfPos, derefChain, _, strippedType, getLastLookupTypeIndex(strippedType)) ) } @@ -1723,29 +1831,30 @@ private module MethodResolution { // forex using recursion pragma[nomagic] private predicate hasNoCompatibleTargetSharedBorrowToIndex( - DerefChain derefChain, TypePath strippedTypePath, Type strippedType, int n + FunctionPosition selfPos, DerefChain derefChain, TypePath strippedTypePath, Type strippedType, + int n ) { - this.hasNoCompatibleTargetNoBorrow(derefChain) and + this.hasNoCompatibleTargetNoBorrow(selfPos, derefChain) and strippedType = - this.getComplexStrippedType(derefChain, TSomeBorrowKind(false), strippedTypePath) and + this.getComplexStrippedType(selfPos, derefChain, TSomeBorrowKind(false), strippedTypePath) and n = -1 or - this.hasNoCompatibleTargetSharedBorrowToIndex(derefChain, strippedTypePath, strippedType, - n - 1) and + this.hasNoCompatibleTargetSharedBorrowToIndex(selfPos, derefChain, strippedTypePath, + strippedType, n - 1) and exists(Type t | t = getNthLookupType(strippedType, n) | - this.hasNoCompatibleNonBlanketLikeTargetCheck(derefChain, TSomeBorrowKind(false), + this.hasNoCompatibleNonBlanketLikeTargetCheck(selfPos, derefChain, TSomeBorrowKind(false), strippedTypePath, t) ) } /** * Holds if the candidate receiver type represented by `derefChain`, followed - * by a shared borrow, does not have a matching method target. + * by a shared borrow, does not have a matching call target at `selfPos`. */ pragma[nomagic] - predicate hasNoCompatibleTargetSharedBorrow(DerefChain derefChain) { + predicate hasNoCompatibleTargetSharedBorrow(FunctionPosition selfPos, DerefChain derefChain) { exists(Type strippedType | - this.hasNoCompatibleTargetSharedBorrowToIndex(derefChain, _, strippedType, + this.hasNoCompatibleTargetSharedBorrowToIndex(selfPos, derefChain, _, strippedType, getLastLookupTypeIndex(strippedType)) ) } @@ -1753,28 +1862,30 @@ private module MethodResolution { // forex using recursion pragma[nomagic] private predicate hasNoCompatibleTargetMutBorrowToIndex( - DerefChain derefChain, TypePath strippedTypePath, Type strippedType, int n + FunctionPosition selfPos, DerefChain derefChain, TypePath strippedTypePath, Type strippedType, + int n ) { - this.hasNoCompatibleTargetSharedBorrow(derefChain) and + this.hasNoCompatibleTargetSharedBorrow(selfPos, derefChain) and strippedType = - this.getComplexStrippedType(derefChain, TSomeBorrowKind(true), strippedTypePath) and + this.getComplexStrippedType(selfPos, derefChain, TSomeBorrowKind(true), strippedTypePath) and n = -1 or - this.hasNoCompatibleTargetMutBorrowToIndex(derefChain, strippedTypePath, strippedType, n - 1) and + this.hasNoCompatibleTargetMutBorrowToIndex(selfPos, derefChain, strippedTypePath, + strippedType, n - 1) and exists(Type t | t = getNthLookupType(strippedType, n) | - this.hasNoCompatibleNonBlanketLikeTargetCheck(derefChain, TSomeBorrowKind(true), + this.hasNoCompatibleNonBlanketLikeTargetCheck(selfPos, derefChain, TSomeBorrowKind(true), strippedTypePath, t) ) } /** * Holds if the candidate receiver type represented by `derefChain`, followed - * by a `mut` borrow, does not have a matching method target. + * by a `mut` borrow, does not have a matching call target at `selfPos`. */ pragma[nomagic] - predicate hasNoCompatibleTargetMutBorrow(DerefChain derefChain) { + predicate hasNoCompatibleTargetMutBorrow(FunctionPosition selfPos, DerefChain derefChain) { exists(Type strippedType | - this.hasNoCompatibleTargetMutBorrowToIndex(derefChain, _, strippedType, + this.hasNoCompatibleTargetMutBorrowToIndex(selfPos, derefChain, _, strippedType, getLastLookupTypeIndex(strippedType)) ) } @@ -1782,65 +1893,74 @@ private module MethodResolution { // forex using recursion pragma[nomagic] private predicate hasNoCompatibleNonBlanketTargetSharedBorrowToIndex( - DerefChain derefChain, TypePath strippedTypePath, Type strippedType, int n + FunctionPosition selfPos, DerefChain derefChain, TypePath strippedTypePath, Type strippedType, + int n ) { - this.hasNoCompatibleTargetNoBorrow(derefChain) and + this.hasNoCompatibleTargetNoBorrow(selfPos, derefChain) and strippedType = - this.getComplexStrippedType(derefChain, TSomeBorrowKind(false), strippedTypePath) and + this.getComplexStrippedType(selfPos, derefChain, TSomeBorrowKind(false), strippedTypePath) and n = -1 or - this.hasNoCompatibleNonBlanketTargetSharedBorrowToIndex(derefChain, strippedTypePath, + this.hasNoCompatibleNonBlanketTargetSharedBorrowToIndex(selfPos, derefChain, strippedTypePath, strippedType, n - 1) and exists(Type t | t = getNthLookupType(strippedType, n) | - this.hasNoCompatibleNonBlanketTargetCheck(derefChain, TSomeBorrowKind(false), + this.hasNoCompatibleNonBlanketTargetCheck(selfPos, derefChain, TSomeBorrowKind(false), strippedTypePath, t) ) } /** * Holds if the candidate receiver type represented by `derefChain`, followed - * by a shared borrow, does not have a matching non-blanket method target. + * by a shared borrow, does not have a matching non-blanket call target at `selfPos`. */ pragma[nomagic] - predicate hasNoCompatibleNonBlanketTargetSharedBorrow(DerefChain derefChain) { + predicate hasNoCompatibleNonBlanketTargetSharedBorrow( + FunctionPosition selfPos, DerefChain derefChain + ) { exists(Type strippedType | - this.hasNoCompatibleNonBlanketTargetSharedBorrowToIndex(derefChain, _, strippedType, - getLastLookupTypeIndex(strippedType)) + this.hasNoCompatibleNonBlanketTargetSharedBorrowToIndex(selfPos, derefChain, _, + strippedType, getLastLookupTypeIndex(strippedType)) ) } // forex using recursion pragma[nomagic] private predicate hasNoCompatibleNonBlanketTargetMutBorrowToIndex( - DerefChain derefChain, TypePath strippedTypePath, Type strippedType, int n + FunctionPosition selfPos, DerefChain derefChain, TypePath strippedTypePath, Type strippedType, + int n ) { - this.hasNoCompatibleNonBlanketTargetSharedBorrow(derefChain) and + this.hasNoCompatibleNonBlanketTargetSharedBorrow(selfPos, derefChain) and strippedType = - this.getComplexStrippedType(derefChain, TSomeBorrowKind(true), strippedTypePath) and + this.getComplexStrippedType(selfPos, derefChain, TSomeBorrowKind(true), strippedTypePath) and n = -1 or - this.hasNoCompatibleNonBlanketTargetMutBorrowToIndex(derefChain, strippedTypePath, + this.hasNoCompatibleNonBlanketTargetMutBorrowToIndex(selfPos, derefChain, strippedTypePath, strippedType, n - 1) and exists(Type t | t = getNthLookupType(strippedType, n) | - this.hasNoCompatibleNonBlanketTargetCheck(derefChain, TSomeBorrowKind(true), + this.hasNoCompatibleNonBlanketTargetCheck(selfPos, derefChain, TSomeBorrowKind(true), strippedTypePath, t) ) } /** * Holds if the candidate receiver type represented by `derefChain`, followed - * by a `mut` borrow, does not have a matching non-blanket method target. + * by a `mut` borrow, does not have a matching non-blanket call target at `selfPos`. */ pragma[nomagic] - predicate hasNoCompatibleNonBlanketTargetMutBorrow(DerefChain derefChain) { + predicate hasNoCompatibleNonBlanketTargetMutBorrow( + FunctionPosition selfPos, DerefChain derefChain + ) { exists(Type strippedType | - this.hasNoCompatibleNonBlanketTargetMutBorrowToIndex(derefChain, _, strippedType, + this.hasNoCompatibleNonBlanketTargetMutBorrowToIndex(selfPos, derefChain, _, strippedType, getLastLookupTypeIndex(strippedType)) ) } /** - * Gets a [candidate receiver type][1] of this method call at `path`. + * Gets the type of this call at `selfPos` and `path`. + * + * In case this call supports auto-dereferencing and borrowing and `selfPos` is the + * `self` parameter position, the result is a [candidate receiver type][1]: * * The type is obtained by repeatedly dereferencing the receiver expression's type, * as long as the method cannot be resolved in an earlier candidate type, and possibly @@ -1852,18 +1972,19 @@ private module MethodResolution { * [1]: https://doc.rust-lang.org/reference/expressions/method-call-expr.html#r-expr.method.candidate-receivers */ pragma[nomagic] - Type getACandidateReceiverTypeAt(DerefChain derefChain, BorrowKind borrow, TypePath path) { - result = this.getACandidateReceiverTypeAtNoBorrow(derefChain, path) and + Type getTypeAt(FunctionPosition selfPos, DerefChain derefChain, BorrowKind borrow, TypePath path) { + result = this.getTypeAtNoBorrow(selfPos, derefChain, path) and borrow.isNoBorrow() or exists(RefType rt | // first try shared borrow this.supportsAutoDerefAndBorrow() and - this.hasNoCompatibleTargetNoBorrow(derefChain) and + selfPos.isSelf() and + this.hasNoCompatibleTargetNoBorrow(selfPos, derefChain) and borrow.isSharedBorrow() or // then try mutable borrow - this.hasNoCompatibleTargetSharedBorrow(derefChain) and + this.hasNoCompatibleTargetSharedBorrow(selfPos, derefChain) and borrow.isMutableBorrow() | rt = borrow.getRefType() and @@ -1872,7 +1993,7 @@ private module MethodResolution { result = rt or exists(TypePath suffix | - result = this.getACandidateReceiverTypeAtNoBorrow(derefChain, suffix) and + result = this.getTypeAtNoBorrow(selfPos, derefChain, suffix) and path = TypePath::cons(rt.getPositionalTypeParameter(0), suffix) ) ) @@ -1880,15 +2001,17 @@ private module MethodResolution { } /** - * Gets a method that this call resolves to after having applied a sequence of + * Gets a function that this call resolves to after having applied a sequence of * dereferences and possibly a borrow on the receiver type, encoded in `derefChain` * and `borrow`. */ pragma[nomagic] - Method resolveCallTarget(ImplOrTraitItemNode i, DerefChain derefChain, BorrowKind borrow) { - exists(MethodCallCand mcc | - mcc = MkMethodCallCand(this, derefChain, borrow) and - result = mcc.resolveCallTarget(i) + AssocFunction resolveCallTarget( + ImplOrTraitItemNode i, FunctionPosition selfPos, DerefChain derefChain, BorrowKind borrow + ) { + exists(AssocFunctionCallCand afcc | + afcc = MkAssocFunctionCallCand(this, selfPos, _, derefChain, borrow) and + result = afcc.resolveCallTarget(i) ) } @@ -1898,21 +2021,24 @@ private module MethodResolution { * resolve the call target. */ predicate argumentHasImplicitDerefChainBorrow(Expr arg, DerefChain derefChain, BorrowKind borrow) { - exists(this.resolveCallTarget(_, derefChain, borrow)) and - arg = this.getArg(any(ArgumentPosition pos | pos.isSelf())) and - not (derefChain.isEmpty() and borrow.isNoBorrow()) + exists(FunctionPosition self | + self.isSelf() and + exists(this.resolveCallTarget(_, self, derefChain, borrow)) and + arg = this.getNodeAt(self) and + not (derefChain.isEmpty() and borrow.isNoBorrow()) + ) } } - private class MethodCallMethodCallExpr extends MethodCall instanceof MethodCallExpr { + private class AssocFunctionCallMethodCallExpr extends AssocFunctionCall instanceof MethodCallExpr { pragma[nomagic] override predicate hasNameAndArity(string name, int arity) { name = super.getIdentifier().getText() and - arity = super.getArgList().getNumberOfArgs() + arity = super.getArgList().getNumberOfArgs() + 1 } - override Expr getArg(ArgumentPosition pos) { - result = MethodCallExpr.super.getSyntacticArgument(pos) + override Expr getNonReturnNodeAt(FunctionPosition pos) { + result = MethodCallExpr.super.getSyntacticArgument(pos.asArgumentPosition()) } override predicate supportsAutoDerefAndBorrow() { any() } @@ -1920,7 +2046,7 @@ private module MethodResolution { override Trait getTrait() { none() } } - private class MethodCallIndexExpr extends MethodCall instanceof IndexExpr { + private class AssocFunctionCallIndexExpr extends AssocFunctionCall instanceof IndexExpr { private predicate isInMutableContext() { // todo: does not handle all cases yet VariableImpl::assignmentOperationDescendant(_, this) @@ -1929,10 +2055,10 @@ private module MethodResolution { pragma[nomagic] override predicate hasNameAndArity(string name, int arity) { (if this.isInMutableContext() then name = "index_mut" else name = "index") and - arity = 1 + arity = 2 } - override Expr getArg(ArgumentPosition pos) { + override Expr getNonReturnNodeAt(FunctionPosition pos) { pos.isSelf() and result = super.getBase() or @@ -1949,67 +2075,29 @@ private module MethodResolution { } } - private class MethodCallCallExpr extends MethodCall instanceof CallExpr { - MethodCallCallExpr() { + private class AssocFunctionCallCallExpr extends AssocFunctionCall instanceof CallExpr { + AssocFunctionCallCallExpr() { exists(getCallExprPathQualifier(this)) and - // even if a method cannot be resolved by path resolution, it may still + // even if a target cannot be resolved by path resolution, it may still // be possible to resolve a blanket implementation (so not `forex`) - forall(ItemNode i | i = CallExprImpl::getResolvedFunction(this) | i instanceof Method) - } - - bindingset[this, f] - pragma[inline_late] - private predicate hasTypeQualifiedCandidateFilter(Function f, ImplItemNode impl) { - f = impl.getAnAssocItem() - or - exists(TraitItemNode trait | - f = trait.getAnAssocItem() and - methodCallVisibleTraitCandidate(this, trait) and - impl.resolveTraitTy() = trait - ) - } - - /** - * Holds if this call has a type qualifier, and we are able to resolve, - * using path resolution, the method to a member of `impl` or the trait - * being implemented by `impl` (when this call os of the kind - * `::f()`). - * - * When this is the case, we still want to check that the type qualifier - * is an instance of the type being implemented, which is done in - * `TypeQualifierIsInstantiationOfImplSelfInput`. - */ - pragma[nomagic] - predicate hasTypeQualifiedCandidate(ImplItemNode impl) { - exists(Function f | - exists(getCallExprTypeQualifier(this, _, _)) and - f = CallExprImpl::getResolvedFunction(this) and - this.hasTypeQualifiedCandidateFilter(f, impl) - ) + forall(ItemNode i | i = CallExprImpl::getResolvedFunction(this) | i instanceof AssocFunction) } pragma[nomagic] override predicate hasNameAndArity(string name, int arity) { name = CallExprImpl::getFunctionPath(this).getText() and - arity = super.getArgList().getNumberOfArgs() - 1 + arity = super.getArgList().getNumberOfArgs() } - override Expr getArg(ArgumentPosition pos) { - pos.isSelf() and - result = super.getSyntacticPositionalArgument(0) - or - result = super.getSyntacticPositionalArgument(pos.asPosition() + 1) + override Expr getNonReturnNodeAt(FunctionPosition pos) { + result = super.getSyntacticPositionalArgument(pos.asPosition()) } - // needed for `TypeQualifierIsInstantiationOfImplSelfInput` - Type getTypeAt(TypePath path) { - result = substituteLookupTraits(getCallExprTypeQualifier(this, path, _)) - } - - pragma[nomagic] - predicate hasNoInherentTarget() { - // `_` is fine below, because auto-deref/borrow is not supported - MkMethodCallCand(this, _, _).(MethodCallCand).hasNoInherentTarget() + override Type getTypeAt(FunctionPosition pos, TypePath path) { + result = super.getTypeAt(pos, path) + or + pos.isTypeQualifier() and + result = getCallExprTypeQualifier(this, path, _) } override predicate supportsAutoDerefAndBorrow() { none() } @@ -2017,21 +2105,21 @@ private module MethodResolution { override Trait getTrait() { result = getCallExprTraitQualifier(this) } } - final class MethodCallOperation extends MethodCall instanceof Operation { + final class AssocFunctionCallOperation extends AssocFunctionCall instanceof Operation { pragma[nomagic] override predicate hasNameAndArity(string name, int arity) { super.isOverloaded(_, name, _) and - arity = super.getNumberOfOperands() - 1 + arity = super.getNumberOfOperands() } - override Expr getArg(ArgumentPosition pos) { + override Expr getNonReturnNodeAt(FunctionPosition pos) { pos.isSelf() and result = super.getOperand(0) or result = super.getOperand(pos.asPosition() + 1) } - private predicate implicitBorrowAt(ArgumentPosition pos, boolean isMutable) { + private predicate implicitBorrowAt(FunctionPosition pos, boolean isMutable) { exists(int borrows | super.isOverloaded(_, _, borrows) | pos.isSelf() and borrows >= 1 and @@ -2043,7 +2131,7 @@ private module MethodResolution { ) } - override Type getArgumentTypeAt(ArgumentPosition pos, TypePath path) { + override Type getTypeAt(FunctionPosition pos, TypePath path) { exists(boolean isMutable, RefType rt | this.implicitBorrowAt(pos, isMutable) and rt = getRefType(isMutable) @@ -2052,21 +2140,21 @@ private module MethodResolution { path.isEmpty() or exists(TypePath path0 | - result = inferType(this.getArg(pos), path0) and + result = inferType(this.getNodeAt(pos), path0) and path = TypePath::cons(rt.getPositionalTypeParameter(0), path0) ) ) or not this.implicitBorrowAt(pos, _) and - result = inferType(this.getArg(pos), path) + result = inferType(this.getNodeAt(pos), path) } override predicate argumentHasImplicitDerefChainBorrow( Expr arg, DerefChain derefChain, BorrowKind borrow ) { - exists(ArgumentPosition pos, boolean isMutable | + exists(FunctionPosition pos, boolean isMutable | this.implicitBorrowAt(pos, isMutable) and - arg = this.getArg(pos) and + arg = this.getNodeAt(pos) and derefChain = DerefChain::nil() and borrow = TSomeBorrowKind(isMutable) ) @@ -2078,74 +2166,102 @@ private module MethodResolution { } pragma[nomagic] - private Method getMethodSuccessor(ImplOrTraitItemNode i, string name, int arity) { + private AssocFunction getFunctionSuccessor(ImplOrTraitItemNode i, string name, int arity) { result = i.getASuccessor(name) and - arity = result.getParamList().getNumberOfParams() + arity = result.getNumberOfParamsInclSelf() } - private newtype TMethodCallCand = - MkMethodCallCand(MethodCall mc, DerefChain derefChain, BorrowKind borrow) { - exists(mc.getACandidateReceiverTypeAt(derefChain, borrow, _)) + private newtype TAssocFunctionCallCand = + MkAssocFunctionCallCand( + AssocFunctionCall afc, FunctionPosition selfPos, FunctionPosition selfPosAdj, + DerefChain derefChain, BorrowKind borrow + ) { + exists(TypePath strippedTypePath, Type strippedType | + strippedType = + substituteLookupTraits(afc.getANonPseudoTypeAt(selfPos, derefChain, borrow, + strippedTypePath)) + | + selfPos.isSelfOrTypeQualifier() + or + blanketLikeCandidate(afc, _, _, selfPosAdj, _, _, _, _) + or + nonBlanketCandidate(afc, _, _, selfPosAdj, _, _, strippedTypePath, strippedType) + ) and + if afc.hasReceiver() + then selfPosAdj = selfPos.getFunctionCallAdjusted() + else selfPosAdj = selfPos } - /** A method call with a dereference chain and a potential borrow. */ - private class MethodCallCand extends MkMethodCallCand { - MethodCall mc_; + /** A call with a dereference chain and a potential borrow. */ + private class AssocFunctionCallCand extends MkAssocFunctionCallCand { + AssocFunctionCall afc_; + FunctionPosition selfPos; + FunctionPosition selfPosAdj; DerefChain derefChain; BorrowKind borrow; - MethodCallCand() { this = MkMethodCallCand(mc_, derefChain, borrow) } + AssocFunctionCallCand() { + this = MkAssocFunctionCallCand(afc_, selfPos, selfPosAdj, derefChain, borrow) + } - MethodCall getMethodCall() { result = mc_ } + AssocFunctionCall getAssocFunctionCall() { result = afc_ } Type getTypeAt(TypePath path) { - result = - substituteLookupTraits(mc_.getANonPseudoCandidateReceiverTypeAt(derefChain, borrow, path)) + result = substituteLookupTraits(afc_.getANonPseudoTypeAt(selfPos, derefChain, borrow, path)) } pragma[nomagic] predicate hasNoCompatibleNonBlanketTarget() { - mc_.hasNoCompatibleNonBlanketTargetSharedBorrow(derefChain) and + afc_.hasNoCompatibleNonBlanketTargetSharedBorrow(selfPos, derefChain) and borrow.isSharedBorrow() or - mc_.hasNoCompatibleNonBlanketTargetMutBorrow(derefChain) and + afc_.hasNoCompatibleNonBlanketTargetMutBorrow(selfPos, derefChain) and borrow.isMutableBorrow() or - mc_.hasNoCompatibleNonBlanketTargetNoBorrow(derefChain) and + afc_.hasNoCompatibleNonBlanketTargetNoBorrow(selfPos, derefChain) and borrow.isNoBorrow() } pragma[nomagic] predicate hasSignature( - MethodCall mc, TypePath strippedTypePath, Type strippedType, string name, int arity + AssocFunctionCall afc, FunctionPosition pos, TypePath strippedTypePath, Type strippedType, + string name, int arity ) { strippedType = this.getTypeAt(strippedTypePath) and - isComplexRootStripped(strippedTypePath, strippedType) and - mc = mc_ and - mc.hasNameAndArity(name, arity) + ( + isComplexRootStripped(strippedTypePath, strippedType) + or + selfPos.isTypeQualifier() and strippedTypePath.isEmpty() + ) and + afc = afc_ and + afc.hasNameAndArity(name, arity) and + pos = selfPosAdj } /** - * Holds if the inherent method inside `impl` with matching name and arity can be + * Holds if the inherent function inside `impl` with matching name and arity can be * ruled out as a candidate for this call. */ pragma[nomagic] private predicate hasIncompatibleInherentTarget(Impl impl) { - ReceiverIsNotInstantiationOfInherentSelfParam::argIsNotInstantiationOf(this, impl, _, _) + ArgIsNotInstantiationOfInherentSelfParam::argIsNotInstantiationOf(this, impl, _, _) } /** - * Holds if this method call has no inherent target, i.e., it does not - * resolve to a method in an `impl` block for the type of the receiver. + * Holds if this function call has no inherent target, i.e., it does not + * resolve to a function in an `impl` block for the type of the receiver. */ pragma[nomagic] predicate hasNoInherentTarget() { - mc_.hasTrait() + afc_.hasTrait() or exists(TypePath strippedTypePath, Type strippedType, string name, int arity | - this.hasSignature(_, strippedTypePath, strippedType, name, arity) and + selfPosAdj.isTypeQualifier() or selfPosAdj.asPosition() = 0 + | + this.hasSignature(_, selfPosAdj, strippedTypePath, strippedType, name, arity) and forall(Impl i | - methodInfoNonBlanket(_, name, arity, i, _, strippedTypePath, strippedType) and + assocFunctionInfoNonBlanket(_, name, arity, _, selfPosAdj, i, _, strippedTypePath, + strippedType) and not i.hasTrait() | this.hasIncompatibleInherentTarget(i) @@ -2153,43 +2269,34 @@ private module MethodResolution { ) } - pragma[nomagic] - private predicate typeQualifierIsInstantiationOf(ImplItemNode i) { - TypeQualifierIsInstantiationOfImplSelf::isInstantiationOf(mc_, i, _) - } - pragma[nomagic] private predicate argIsInstantiationOf(ImplOrTraitItemNode i, string name, int arity) { - ( - ReceiverIsInstantiationOfSelfParam::argIsInstantiationOf(this, i, _) - or - this.typeQualifierIsInstantiationOf(i) - ) and - mc_.hasNameAndArity(name, arity) + ArgIsInstantiationOfSelfParam::argIsInstantiationOf(this, i, _) and + afc_.hasNameAndArity(name, arity) } pragma[nomagic] - Method resolveCallTargetCand(ImplOrTraitItemNode i) { + AssocFunction resolveCallTargetCand(ImplOrTraitItemNode i) { exists(string name, int arity | this.argIsInstantiationOf(i, name, arity) and - result = getMethodSuccessor(i, name, arity) + result = getFunctionSuccessor(i, name, arity) ) } - /** Gets a method that matches this method call. */ + /** Gets a function that matches this call. */ pragma[nomagic] - Method resolveCallTarget(ImplOrTraitItemNode i) { + AssocFunction resolveCallTarget(ImplOrTraitItemNode i) { result = this.resolveCallTargetCand(i) and not FunctionOverloading::functionResolutionDependsOnArgument(i, result, _, _) or - MethodArgsAreInstantiationsOf::argsAreInstantiationsOf(this, i, result) + CallArgsAreInstantiationsOf::argsAreInstantiationsOf(afc_, i, result) } string toString() { - result = mc_.toString() + " [" + derefChain.toString() + "; " + borrow + "]" + result = afc_ + " at " + selfPos + " [" + derefChain.toString() + "; " + borrow + "]" } - Location getLocation() { result = mc_.getLocation() } + Location getLocation() { result = afc_.getLocation() } } /** @@ -2197,21 +2304,23 @@ private module MethodResolution { */ private module ImplicitDeref { private newtype TMethodCallDerefCand = - MkMethodCallDerefCand(MethodCall mc, DerefChain derefChain) { + MkMethodCallDerefCand(AssocFunctionCall mc, FunctionPosition selfPos, DerefChain derefChain) { mc.supportsAutoDerefAndBorrow() and - mc.hasNoCompatibleTargetMutBorrow(derefChain) and - exists(mc.getACandidateReceiverTypeAtNoBorrow(derefChain, TypePath::nil())) + selfPos.isSelf() and + mc.hasNoCompatibleTargetMutBorrow(selfPos, derefChain) and + exists(mc.getTypeAtNoBorrow(selfPos, derefChain, TypePath::nil())) } /** A method call with a dereference chain. */ private class MethodCallDerefCand extends MkMethodCallDerefCand { - MethodCall mc; + AssocFunctionCall mc; + FunctionPosition selfPos; DerefChain derefChain; - MethodCallDerefCand() { this = MkMethodCallDerefCand(mc, derefChain) } + MethodCallDerefCand() { this = MkMethodCallDerefCand(mc, selfPos, derefChain) } Type getTypeAt(TypePath path) { - result = substituteLookupTraits(mc.getACandidateReceiverTypeAtNoBorrow(derefChain, path)) and + result = substituteLookupTraits(mc.getTypeAtNoBorrow(selfPos, derefChain, path)) and result != TNeverType() and result != TUnknownType() } @@ -2240,15 +2349,16 @@ private module MethodResolution { } /** - * Gets the type of the receiver of `mc` at `path` after applying the implicit + * Gets the type of the receiver of `afc` at `path` after applying the implicit * dereference inside `impl`, following the existing dereference chain `derefChain`. */ pragma[nomagic] Type getDereferencedCandidateReceiverType( - MethodCall mc, DerefImplItemNode impl, DerefChain derefChain, TypePath path + AssocFunctionCall afc, FunctionPosition selfPos, DerefImplItemNode impl, + DerefChain derefChain, TypePath path ) { exists(MethodCallDerefCand mcc, TypePath exprPath | - mcc = MkMethodCallDerefCand(mc, derefChain) and + mcc = MkMethodCallDerefCand(afc, selfPos, derefChain) and MethodCallSatisfiesDerefConstraint::satisfiesConstraintTypeThrough(mcc, impl, _, exprPath, result) and exprPath.isCons(getDerefTargetTypeParameter(), path) @@ -2256,21 +2366,22 @@ private module MethodResolution { } } - private module ReceiverSatisfiesBlanketLikeConstraintInput implements - BlanketImplementation::SatisfiesBlanketConstraintInputSig + private module ArgSatisfiesBlanketLikeConstraintInput implements + BlanketImplementation::SatisfiesBlanketConstraintInputSig { pragma[nomagic] predicate hasBlanketCandidate( - MethodCallCand mcc, ImplItemNode impl, TypePath blanketPath, TypeParam blanketTypeParam + AssocFunctionCallCand afcc, ImplItemNode impl, TypePath blanketPath, + TypeParam blanketTypeParam ) { - exists(MethodCall mc, BorrowKind borrow | - mcc = MkMethodCallCand(mc, _, borrow) and - methodCallBlanketLikeCandidate(mc, _, impl, _, blanketPath, blanketTypeParam) and + exists(AssocFunctionCall afc, FunctionPosition selfPosAdj, BorrowKind borrow | + afcc = MkAssocFunctionCallCand(afc, _, selfPosAdj, _, borrow) and + blanketLikeCandidate(afc, _, _, selfPosAdj, impl, _, blanketPath, blanketTypeParam) and // Only apply blanket implementations when no other implementations are possible; // this is to account for codebases that use the (unstable) specialization feature // (https://rust-lang.github.io/rfcs/1210-impl-specialization.html), as well as // cases where our blanket implementation filtering is not precise enough. - (mcc.hasNoCompatibleNonBlanketTarget() or not impl.isBlanketImplementation()) + (afcc.hasNoCompatibleNonBlanketTarget() or not impl.isBlanketImplementation()) | borrow.isNoBorrow() or @@ -2279,161 +2390,147 @@ private module MethodResolution { } } - private module ReceiverSatisfiesBlanketLikeConstraint = - BlanketImplementation::SatisfiesBlanketConstraint; + private module ArgSatisfiesBlanketLikeConstraint = + BlanketImplementation::SatisfiesBlanketConstraint; /** - * A configuration for matching the type of a receiver against the type of - * a `self` parameter. + * A configuration for matching the type of an argument against the type of + * a `self` parameter or similar parameter used to determine dispatch. */ - private module ReceiverIsInstantiationOfSelfParamInput implements - IsInstantiationOfInputSig + private module ArgIsInstantiationOfSelfParamInput implements + IsInstantiationOfInputSig { pragma[nomagic] additional predicate potentialInstantiationOf0( - MethodCallCand mcc, ImplOrTraitItemNode i, AssocFunctionType selfType + AssocFunctionCallCand afcc, ImplOrTraitItemNode i, AssocFunctionType selfType ) { exists( - MethodCall mc, Method m, string name, int arity, TypePath strippedTypePath, - Type strippedType + AssocFunctionCall afc, FunctionPosition pos, Function f, string name, int arity, + TypePath strippedTypePath, Type strippedType | - mcc.hasSignature(mc, strippedTypePath, strippedType, name, arity) + afcc.hasSignature(afc, pos, strippedTypePath, strippedType, name, arity) | - methodCallNonBlanketCandidate(mc, m, i, selfType, strippedTypePath, strippedType) + nonBlanketCandidate(afc, f, _, pos, i, selfType, strippedTypePath, strippedType) or - methodCallBlanketLikeCandidate(mc, m, i, selfType, _, _) and - ReceiverSatisfiesBlanketLikeConstraint::satisfiesBlanketConstraint(mcc, i) + blanketLikeCandidate(afc, f, _, pos, i, selfType, _, _) and + ArgSatisfiesBlanketLikeConstraint::satisfiesBlanketConstraint(afcc, i) ) } pragma[nomagic] predicate potentialInstantiationOf( - MethodCallCand mcc, TypeAbstraction abs, AssocFunctionType constraint + AssocFunctionCallCand afcc, TypeAbstraction abs, AssocFunctionType constraint ) { - potentialInstantiationOf0(mcc, abs, constraint) and + potentialInstantiationOf0(afcc, abs, constraint) and if abs.(Impl).hasTrait() then - // inherent methods take precedence over trait methods, so only allow - // trait methods when there are no matching inherent methods - mcc.hasNoInherentTarget() + // inherent functions take precedence over trait functions, so only allow + // trait functions when there are no matching inherent functions + afcc.hasNoInherentTarget() else any() } predicate relevantConstraint(AssocFunctionType constraint) { - methodInfo(_, _, _, _, constraint, _, _) + assocFunctionInfo(_, _, _, _, _, _, constraint, _, _) // todo } } - private module ReceiverIsInstantiationOfSelfParam = - ArgIsInstantiationOf; + private module ArgIsInstantiationOfSelfParam { + import ArgIsInstantiationOf - /** - * A configuration for anti-matching the type of a receiver against the type of - * a `self` parameter belonging to a blanket (like) implementation. - */ - private module ReceiverIsNotInstantiationOfBlanketLikeSelfParamInput implements - IsInstantiationOfInputSig - { pragma[nomagic] - predicate potentialInstantiationOf( - MethodCallCand mcc, TypeAbstraction abs, AssocFunctionType constraint + predicate argIsNotInstantiationOf( + AssocFunctionCall afc, ImplOrTraitItemNode i, FunctionPosition selfPos, DerefChain derefChain, + BorrowKind borrow, TypePath path ) { - methodCallBlanketLikeCandidate(mcc.getMethodCall(), _, abs, constraint, _, _) and - if abs.(Impl).hasTrait() - then - // inherent methods take precedence over trait methods, so only allow - // trait methods when there are no matching inherent methods - mcc.hasNoInherentTarget() - else any() + argIsNotInstantiationOf(MkAssocFunctionCallCand(afc, selfPos, _, derefChain, borrow), i, _, + path) } - } - - private module ReceiverIsNotInstantiationOfBlanketLikeSelfParam = - ArgIsInstantiationOf; - /** - * A configuration for matching the type qualifier of a method call - * against the type being implemented in an `impl` block. For example, - * in `Foo::::m(x)`, we check that the type `Foo` is an - * instance of the type being implemented. - */ - private module TypeQualifierIsInstantiationOfImplSelfInput implements - IsInstantiationOfInputSig - { pragma[nomagic] - private predicate potentialInstantiationOf0( - MethodCallCallExpr ce, ImplItemNode impl, TypeMention constraint + predicate argIsInstantiationOf( + AssocFunctionCall afc, ImplOrTraitItemNode i, FunctionPosition selfPos, DerefChain derefChain, + BorrowKind borrow, AssocFunctionType selfType ) { - ce.hasTypeQualifiedCandidate(impl) and - constraint = impl.getSelfPath() + argIsInstantiationOf(MkAssocFunctionCallCand(afc, selfPos, _, derefChain, borrow), i, selfType) } + } + /** + * A configuration for anti-matching the type of an argument against the type of + * a `self` parameter belonging to a blanket (like) implementation. + */ + private module ArgIsNotInstantiationOfBlanketLikeSelfParamInput implements + IsInstantiationOfInputSig + { pragma[nomagic] predicate potentialInstantiationOf( - MethodCallCallExpr ce, TypeAbstraction abs, TypeMention constraint + AssocFunctionCallCand afcc, TypeAbstraction abs, AssocFunctionType constraint ) { - potentialInstantiationOf0(ce, abs, constraint) and - if abs.(Impl).hasTrait() - then - // inherent methods take precedence over trait methods, so only allow - // trait methods when there are no matching inherent methods - ce.hasNoInherentTarget() - else any() - } - - predicate relevantConstraint(TypeMention constraint) { - potentialInstantiationOf0(_, _, constraint) + exists(AssocFunctionCall afc, FunctionPosition selfPosAdj | + afcc = MkAssocFunctionCallCand(afc, _, selfPosAdj, _, _) and + blanketLikeCandidate(afc, _, _, selfPosAdj, abs, constraint, _, _) and + if abs.(Impl).hasTrait() + then + // inherent functions take precedence over trait functions, so only allow + // trait functions when there are no matching inherent functions + afcc.hasNoInherentTarget() + else any() + ) } } - private module TypeQualifierIsInstantiationOfImplSelf = - IsInstantiationOf; + private module ArgIsNotInstantiationOfBlanketLikeSelfParam = + ArgIsInstantiationOf; /** - * A configuration for anti-matching the type of a receiver against the type of + * A configuration for anti-matching the type of an argument against the type of * a `self` parameter in an inherent method. */ - private module ReceiverIsNotInstantiationOfInherentSelfParamInput implements - IsInstantiationOfInputSig + private module ArgIsNotInstantiationOfInherentSelfParamInput implements + IsInstantiationOfInputSig { pragma[nomagic] predicate potentialInstantiationOf( - MethodCallCand mcc, TypeAbstraction abs, AssocFunctionType constraint + AssocFunctionCallCand afcc, TypeAbstraction abs, AssocFunctionType constraint ) { - ReceiverIsInstantiationOfSelfParamInput::potentialInstantiationOf0(mcc, abs, constraint) and - abs = any(Impl i | not i.hasTrait()) + ArgIsInstantiationOfSelfParamInput::potentialInstantiationOf0(afcc, abs, constraint) and + abs = any(Impl i | not i.hasTrait()) and + // todo: comment + exists(FunctionPosition selfPosAdj | afcc = MkAssocFunctionCallCand(_, _, selfPosAdj, _, _) | + selfPosAdj.isTypeQualifier() or selfPosAdj.asPosition() = 0 + ) } } - private module ReceiverIsNotInstantiationOfInherentSelfParam = - ArgIsInstantiationOf; + private module ArgIsNotInstantiationOfInherentSelfParam = + ArgIsInstantiationOf; /** * A configuration for matching the types of positional arguments against the * types of parameters, when needed to disambiguate the call. */ - private module MethodArgsAreInstantiationsOfInput implements ArgsAreInstantiationsOfInputSig { + private module CallArgsAreInstantiationsOfInput implements ArgsAreInstantiationsOfInputSig { predicate toCheck(ImplOrTraitItemNode i, Function f, TypeParameter traitTp, FunctionPosition pos) { FunctionOverloading::functionResolutionDependsOnArgument(i, f, traitTp, pos) } - class Call extends MethodCallCand { - Type getArgType(FunctionPosition pos, TypePath path) { - result = mc_.getArgumentTypeAt(pos.asArgumentPosition(), path) - or - pos.isReturn() and - result = inferType(mc_.getNodeAt(pos), path) - } + final private class AssocFunctionCallFinal = AssocFunctionCall; + + class Call extends AssocFunctionCallFinal { + Type getArgType(FunctionPosition pos, TypePath path) { result = this.getTypeAt(pos, path) } predicate hasTargetCand(ImplOrTraitItemNode i, Function f) { - f = this.resolveCallTargetCand(i) + f = + any(AssocFunctionCallCand afcc | afcc = MkAssocFunctionCallCand(this, _, _, _, _)) + .resolveCallTargetCand(i) } } } - private module MethodArgsAreInstantiationsOf = - ArgsAreInstantiationsOf; + private module CallArgsAreInstantiationsOf = + ArgsAreInstantiationsOf; } /** @@ -2467,7 +2564,7 @@ private module MethodCallMatchingInput implements MatchingWithEnvironmentInputSi } Type getDeclaredType(DeclarationPosition dpos, TypePath path) { - result = m.getParameterTypeInclNonMethodSelf(someParent, dpos, path) + result = m.getParameterType(someParent, dpos, path) or dpos.isReturn() and result = m.getReturnType(someParent, path) @@ -2480,25 +2577,30 @@ private module MethodCallMatchingInput implements MatchingWithEnvironmentInputSi class AccessEnvironment = string; - bindingset[derefChain, borrow] - private AccessEnvironment encodeDerefChainBorrow(DerefChain derefChain, BorrowKind borrow) { - result = derefChain + ";" + borrow + bindingset[pos, derefChain, borrow] + private AccessEnvironment encodeDerefChainBorrow( + FunctionPosition pos, DerefChain derefChain, BorrowKind borrow + ) { + result = pos + ":" + derefChain + ";" + borrow } bindingset[derefChainBorrow] additional predicate decodeDerefChainBorrow( - string derefChainBorrow, DerefChain derefChain, BorrowKind borrow + string derefChainBorrow, FunctionPosition pos, DerefChain derefChain, BorrowKind borrow ) { - exists(int i | - i = derefChainBorrow.indexOf(";") and - derefChain = derefChainBorrow.prefix(i) and - borrow.toString() = derefChainBorrow.suffix(i + 1) + exists(int i, string rest, int j | + i = derefChainBorrow.indexOf(":") and + pos.toString() = derefChainBorrow.prefix(i) and + rest = derefChainBorrow.suffix(i + 1) and + j = rest.indexOf(";") and + derefChain = rest.prefix(j) and + borrow.toString() = rest.suffix(j + 1) ) } - final private class MethodCallFinal = MethodResolution::MethodCall; + final private class AssocFunctionCallFinal = AssocFunctionResolution::AssocFunctionCall; - class Access extends MethodCallFinal, ContextTyping::ContextTypedCallCand { + class Access extends AssocFunctionCallFinal, ContextTyping::ContextTypedCallCand { Access() { // handled in the `OperationMatchingInput` module not this instanceof Operation @@ -2517,46 +2619,43 @@ private module MethodCallMatchingInput implements MatchingWithEnvironmentInputSi } pragma[nomagic] - private Type getInferredSelfType(AccessPosition apos, string derefChainBorrow, TypePath path) { + private Type getInferredSelfType( + FunctionPosition pos, AccessPosition apos, string derefChainBorrow, TypePath path + ) { exists(DerefChain derefChain, BorrowKind borrow | - result = this.getACandidateReceiverTypeAt(derefChain, borrow, path) and - derefChainBorrow = encodeDerefChainBorrow(derefChain, borrow) and - apos.isSelf() + result = this.getTypeAt(pos, derefChain, borrow, path) and + derefChainBorrow = encodeDerefChainBorrow(pos, derefChain, borrow) and + if this.hasReceiver() then apos = pos else pos = apos.getFunctionCallAdjusted() ) } pragma[nomagic] - Type getInferredNonSelfType(AccessPosition apos, TypePath path) { - if - // index expression `x[i]` desugars to `*x.index(i)`, so we must account for - // the implicit deref - apos.isReturn() and - this instanceof IndexExpr - then - path.isEmpty() and - result instanceof RefType - or - exists(TypePath suffix | - result = inferType(this.getNodeAt(apos), suffix) and - path = TypePath::cons(getRefTypeParameter(_), suffix) - ) - else ( - not apos.isSelf() and - result = inferType(this.getNodeAt(apos), path) + private Type getInferredNonSelfType(FunctionPosition pos, AccessPosition apos, TypePath path) { + exists(DerefChain derefChain, BorrowKind borrow | + result = this.getTypeAt(pos, derefChain, borrow, path) and + derefChain.isEmpty() and + borrow.isNoBorrow() and + if this.hasReceiver() then apos = pos else pos = apos.getFunctionCallAdjusted() ) } bindingset[derefChainBorrow] Type getInferredType(string derefChainBorrow, AccessPosition apos, TypePath path) { - result = this.getInferredSelfType(apos, derefChainBorrow, path) - or - result = this.getInferredNonSelfType(apos, path) + exists(FunctionPosition pos | + result = this.getInferredSelfType(pos, apos, derefChainBorrow, path) + or + exists(FunctionPosition selfPos | + MethodCallMatchingInput::decodeDerefChainBorrow(derefChainBorrow, selfPos, _, _) and + result = this.getInferredNonSelfType(pos, apos, path) and + pos != selfPos + ) + ) } Method getTarget(ImplOrTraitItemNode i, string derefChainBorrow) { - exists(DerefChain derefChain, BorrowKind borrow | - derefChainBorrow = encodeDerefChainBorrow(derefChain, borrow) and - result = this.resolveCallTarget(i, derefChain, borrow) // mutual recursion; resolving method calls requires resolving types and vice versa + exists(FunctionPosition pos, DerefChain derefChain, BorrowKind borrow | + derefChainBorrow = encodeDerefChainBorrow(pos, derefChain, borrow) and + result = this.resolveCallTarget(i, pos, derefChain, borrow) // mutual recursion; resolving method calls requires resolving types and vice versa ) } @@ -2577,6 +2676,20 @@ private module MethodCallMatchingInput implements MatchingWithEnvironmentInputSi this.hasUnknownTypeAt(i, this.getTarget(i, derefChainBorrow), pos, path) ) } + + /** + * Holds if the return type of this call at `path` may have to be inferred + * from the context. + */ + pragma[nomagic] + predicate hasUnknownTypeAt(FunctionPosition pos, TypePath path) { + forex(ImplOrTraitItemNode i, Function f | + f = CallExprImpl::getResolvedFunction(this) and + f = i.getAnAssocItem() + | + this.hasUnknownTypeAt(i, f, pos, path) + ) + } } } @@ -2585,15 +2698,26 @@ private module MethodCallMatching = MatchingWithEnvironment; - /** A (potential) non-method call, `f(x)`. */ final class NonMethodCall extends CallExpr { NonMethodCall() { // even if a function cannot be resolved by path resolution, it may still // be possible to resolve a blanket implementation (so not `forex`) - forall(Function f | f = CallExprImpl::getResolvedFunction(this) | - f instanceof NonMethodFunction - ) + forall(Function f | f = CallExprImpl::getResolvedFunction(this) | not f instanceof Method) } - pragma[nomagic] - predicate hasNameAndArity(string name, int arity) { - name = CallExprImpl::getFunctionPath(this).getText() and - arity = this.getArgList().getNumberOfArgs() - } - - /** - * Gets the item that this function call resolves to using path resolution, - * if any. - */ - private ItemNode getPathResolutionResolved() { - result = CallExprImpl::getResolvedFunction(this) and - not result.(Function).hasSelfParam() - } - - /** - * Gets the associated function that this function call resolves to using path - * resolution, if any. - */ - pragma[nomagic] - NonMethodFunction getPathResolutionResolved(ImplOrTraitItemNode i) { - result = this.getPathResolutionResolved() and - result = i.getAnAssocItem() - } - - /** - * Gets the blanket function that this call may resolve to, if any. - */ - pragma[nomagic] - NonMethodFunction resolveCallTargetBlanketCand(ImplItemNode impl) { - exists(string name | - this.hasNameAndArity(pragma[only_bind_into](name), _) and - ArgIsInstantiationOfBlanketParam::argIsInstantiationOf(MkCallAndBlanketPos(this, _), impl, _) and - result = impl.getASuccessor(pragma[only_bind_into](name)) - ) - } - - /** Gets the trait targeted by this call, if any. */ - Trait getTrait() { result = getCallExprTraitQualifier(this) } - - /** Holds if this call targets a trait. */ - predicate hasTrait() { exists(this.getTrait()) } - AstNode getNodeAt(FunctionPosition pos) { result = this.getSyntacticArgument(pos.asArgumentPosition()) or result = this and pos.isReturn() } - Type getTypeAt(FunctionPosition pos, TypePath path) { - result = inferType(this.getNodeAt(pos), path) - } - - pragma[nomagic] - NonMethodFunction resolveCallTargetNonBlanketCand(ImplItemNode i) { - not this.hasTrait() and - result = this.getPathResolutionResolved(i) and - not exists(this.resolveCallTargetViaPathResolution()) and - functionResolutionDependsOnArgument(i, result, _, _) - } - - pragma[nomagic] - predicate resolveCallTargetBlanketLikeCand( - ImplItemNode impl, FunctionPosition pos, TypePath blanketPath, TypeParam blanketTypeParam - ) { - exists(string name, int arity, Trait trait, AssocFunctionType t | - this.hasNameAndArity(name, arity) and - exists(this.getTypeAt(pos, blanketPath)) and - functionInfoBlanketLikeRelevantPos(_, name, arity, impl, trait, pos, t, blanketPath, - blanketTypeParam) and - BlanketTraitIsVisible::traitIsVisible(this, trait) - | - not this.hasTrait() - or - trait = this.getTrait() - ) - } - - pragma[nomagic] - predicate hasTraitResolved(TraitItemNode trait, NonMethodFunction resolved) { - resolved = this.getPathResolutionResolved() and - trait = this.getTrait() - } - - /** - * Holds if this call has no compatible non-blanket target, and it has some - * candidate blanket target. - */ - pragma[nomagic] - predicate hasNoCompatibleNonBlanketTarget() { - this.resolveCallTargetBlanketLikeCand(_, _, _, _) and - not exists(this.resolveCallTargetViaPathResolution()) and - forall(ImplOrTraitItemNode i, Function f | f = this.resolveCallTargetNonBlanketCand(i) | - NonMethodArgsAreInstantiationsOfNonBlanket::argsAreNotInstantiationsOf(this, i, f) - ) and - ( - not this.hasTraitResolved(_, _) - or - exists( - TraitItemNode trait, NonMethodFunction resolved, FunctionPosition pos, TypePath path, - Type t - | - this.(NonMethodArgsAreInstantiationsOfNonBlanketInput::Call) - .hasTraitResolvedSelfType(trait, resolved, pos, path, t) - | - forall(ImplOrTraitItemNode i, Function f | - traitFunctionHasSelfType(trait, resolved, pos, path, t, i, f) - | - NonMethodArgsAreInstantiationsOfNonBlanket::argsAreNotInstantiationsOf(this, i, f) - ) - ) - ) - } - /** * Gets the target of this call, which can be resolved using only path resolution. */ pragma[nomagic] ItemNode resolveCallTargetViaPathResolution() { - not this.hasTrait() and - result = this.getPathResolutionResolved() and - not functionResolutionDependsOnArgument(_, result, _, _) - } - - /** - * Gets the target of this call, which can be resolved using type inference. - */ - pragma[nomagic] - NonMethodFunction resolveCallTargetViaTypeInference(ImplOrTraitItemNode i) { - result = this.resolveCallTargetBlanketCand(i) and - not FunctionOverloading::functionResolutionDependsOnArgument(_, result, _, _) - or - NonMethodArgsAreInstantiationsOfBlanket::argsAreInstantiationsOf(this, i, result) - or - NonMethodArgsAreInstantiationsOfNonBlanket::argsAreInstantiationsOf(this, i, result) - } - } - - private newtype TCallAndBlanketPos = - MkCallAndBlanketPos(NonMethodCall fc, FunctionPosition pos) { - fc.resolveCallTargetBlanketLikeCand(_, pos, _, _) - } - - /** A call tagged with a position. */ - private class CallAndBlanketPos extends MkCallAndBlanketPos { - NonMethodCall fc; - FunctionPosition pos; - - CallAndBlanketPos() { this = MkCallAndBlanketPos(fc, pos) } - - Location getLocation() { result = fc.getLocation() } - - Type getTypeAt(TypePath path) { result = fc.getTypeAt(pos, path) } - - string toString() { result = fc.toString() + " [arg " + pos + "]" } - } - - private module ArgSatisfiesBlanketConstraintInput implements - BlanketImplementation::SatisfiesBlanketConstraintInputSig - { - pragma[nomagic] - predicate hasBlanketCandidate( - CallAndBlanketPos fcp, ImplItemNode impl, TypePath blanketPath, TypeParam blanketTypeParam - ) { - exists(NonMethodCall fc, FunctionPosition pos | - fcp = MkCallAndBlanketPos(fc, pos) and - fc.resolveCallTargetBlanketLikeCand(impl, pos, blanketPath, blanketTypeParam) and - // Only apply blanket implementations when no other implementations are possible; - // this is to account for codebases that use the (unstable) specialization feature - // (https://rust-lang.github.io/rfcs/1210-impl-specialization.html), as well as - // cases where our blanket implementation filtering is not precise enough. - (fc.hasNoCompatibleNonBlanketTarget() or not impl.isBlanketImplementation()) - ) - } - } - - private module ArgSatisfiesBlanketConstraint = - BlanketImplementation::SatisfiesBlanketConstraint; - - /** - * A configuration for matching the type of an argument against the type of - * a parameter that mentions a satisfied blanket type parameter. - */ - private module ArgIsInstantiationOfBlanketParamInput implements - IsInstantiationOfInputSig - { - pragma[nomagic] - predicate potentialInstantiationOf( - CallAndBlanketPos fcp, TypeAbstraction abs, AssocFunctionType constraint - ) { - exists(FunctionPosition pos | - ArgSatisfiesBlanketConstraint::satisfiesBlanketConstraint(fcp, abs) and - fcp = MkCallAndBlanketPos(_, pos) and - functionInfoBlanketLikeRelevantPos(_, _, _, abs, _, pos, constraint, _, _) - ) - } - - predicate relevantConstraint(AssocFunctionType constraint) { - functionInfoBlanketLikeRelevantPos(_, _, _, _, _, _, constraint, _, _) - } - } - - private module ArgIsInstantiationOfBlanketParam = - ArgIsInstantiationOf; - - private Type getArgType( - NonMethodCall call, FunctionPosition pos, TypePath path, boolean isDefaultTypeArg - ) { - result = inferType(call.getNodeAt(pos), path) and - isDefaultTypeArg = false - or - result = getCallExprTypeQualifier(call, path, isDefaultTypeArg) and - pos.isSelf() - } - - private module NonMethodArgsAreInstantiationsOfBlanketInput implements - ArgsAreInstantiationsOfInputSig - { - predicate toCheck(ImplOrTraitItemNode i, Function f, TypeParameter tp, FunctionPosition pos) { - functionResolutionDependsOnArgument(i, f, pos, tp) - } - - final class Call extends NonMethodCall { - Type getArgType(FunctionPosition pos, TypePath path) { - result = getArgType(this, pos, path, false) - } - - predicate hasTargetCand(ImplOrTraitItemNode i, Function f) { - f = this.resolveCallTargetBlanketCand(i) - } - } - } - - private module NonMethodArgsAreInstantiationsOfBlanket = - ArgsAreInstantiationsOf; - - private module NonMethodArgsAreInstantiationsOfNonBlanketInput implements - ArgsAreInstantiationsOfInputSig - { - predicate toCheck(ImplOrTraitItemNode i, Function f, TypeParameter traitTp, FunctionPosition pos) { - functionResolutionDependsOnArgument(i, f, pos, traitTp) - or - // Also match against the trait function itself - FunctionOverloading::traitTypeParameterOccurrence(i, f, _, pos, _, traitTp) and - traitTp = TSelfTypeParameter(i) - } - - class Call extends NonMethodCall { - Type getArgType(FunctionPosition pos, TypePath path) { - result = getArgType(this, pos, path, _) - } - - /** - * Holds if this call is of the form `Trait::function(args)`, and the type at `pos` and - * `path` matches the `Self` type parameter of `Trait`. - */ - pragma[nomagic] - predicate hasTraitResolvedSelfType( - TraitItemNode trait, NonMethodFunction function, FunctionPosition pos, TypePath path, Type t - ) { - this.hasTraitResolved(trait, function) and - FunctionOverloading::traitTypeParameterOccurrence(trait, function, _, pos, path, - TSelfTypeParameter(trait)) and - t = substituteLookupTraits(this.getArgType(pos, path)) and - t != TUnknownType() - } - - predicate hasTargetCand(ImplOrTraitItemNode i, Function f) { - f = this.resolveCallTargetNonBlanketCand(i) - or - exists( - TraitItemNode trait, NonMethodFunction resolved, FunctionPosition pos, TypePath path, - Type t - | - this.hasTraitResolvedSelfType(trait, resolved, pos, path, t) and - traitFunctionHasSelfType(trait, resolved, pos, path, t, i, f) - ) - } + result = CallExprImpl::getResolvedFunction(this) and + not result instanceof AssocFunction } } - - private module NonMethodArgsAreInstantiationsOfNonBlanket = - ArgsAreInstantiationsOf; } abstract private class TupleLikeConstructor extends Addressable { @@ -3199,7 +2924,7 @@ private module NonMethodCallMatchingInput implements MatchingInputSig { } override Type getParameterType(DeclarationPosition dpos, TypePath path) { - result = f.getParameterTypeInclNonMethodSelf(i, dpos, path) + result = f.getParameterType(i, dpos, path) } override Type getReturnType(TypePath path) { result = f.getReturnType(i, path) } @@ -3243,7 +2968,7 @@ private module NonMethodCallMatchingInput implements MatchingInputSig { pragma[nomagic] Type getInferredType(AccessPosition apos, TypePath path) { - apos.isSelf() and + apos.isTypeQualifier() and result = getCallExprTypeQualifier(this, path, false) or result = inferType(this.getNodeAt(apos), path) @@ -3254,7 +2979,7 @@ private module NonMethodCallMatchingInput implements MatchingInputSig { exists(ImplOrTraitItemNodeOption i, NonMethodFunctionDeclaration f | result = TNonMethodFunctionDeclaration(i, f) | - f = this.resolveCallTargetViaTypeInference(i.asSome()) // mutual recursion; resolving some associated function calls requires resolving types + f = this.(AssocFunctionResolution::AssocFunctionCall).resolveCallTarget(i.asSome(), _, _, _) // mutual recursion; resolving some associated function calls requires resolving types or f = this.resolveCallTargetViaPathResolution() and f.isDirectlyFor(i) @@ -3276,12 +3001,6 @@ private module NonMethodCallMatchingInput implements MatchingInputSig { this.hasUnknownTypeAt(i.asSome(), f, pos, path) ) or - forex(ImplOrTraitItemNode i, NonMethodFunctionDeclaration f | - f = this.getPathResolutionResolved(i) - | - this.hasUnknownTypeAt(i, f, pos, path) - ) - or // Tuple declarations, such as `Result::Ok(...)`, may also be context typed exists(TupleLikeConstructor tc, TypeParameter tp | tc = this.resolveCallTargetViaPathResolution() and @@ -3301,14 +3020,11 @@ private module NonMethodCallMatchingInput implements MatchingInputSig { private module NonMethodCallMatching = Matching; pragma[nomagic] -private Type inferNonMethodCallType0(AstNode n, boolean isReturn, TypePath path) { - exists(NonMethodCallMatchingInput::Access a, NonMethodCallMatchingInput::AccessPosition apos | - n = a.getNodeAt(apos) and - if apos.isReturn() then isReturn = true else isReturn = false - | - result = NonMethodCallMatching::inferAccessType(a, apos, path) +private Type inferNonMethodCallType0(AstNode n, FunctionPosition pos, TypePath path) { + exists(NonMethodCallMatchingInput::Access a | n = a.getNodeAt(pos) | + result = NonMethodCallMatching::inferAccessType(a, pos, path) or - a.hasUnknownTypeAt(apos, path) and + a.hasUnknownTypeAt(pos, path) and result = TUnknownType() ) } @@ -3360,7 +3076,7 @@ private module OperationMatchingInput implements MatchingInputSig { } } - class Access extends MethodResolution::MethodCallOperation { + class Access extends AssocFunctionResolution::AssocFunctionCallOperation { Type getTypeArgument(TypeArgumentPosition apos, TypePath path) { none() } pragma[nomagic] @@ -3370,7 +3086,7 @@ private module OperationMatchingInput implements MatchingInputSig { Declaration getTarget() { exists(ImplOrTraitItemNode i | - result.isMethod(i, this.resolveCallTarget(i, _, _)) // mutual recursion + result.isMethod(i, this.resolveCallTarget(i, _, _, _)) // mutual recursion ) } } @@ -3379,11 +3095,10 @@ private module OperationMatchingInput implements MatchingInputSig { private module OperationMatching = Matching; pragma[nomagic] -private Type inferOperationType0(AstNode n, boolean isReturn, TypePath path) { - exists(OperationMatchingInput::Access a, OperationMatchingInput::AccessPosition apos | - n = a.getNodeAt(apos) and - result = OperationMatching::inferAccessType(a, apos, path) and - if apos.isReturn() then isReturn = true else isReturn = false +private Type inferOperationType0(AstNode n, FunctionPosition pos, TypePath path) { + exists(OperationMatchingInput::Access a | + n = a.getNodeAt(pos) and + result = OperationMatching::inferAccessType(a, pos, path) ) } @@ -3716,11 +3431,13 @@ private module AwaitSatisfiesConstraintInput implements SatisfiesConstraintInput } } +private module AwaitSatisfiesConstraint = + SatisfiesConstraint; + pragma[nomagic] private Type inferAwaitExprType(AstNode n, TypePath path) { exists(TypePath exprPath | - SatisfiesConstraint::satisfiesConstraintType(n.(AwaitExpr) - .getExpr(), _, exprPath, result) and + AwaitSatisfiesConstraint::satisfiesConstraintType(n.(AwaitExpr).getExpr(), _, exprPath, result) and exprPath.isCons(getFutureOutputTypeParameter(), path) ) } @@ -3922,13 +3639,15 @@ private AssociatedTypeTypeParameter getIntoIteratorItemTypeParameter() { result = getAssociatedTypeTypeParameter(any(IntoIteratorTrait t).getItemType()) } +private module ForIterableSatisfiesConstraint = + SatisfiesConstraint; + pragma[nomagic] private Type inferForLoopExprType(AstNode n, TypePath path) { // type of iterable -> type of pattern (loop variable) exists(ForExpr fe, TypePath exprPath, AssociatedTypeTypeParameter tp | n = fe.getPat() and - SatisfiesConstraint::satisfiesConstraintType(fe.getIterable(), - _, exprPath, result) and + ForIterableSatisfiesConstraint::satisfiesConstraintType(fe.getIterable(), _, exprPath, result) and exprPath.isCons(tp, path) | tp = getIntoIteratorItemTypeParameter() @@ -3963,10 +3682,12 @@ private module InvokedClosureSatisfiesConstraintInput implements } } +private module InvokedClosureSatisfiesConstraint = + SatisfiesConstraint; + /** Gets the type of `ce` when viewed as an implementation of `FnOnce`. */ private Type invokedClosureFnTypeAt(InvokedClosureExpr ce, TypePath path) { - SatisfiesConstraint::satisfiesConstraintType(ce, - _, path, result) + InvokedClosureSatisfiesConstraint::satisfiesConstraintType(ce, _, path, result) } /** @@ -4076,7 +3797,8 @@ private module Cached { cached predicate implicitDerefChainBorrow(Expr e, DerefChain derefChain, boolean borrow) { exists(BorrowKind bk | - any(MethodResolution::MethodCall mc).argumentHasImplicitDerefChainBorrow(e, derefChain, bk) and + any(AssocFunctionResolution::AssocFunctionCall afc) + .argumentHasImplicitDerefChainBorrow(e, derefChain, bk) and if bk.isNoBorrow() then borrow = false else borrow = true ) or @@ -4108,8 +3830,7 @@ private module Cached { or i instanceof ImplItemNode and dispatch = false | - result = call.(MethodResolution::MethodCall).resolveCallTarget(i, _, _) or - result = call.(NonMethodResolution::NonMethodCall).resolveCallTargetViaTypeInference(i) + result = call.(AssocFunctionResolution::AssocFunctionCall).resolveCallTarget(i, _, _, _) ) } @@ -4241,8 +3962,8 @@ private module Debug { Locatable getRelevantLocatable() { exists(string filepath, int startline, int startcolumn, int endline, int endcolumn | result.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and - filepath.matches("%/sqlx.rs") and - startline = [56 .. 60] + filepath.matches("%/main.rs") and + startline = 50 ) } diff --git a/rust/ql/test/library-tests/dataflow/taint/inline-taint-flow.expected b/rust/ql/test/library-tests/dataflow/taint/inline-taint-flow.expected index 255af4cc86ed..763bff966d3f 100644 --- a/rust/ql/test/library-tests/dataflow/taint/inline-taint-flow.expected +++ b/rust/ql/test/library-tests/dataflow/taint/inline-taint-flow.expected @@ -100,7 +100,9 @@ edges | main.rs:161:10:161:18 | source(...) | main.rs:161:10:161:25 | ... .shr(...) | provenance | MaD:30 | | main.rs:162:19:162:27 | source(...) | main.rs:162:10:162:28 | 1i64.shr(...) | provenance | MaD:30 | | main.rs:164:10:164:18 | source(...) | main.rs:164:10:164:30 | ... .bitor(...) | provenance | MaD:19 | +| main.rs:165:10:165:18 | source(...) | main.rs:165:10:165:27 | ... .bitor(...) | provenance | MaD:19 | | main.rs:166:21:166:29 | source(...) | main.rs:166:10:166:30 | 1i64.bitor(...) | provenance | MaD:19 | +| main.rs:167:18:167:26 | source(...) | main.rs:167:10:167:27 | 1.bitor(...) | provenance | MaD:19 | | main.rs:170:5:170:5 | [post] a | main.rs:171:5:171:5 | a | provenance | | | main.rs:170:5:170:5 | [post] a | main.rs:172:5:172:5 | a | provenance | | | main.rs:170:5:170:5 | [post] a | main.rs:173:5:173:5 | a | provenance | | @@ -351,8 +353,12 @@ nodes | main.rs:162:19:162:27 | source(...) | semmle.label | source(...) | | main.rs:164:10:164:18 | source(...) | semmle.label | source(...) | | main.rs:164:10:164:30 | ... .bitor(...) | semmle.label | ... .bitor(...) | +| main.rs:165:10:165:18 | source(...) | semmle.label | source(...) | +| main.rs:165:10:165:27 | ... .bitor(...) | semmle.label | ... .bitor(...) | | main.rs:166:10:166:30 | 1i64.bitor(...) | semmle.label | 1i64.bitor(...) | | main.rs:166:21:166:29 | source(...) | semmle.label | source(...) | +| main.rs:167:10:167:27 | 1.bitor(...) | semmle.label | 1.bitor(...) | +| main.rs:167:18:167:26 | source(...) | semmle.label | source(...) | | main.rs:170:5:170:5 | [post] a | semmle.label | [post] a | | main.rs:170:18:170:26 | source(...) | semmle.label | source(...) | | main.rs:171:5:171:5 | [post] a | semmle.label | [post] a | @@ -516,7 +522,9 @@ testFailures | main.rs:161:10:161:25 | ... .shr(...) | main.rs:161:10:161:18 | source(...) | main.rs:161:10:161:25 | ... .shr(...) | $@ | main.rs:161:10:161:18 | source(...) | source(...) | | main.rs:162:10:162:28 | 1i64.shr(...) | main.rs:162:19:162:27 | source(...) | main.rs:162:10:162:28 | 1i64.shr(...) | $@ | main.rs:162:19:162:27 | source(...) | source(...) | | main.rs:164:10:164:30 | ... .bitor(...) | main.rs:164:10:164:18 | source(...) | main.rs:164:10:164:30 | ... .bitor(...) | $@ | main.rs:164:10:164:18 | source(...) | source(...) | +| main.rs:165:10:165:27 | ... .bitor(...) | main.rs:165:10:165:18 | source(...) | main.rs:165:10:165:27 | ... .bitor(...) | $@ | main.rs:165:10:165:18 | source(...) | source(...) | | main.rs:166:10:166:30 | 1i64.bitor(...) | main.rs:166:21:166:29 | source(...) | main.rs:166:10:166:30 | 1i64.bitor(...) | $@ | main.rs:166:21:166:29 | source(...) | source(...) | +| main.rs:167:10:167:27 | 1.bitor(...) | main.rs:167:18:167:26 | source(...) | main.rs:167:10:167:27 | 1.bitor(...) | $@ | main.rs:167:18:167:26 | source(...) | source(...) | | main.rs:176:10:176:10 | a | main.rs:170:18:170:26 | source(...) | main.rs:176:10:176:10 | a | $@ | main.rs:170:18:170:26 | source(...) | source(...) | | main.rs:176:10:176:10 | a | main.rs:171:18:171:26 | source(...) | main.rs:176:10:176:10 | a | $@ | main.rs:171:18:171:26 | source(...) | source(...) | | main.rs:176:10:176:10 | a | main.rs:172:18:172:26 | source(...) | main.rs:176:10:176:10 | a | $@ | main.rs:172:18:172:26 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/taint/main.rs b/rust/ql/test/library-tests/dataflow/taint/main.rs index 07770cc71189..05dbd1eb702f 100644 --- a/rust/ql/test/library-tests/dataflow/taint/main.rs +++ b/rust/ql/test/library-tests/dataflow/taint/main.rs @@ -162,9 +162,9 @@ fn std_ops() { sink(1i64.shr(source(2))); // $ hasTaintFlow=2 sink(source(1).bitor(2i64)); // $ hasTaintFlow=1 - sink(source(1).bitor(2)); // $ MISSING: hasTaintFlow=1 + sink(source(1).bitor(2)); // $ hasTaintFlow=1 sink(1i64.bitor(source(2))); // $ hasTaintFlow=2 - sink(1.bitor(source(2))); // $ MISSING: hasTaintFlow=2 + sink(1.bitor(source(2))); // $ hasTaintFlow=2 let mut a: i64 = 1; a.add_assign(source(2)); diff --git a/rust/ql/test/library-tests/type-inference/CONSISTENCY/PathResolutionConsistency.expected b/rust/ql/test/library-tests/type-inference/CONSISTENCY/PathResolutionConsistency.expected index 734601169687..a753b733ba38 100644 --- a/rust/ql/test/library-tests/type-inference/CONSISTENCY/PathResolutionConsistency.expected +++ b/rust/ql/test/library-tests/type-inference/CONSISTENCY/PathResolutionConsistency.expected @@ -1,4 +1,4 @@ multipleResolvedTargets | main.rs:2223:9:2223:31 | ... .my_add(...) | | main.rs:2225:9:2225:29 | ... .my_add(...) | -| main.rs:2723:13:2723:17 | x.f() | +| main.rs:2733:13:2733:17 | x.f() | diff --git a/rust/ql/test/library-tests/type-inference/main.rs b/rust/ql/test/library-tests/type-inference/main.rs index 204bd7e55cb5..f342d3897f4d 100644 --- a/rust/ql/test/library-tests/type-inference/main.rs +++ b/rust/ql/test/library-tests/type-inference/main.rs @@ -2636,6 +2636,13 @@ mod block_types { } mod context_typed { + #[derive(Default)] + struct S; + + impl S { + fn f(self) {} + } + pub fn f() { let x = None; // $ type=x:T.i32 let x: Option = x; @@ -2683,6 +2690,9 @@ mod context_typed { let y = Default::default(); // $ type=y:i32 target=default x.push(y); // $ target=push + + let s = Default::default(); // $ target=default type=s:S + S::f(s); // $ target=f } } @@ -2740,6 +2750,7 @@ mod blanket_impl; mod closure; mod dereference; mod dyn_type; +mod regressions; fn main() { field_access::f(); // $ target=f diff --git a/rust/ql/test/library-tests/type-inference/regressions.rs b/rust/ql/test/library-tests/type-inference/regressions.rs new file mode 100644 index 000000000000..2830ca5aa2be --- /dev/null +++ b/rust/ql/test/library-tests/type-inference/regressions.rs @@ -0,0 +1,72 @@ +mod regression1 { + + pub struct S(T); + + pub enum E { + V { vec: Vec }, + } + + impl From> for Option { + fn from(s: S) -> Self { + Some(s.0) // $ fieldof=S + } + } + + pub fn f() -> E { + let mut vec_e = Vec::new(); // $ target=new + let mut opt_e = None; + + let e = E::V { vec: Vec::new() }; // $ target=new + + if let Some(e) = opt_e { + vec_e.push(e); // $ target=push + } + opt_e = e.into(); // $ target=into + + #[rustfmt::skip] + let _ = if let Some(last) = vec_e.pop() // $ target=pop + { + opt_e = last.into(); // $ target=into + }; + + opt_e.unwrap() // $ target=unwrap + } +} + +mod regression2 { + trait SomeTrait {} + + trait MyFrom { + fn my_from(value: T) -> Self; + } + + impl MyFrom for T { + fn my_from(s: T) -> Self { + s + } + } + + impl MyFrom for Option { + fn my_from(val: T) -> Option { + Some(val) + } + } + + pub struct S(T); + + impl MyFrom> for Option { + fn my_from(s: S) -> Self { + Some(s.0) // $ fieldof=S + } + } + + pub fn f(x: T2) -> T2 + where + T2: SomeTrait + MyFrom>, + Option: MyFrom, + { + let y = MyFrom::my_from(x); // $ target=my_from + let z = MyFrom::my_from(y); // $ target=my_from + z + } +} diff --git a/rust/ql/test/library-tests/type-inference/type-inference.expected b/rust/ql/test/library-tests/type-inference/type-inference.expected index 1b750fab4586..78358a8adab8 100644 --- a/rust/ql/test/library-tests/type-inference/type-inference.expected +++ b/rust/ql/test/library-tests/type-inference/type-inference.expected @@ -3630,129 +3630,132 @@ inferCertainType | main.rs:2633:18:2633:29 | ...::_print(...) | | {EXTERNAL LOCATION} | () | | main.rs:2633:18:2633:29 | { ... } | | {EXTERNAL LOCATION} | () | | main.rs:2633:29:2633:29 | a | | {EXTERNAL LOCATION} | () | -| main.rs:2639:16:2686:5 | { ... } | | {EXTERNAL LOCATION} | () | -| main.rs:2641:13:2641:13 | x | | {EXTERNAL LOCATION} | Option | -| main.rs:2641:13:2641:13 | x | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2645:26:2645:28 | opt | | {EXTERNAL LOCATION} | Option | -| main.rs:2645:26:2645:28 | opt | T | main.rs:2645:23:2645:23 | T | -| main.rs:2645:42:2645:42 | x | | main.rs:2645:23:2645:23 | T | -| main.rs:2645:48:2645:49 | { ... } | | {EXTERNAL LOCATION} | () | -| main.rs:2648:9:2648:24 | pin_option(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2655:13:2655:13 | x | | main.rs:2650:9:2653:9 | MyEither | -| main.rs:2655:17:2655:39 | ...::A {...} | | main.rs:2650:9:2653:9 | MyEither | -| main.rs:2656:13:2656:13 | x | | main.rs:2650:9:2653:9 | MyEither | -| main.rs:2656:13:2656:13 | x | T1 | {EXTERNAL LOCATION} | i32 | -| main.rs:2656:13:2656:13 | x | T2 | {EXTERNAL LOCATION} | String | -| main.rs:2656:40:2656:40 | x | | main.rs:2650:9:2653:9 | MyEither | -| main.rs:2657:13:2657:13 | x | | main.rs:2650:9:2653:9 | MyEither | -| main.rs:2657:13:2657:13 | x | T2 | {EXTERNAL LOCATION} | String | -| main.rs:2657:17:2657:52 | ...::A {...} | | main.rs:2650:9:2653:9 | MyEither | -| main.rs:2657:17:2657:52 | ...::A {...} | T2 | {EXTERNAL LOCATION} | String | -| main.rs:2659:13:2659:13 | x | | main.rs:2650:9:2653:9 | MyEither | -| main.rs:2659:13:2659:13 | x | T1 | {EXTERNAL LOCATION} | i32 | -| main.rs:2659:17:2661:9 | ...::B::<...> {...} | | main.rs:2650:9:2653:9 | MyEither | -| main.rs:2659:17:2661:9 | ...::B::<...> {...} | T1 | {EXTERNAL LOCATION} | i32 | -| main.rs:2660:20:2660:32 | ...::new(...) | | {EXTERNAL LOCATION} | String | -| main.rs:2663:29:2663:29 | e | | main.rs:2650:9:2653:9 | MyEither | -| main.rs:2663:29:2663:29 | e | T1 | main.rs:2663:26:2663:26 | T | -| main.rs:2663:29:2663:29 | e | T2 | {EXTERNAL LOCATION} | String | -| main.rs:2663:53:2663:53 | x | | main.rs:2663:26:2663:26 | T | -| main.rs:2663:59:2663:60 | { ... } | | {EXTERNAL LOCATION} | () | -| main.rs:2666:13:2666:13 | x | | main.rs:2650:9:2653:9 | MyEither | -| main.rs:2666:17:2668:9 | ...::B {...} | | main.rs:2650:9:2653:9 | MyEither | +| main.rs:2643:14:2643:17 | SelfParam | | main.rs:2639:5:2640:13 | S | +| main.rs:2643:20:2643:21 | { ... } | | {EXTERNAL LOCATION} | () | +| main.rs:2646:16:2696:5 | { ... } | | {EXTERNAL LOCATION} | () | +| main.rs:2648:13:2648:13 | x | | {EXTERNAL LOCATION} | Option | +| main.rs:2648:13:2648:13 | x | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2652:26:2652:28 | opt | | {EXTERNAL LOCATION} | Option | +| main.rs:2652:26:2652:28 | opt | T | main.rs:2652:23:2652:23 | T | +| main.rs:2652:42:2652:42 | x | | main.rs:2652:23:2652:23 | T | +| main.rs:2652:48:2652:49 | { ... } | | {EXTERNAL LOCATION} | () | +| main.rs:2655:9:2655:24 | pin_option(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2662:13:2662:13 | x | | main.rs:2657:9:2660:9 | MyEither | +| main.rs:2662:17:2662:39 | ...::A {...} | | main.rs:2657:9:2660:9 | MyEither | +| main.rs:2663:13:2663:13 | x | | main.rs:2657:9:2660:9 | MyEither | +| main.rs:2663:13:2663:13 | x | T1 | {EXTERNAL LOCATION} | i32 | +| main.rs:2663:13:2663:13 | x | T2 | {EXTERNAL LOCATION} | String | +| main.rs:2663:40:2663:40 | x | | main.rs:2657:9:2660:9 | MyEither | +| main.rs:2664:13:2664:13 | x | | main.rs:2657:9:2660:9 | MyEither | +| main.rs:2664:13:2664:13 | x | T2 | {EXTERNAL LOCATION} | String | +| main.rs:2664:17:2664:52 | ...::A {...} | | main.rs:2657:9:2660:9 | MyEither | +| main.rs:2664:17:2664:52 | ...::A {...} | T2 | {EXTERNAL LOCATION} | String | +| main.rs:2666:13:2666:13 | x | | main.rs:2657:9:2660:9 | MyEither | +| main.rs:2666:13:2666:13 | x | T1 | {EXTERNAL LOCATION} | i32 | +| main.rs:2666:17:2668:9 | ...::B::<...> {...} | | main.rs:2657:9:2660:9 | MyEither | +| main.rs:2666:17:2668:9 | ...::B::<...> {...} | T1 | {EXTERNAL LOCATION} | i32 | | main.rs:2667:20:2667:32 | ...::new(...) | | {EXTERNAL LOCATION} | String | -| main.rs:2669:9:2669:27 | pin_my_either(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2669:23:2669:23 | x | | main.rs:2650:9:2653:9 | MyEither | -| main.rs:2672:13:2672:13 | x | | {EXTERNAL LOCATION} | Result | -| main.rs:2672:13:2672:13 | x | E | {EXTERNAL LOCATION} | String | -| main.rs:2672:13:2672:13 | x | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2676:29:2676:31 | res | | {EXTERNAL LOCATION} | Result | -| main.rs:2676:29:2676:31 | res | E | main.rs:2676:26:2676:26 | E | -| main.rs:2676:29:2676:31 | res | T | main.rs:2676:23:2676:23 | T | -| main.rs:2676:48:2676:48 | x | | main.rs:2676:26:2676:26 | E | -| main.rs:2676:54:2676:55 | { ... } | | {EXTERNAL LOCATION} | () | -| main.rs:2679:9:2679:28 | pin_result(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2679:23:2679:27 | false | | {EXTERNAL LOCATION} | bool | -| main.rs:2681:17:2681:17 | x | | {EXTERNAL LOCATION} | Vec | -| main.rs:2681:17:2681:17 | x | A | {EXTERNAL LOCATION} | Global | -| main.rs:2681:21:2681:30 | ...::new(...) | | {EXTERNAL LOCATION} | Vec | -| main.rs:2681:21:2681:30 | ...::new(...) | A | {EXTERNAL LOCATION} | Global | -| main.rs:2682:9:2682:9 | x | | {EXTERNAL LOCATION} | Vec | -| main.rs:2682:9:2682:9 | x | A | {EXTERNAL LOCATION} | Global | -| main.rs:2685:9:2685:9 | x | | {EXTERNAL LOCATION} | Vec | -| main.rs:2685:9:2685:9 | x | A | {EXTERNAL LOCATION} | Global | -| main.rs:2692:14:2692:17 | SelfParam | | main.rs:2690:5:2698:5 | Self [trait MyTrait] | -| main.rs:2695:14:2695:18 | SelfParam | | {EXTERNAL LOCATION} | & | -| main.rs:2695:14:2695:18 | SelfParam | TRef | main.rs:2690:5:2698:5 | Self [trait MyTrait] | -| main.rs:2695:21:2695:25 | other | | {EXTERNAL LOCATION} | & | -| main.rs:2695:21:2695:25 | other | TRef | main.rs:2690:5:2698:5 | Self [trait MyTrait] | -| main.rs:2695:44:2697:9 | { ... } | | {EXTERNAL LOCATION} | & | -| main.rs:2695:44:2697:9 | { ... } | TRef | main.rs:2690:5:2698:5 | Self [trait MyTrait] | -| main.rs:2696:13:2696:16 | self | | {EXTERNAL LOCATION} | & | -| main.rs:2696:13:2696:16 | self | TRef | main.rs:2690:5:2698:5 | Self [trait MyTrait] | -| main.rs:2702:14:2702:17 | SelfParam | | {EXTERNAL LOCATION} | i32 | -| main.rs:2702:28:2704:9 | { ... } | | {EXTERNAL LOCATION} | i32 | -| main.rs:2703:13:2703:16 | self | | {EXTERNAL LOCATION} | i32 | -| main.rs:2709:14:2709:17 | SelfParam | | {EXTERNAL LOCATION} | usize | -| main.rs:2709:28:2711:9 | { ... } | | {EXTERNAL LOCATION} | usize | -| main.rs:2710:13:2710:16 | self | | {EXTERNAL LOCATION} | usize | -| main.rs:2716:14:2716:17 | SelfParam | | {EXTERNAL LOCATION} | & | -| main.rs:2716:14:2716:17 | SelfParam | TRef | main.rs:2714:10:2714:10 | T | -| main.rs:2716:28:2718:9 | { ... } | | {EXTERNAL LOCATION} | & | -| main.rs:2716:28:2718:9 | { ... } | TRef | main.rs:2714:10:2714:10 | T | -| main.rs:2717:13:2717:16 | self | | {EXTERNAL LOCATION} | & | -| main.rs:2717:13:2717:16 | self | TRef | main.rs:2714:10:2714:10 | T | -| main.rs:2721:25:2725:5 | { ... } | | {EXTERNAL LOCATION} | usize | -| main.rs:2727:12:2735:5 | { ... } | | {EXTERNAL LOCATION} | () | -| main.rs:2728:13:2728:13 | x | | {EXTERNAL LOCATION} | usize | -| main.rs:2729:13:2729:13 | y | | {EXTERNAL LOCATION} | & | -| main.rs:2729:17:2729:18 | &1 | | {EXTERNAL LOCATION} | & | -| main.rs:2730:17:2730:17 | x | | {EXTERNAL LOCATION} | usize | -| main.rs:2730:21:2730:21 | y | | {EXTERNAL LOCATION} | & | -| main.rs:2733:13:2733:13 | y | | {EXTERNAL LOCATION} | usize | -| main.rs:2734:23:2734:23 | y | | {EXTERNAL LOCATION} | usize | -| main.rs:2744:11:2779:1 | { ... } | | {EXTERNAL LOCATION} | () | -| main.rs:2745:5:2745:21 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2746:5:2746:20 | ...::f(...) | | main.rs:72:5:72:21 | Foo | -| main.rs:2747:5:2747:60 | ...::g(...) | | main.rs:72:5:72:21 | Foo | -| main.rs:2747:20:2747:38 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | -| main.rs:2747:41:2747:59 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | -| main.rs:2748:5:2748:35 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2749:5:2749:41 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2750:5:2750:45 | ...::test(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2751:5:2751:30 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2752:5:2752:21 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2753:5:2753:27 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2754:5:2754:32 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2755:5:2755:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2756:5:2756:36 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2757:5:2757:35 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2758:5:2758:29 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2759:5:2759:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2760:5:2760:24 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2761:5:2761:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2762:5:2762:18 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2763:5:2763:15 | ...::f(...) | | {EXTERNAL LOCATION} | dyn Future | -| main.rs:2763:5:2763:15 | ...::f(...) | dyn(Output) | {EXTERNAL LOCATION} | () | -| main.rs:2764:5:2764:19 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2765:5:2765:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2766:5:2766:14 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2767:5:2767:27 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2768:5:2768:15 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2769:5:2769:43 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2770:5:2770:15 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2771:5:2771:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2772:5:2772:28 | ...::test(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2773:5:2773:23 | ...::test(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2774:5:2774:41 | ...::test_all_patterns(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2775:5:2775:49 | ...::box_patterns(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2776:5:2776:20 | ...::test(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2777:5:2777:20 | ...::f(...) | | {EXTERNAL LOCATION} | Box | -| main.rs:2777:5:2777:20 | ...::f(...) | A | {EXTERNAL LOCATION} | Global | -| main.rs:2777:5:2777:20 | ...::f(...) | T | main.rs:2547:5:2549:5 | dyn MyTrait | -| main.rs:2777:5:2777:20 | ...::f(...) | T.dyn(T) | {EXTERNAL LOCATION} | i32 | -| main.rs:2777:16:2777:19 | true | | {EXTERNAL LOCATION} | bool | -| main.rs:2778:5:2778:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2670:29:2670:29 | e | | main.rs:2657:9:2660:9 | MyEither | +| main.rs:2670:29:2670:29 | e | T1 | main.rs:2670:26:2670:26 | T | +| main.rs:2670:29:2670:29 | e | T2 | {EXTERNAL LOCATION} | String | +| main.rs:2670:53:2670:53 | x | | main.rs:2670:26:2670:26 | T | +| main.rs:2670:59:2670:60 | { ... } | | {EXTERNAL LOCATION} | () | +| main.rs:2673:13:2673:13 | x | | main.rs:2657:9:2660:9 | MyEither | +| main.rs:2673:17:2675:9 | ...::B {...} | | main.rs:2657:9:2660:9 | MyEither | +| main.rs:2674:20:2674:32 | ...::new(...) | | {EXTERNAL LOCATION} | String | +| main.rs:2676:9:2676:27 | pin_my_either(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2676:23:2676:23 | x | | main.rs:2657:9:2660:9 | MyEither | +| main.rs:2679:13:2679:13 | x | | {EXTERNAL LOCATION} | Result | +| main.rs:2679:13:2679:13 | x | E | {EXTERNAL LOCATION} | String | +| main.rs:2679:13:2679:13 | x | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2683:29:2683:31 | res | | {EXTERNAL LOCATION} | Result | +| main.rs:2683:29:2683:31 | res | E | main.rs:2683:26:2683:26 | E | +| main.rs:2683:29:2683:31 | res | T | main.rs:2683:23:2683:23 | T | +| main.rs:2683:48:2683:48 | x | | main.rs:2683:26:2683:26 | E | +| main.rs:2683:54:2683:55 | { ... } | | {EXTERNAL LOCATION} | () | +| main.rs:2686:9:2686:28 | pin_result(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2686:23:2686:27 | false | | {EXTERNAL LOCATION} | bool | +| main.rs:2688:17:2688:17 | x | | {EXTERNAL LOCATION} | Vec | +| main.rs:2688:17:2688:17 | x | A | {EXTERNAL LOCATION} | Global | +| main.rs:2688:21:2688:30 | ...::new(...) | | {EXTERNAL LOCATION} | Vec | +| main.rs:2688:21:2688:30 | ...::new(...) | A | {EXTERNAL LOCATION} | Global | +| main.rs:2689:9:2689:9 | x | | {EXTERNAL LOCATION} | Vec | +| main.rs:2689:9:2689:9 | x | A | {EXTERNAL LOCATION} | Global | +| main.rs:2692:9:2692:9 | x | | {EXTERNAL LOCATION} | Vec | +| main.rs:2692:9:2692:9 | x | A | {EXTERNAL LOCATION} | Global | +| main.rs:2695:9:2695:15 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2702:14:2702:17 | SelfParam | | main.rs:2700:5:2708:5 | Self [trait MyTrait] | +| main.rs:2705:14:2705:18 | SelfParam | | {EXTERNAL LOCATION} | & | +| main.rs:2705:14:2705:18 | SelfParam | TRef | main.rs:2700:5:2708:5 | Self [trait MyTrait] | +| main.rs:2705:21:2705:25 | other | | {EXTERNAL LOCATION} | & | +| main.rs:2705:21:2705:25 | other | TRef | main.rs:2700:5:2708:5 | Self [trait MyTrait] | +| main.rs:2705:44:2707:9 | { ... } | | {EXTERNAL LOCATION} | & | +| main.rs:2705:44:2707:9 | { ... } | TRef | main.rs:2700:5:2708:5 | Self [trait MyTrait] | +| main.rs:2706:13:2706:16 | self | | {EXTERNAL LOCATION} | & | +| main.rs:2706:13:2706:16 | self | TRef | main.rs:2700:5:2708:5 | Self [trait MyTrait] | +| main.rs:2712:14:2712:17 | SelfParam | | {EXTERNAL LOCATION} | i32 | +| main.rs:2712:28:2714:9 | { ... } | | {EXTERNAL LOCATION} | i32 | +| main.rs:2713:13:2713:16 | self | | {EXTERNAL LOCATION} | i32 | +| main.rs:2719:14:2719:17 | SelfParam | | {EXTERNAL LOCATION} | usize | +| main.rs:2719:28:2721:9 | { ... } | | {EXTERNAL LOCATION} | usize | +| main.rs:2720:13:2720:16 | self | | {EXTERNAL LOCATION} | usize | +| main.rs:2726:14:2726:17 | SelfParam | | {EXTERNAL LOCATION} | & | +| main.rs:2726:14:2726:17 | SelfParam | TRef | main.rs:2724:10:2724:10 | T | +| main.rs:2726:28:2728:9 | { ... } | | {EXTERNAL LOCATION} | & | +| main.rs:2726:28:2728:9 | { ... } | TRef | main.rs:2724:10:2724:10 | T | +| main.rs:2727:13:2727:16 | self | | {EXTERNAL LOCATION} | & | +| main.rs:2727:13:2727:16 | self | TRef | main.rs:2724:10:2724:10 | T | +| main.rs:2731:25:2735:5 | { ... } | | {EXTERNAL LOCATION} | usize | +| main.rs:2737:12:2745:5 | { ... } | | {EXTERNAL LOCATION} | () | +| main.rs:2738:13:2738:13 | x | | {EXTERNAL LOCATION} | usize | +| main.rs:2739:13:2739:13 | y | | {EXTERNAL LOCATION} | & | +| main.rs:2739:17:2739:18 | &1 | | {EXTERNAL LOCATION} | & | +| main.rs:2740:17:2740:17 | x | | {EXTERNAL LOCATION} | usize | +| main.rs:2740:21:2740:21 | y | | {EXTERNAL LOCATION} | & | +| main.rs:2743:13:2743:13 | y | | {EXTERNAL LOCATION} | usize | +| main.rs:2744:23:2744:23 | y | | {EXTERNAL LOCATION} | usize | +| main.rs:2755:11:2790:1 | { ... } | | {EXTERNAL LOCATION} | () | +| main.rs:2756:5:2756:21 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2757:5:2757:20 | ...::f(...) | | main.rs:72:5:72:21 | Foo | +| main.rs:2758:5:2758:60 | ...::g(...) | | main.rs:72:5:72:21 | Foo | +| main.rs:2758:20:2758:38 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | +| main.rs:2758:41:2758:59 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | +| main.rs:2759:5:2759:35 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2760:5:2760:41 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2761:5:2761:45 | ...::test(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2762:5:2762:30 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2763:5:2763:21 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2764:5:2764:27 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2765:5:2765:32 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2766:5:2766:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2767:5:2767:36 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2768:5:2768:35 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2769:5:2769:29 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2770:5:2770:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2771:5:2771:24 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2772:5:2772:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2773:5:2773:18 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2774:5:2774:15 | ...::f(...) | | {EXTERNAL LOCATION} | dyn Future | +| main.rs:2774:5:2774:15 | ...::f(...) | dyn(Output) | {EXTERNAL LOCATION} | () | +| main.rs:2775:5:2775:19 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2776:5:2776:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2777:5:2777:14 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2778:5:2778:27 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2779:5:2779:15 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2780:5:2780:43 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2781:5:2781:15 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2782:5:2782:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2783:5:2783:28 | ...::test(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2784:5:2784:23 | ...::test(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2785:5:2785:41 | ...::test_all_patterns(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2786:5:2786:49 | ...::box_patterns(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2787:5:2787:20 | ...::test(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2788:5:2788:20 | ...::f(...) | | {EXTERNAL LOCATION} | Box | +| main.rs:2788:5:2788:20 | ...::f(...) | A | {EXTERNAL LOCATION} | Global | +| main.rs:2788:5:2788:20 | ...::f(...) | T | main.rs:2547:5:2549:5 | dyn MyTrait | +| main.rs:2788:5:2788:20 | ...::f(...) | T.dyn(T) | {EXTERNAL LOCATION} | i32 | +| main.rs:2788:16:2788:19 | true | | {EXTERNAL LOCATION} | bool | +| main.rs:2789:5:2789:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | | overloading.rs:4:19:4:23 | SelfParam | | {EXTERNAL LOCATION} | & | | overloading.rs:4:19:4:23 | SelfParam | TRef | overloading.rs:2:5:11:5 | Self [trait FirstTrait] | | overloading.rs:4:34:6:9 | { ... } | | {EXTERNAL LOCATION} | bool | @@ -4920,6 +4923,47 @@ inferCertainType | raw_pointer.rs:58:19:58:23 | false | | {EXTERNAL LOCATION} | bool | | raw_pointer.rs:59:5:59:30 | raw_type_from_deref(...) | | {EXTERNAL LOCATION} | () | | raw_pointer.rs:59:25:59:29 | false | | {EXTERNAL LOCATION} | bool | +| regressions.rs:10:17:10:17 | s | | regressions.rs:3:5:3:23 | S | +| regressions.rs:10:17:10:17 | s | T | regressions.rs:9:10:9:10 | T | +| regressions.rs:10:34:12:9 | { ... } | | {EXTERNAL LOCATION} | Option | +| regressions.rs:10:34:12:9 | { ... } | T | regressions.rs:9:10:9:10 | T | +| regressions.rs:11:18:11:18 | s | | regressions.rs:3:5:3:23 | S | +| regressions.rs:11:18:11:18 | s | T | regressions.rs:9:10:9:10 | T | +| regressions.rs:15:21:33:5 | { ... } | | regressions.rs:5:5:7:5 | E | +| regressions.rs:16:17:16:21 | vec_e | | {EXTERNAL LOCATION} | Vec | +| regressions.rs:16:17:16:21 | vec_e | A | {EXTERNAL LOCATION} | Global | +| regressions.rs:16:25:16:34 | ...::new(...) | | {EXTERNAL LOCATION} | Vec | +| regressions.rs:16:25:16:34 | ...::new(...) | A | {EXTERNAL LOCATION} | Global | +| regressions.rs:19:13:19:13 | e | | regressions.rs:5:5:7:5 | E | +| regressions.rs:19:17:19:40 | ...::V {...} | | regressions.rs:5:5:7:5 | E | +| regressions.rs:19:29:19:38 | ...::new(...) | | {EXTERNAL LOCATION} | Vec | +| regressions.rs:19:29:19:38 | ...::new(...) | A | {EXTERNAL LOCATION} | Global | +| regressions.rs:21:9:23:9 | if ... {...} | | {EXTERNAL LOCATION} | () | +| regressions.rs:21:32:23:9 | { ... } | | {EXTERNAL LOCATION} | () | +| regressions.rs:22:13:22:17 | vec_e | | {EXTERNAL LOCATION} | Vec | +| regressions.rs:22:13:22:17 | vec_e | A | {EXTERNAL LOCATION} | Global | +| regressions.rs:24:17:24:17 | e | | regressions.rs:5:5:7:5 | E | +| regressions.rs:27:17:30:9 | if ... {...} | | {EXTERNAL LOCATION} | () | +| regressions.rs:27:37:27:41 | vec_e | | {EXTERNAL LOCATION} | Vec | +| regressions.rs:27:37:27:41 | vec_e | A | {EXTERNAL LOCATION} | Global | +| regressions.rs:28:9:30:9 | { ... } | | {EXTERNAL LOCATION} | () | +| regressions.rs:40:20:40:24 | value | | regressions.rs:39:18:39:18 | T | +| regressions.rs:44:20:44:20 | s | | regressions.rs:43:10:43:10 | T | +| regressions.rs:44:34:46:9 | { ... } | | regressions.rs:43:10:43:10 | T | +| regressions.rs:45:13:45:13 | s | | regressions.rs:43:10:43:10 | T | +| regressions.rs:50:20:50:22 | val | | regressions.rs:49:10:49:10 | T | +| regressions.rs:50:41:52:9 | { ... } | | {EXTERNAL LOCATION} | Option | +| regressions.rs:50:41:52:9 | { ... } | T | regressions.rs:49:10:49:10 | T | +| regressions.rs:51:18:51:20 | val | | regressions.rs:49:10:49:10 | T | +| regressions.rs:58:20:58:20 | s | | regressions.rs:55:5:55:23 | S | +| regressions.rs:58:20:58:20 | s | T | regressions.rs:57:10:57:10 | T | +| regressions.rs:58:37:60:9 | { ... } | | {EXTERNAL LOCATION} | Option | +| regressions.rs:58:37:60:9 | { ... } | T | regressions.rs:57:10:57:10 | T | +| regressions.rs:59:18:59:18 | s | | regressions.rs:55:5:55:23 | S | +| regressions.rs:59:18:59:18 | s | T | regressions.rs:57:10:57:10 | T | +| regressions.rs:63:22:63:22 | x | | regressions.rs:63:18:63:19 | T2 | +| regressions.rs:67:5:71:5 | { ... } | | regressions.rs:63:18:63:19 | T2 | +| regressions.rs:68:33:68:33 | x | | regressions.rs:63:18:63:19 | T2 | inferType | associated_types.rs:5:15:5:18 | SelfParam | | associated_types.rs:1:1:2:21 | Wrapper | | associated_types.rs:5:15:5:18 | SelfParam | A | associated_types.rs:4:6:4:6 | A | @@ -9488,7 +9532,6 @@ inferType | main.rs:1412:17:1412:20 | self | TRef.TSlice | main.rs:1410:14:1410:23 | T | | main.rs:1412:17:1412:27 | self.get(...) | | {EXTERNAL LOCATION} | Option | | main.rs:1412:17:1412:27 | self.get(...) | T | {EXTERNAL LOCATION} | & | -| main.rs:1412:17:1412:27 | self.get(...) | T.TRef | main.rs:1410:14:1410:23 | T | | main.rs:1412:17:1412:36 | ... .unwrap() | | {EXTERNAL LOCATION} | & | | main.rs:1412:17:1412:36 | ... .unwrap() | TRef | main.rs:1410:14:1410:23 | T | | main.rs:1412:26:1412:26 | 0 | | {EXTERNAL LOCATION} | i32 | @@ -11151,12 +11194,15 @@ inferType | main.rs:2319:18:2319:23 | range1 | Idx | {EXTERNAL LOCATION} | u16 | | main.rs:2319:25:2319:26 | { ... } | | {EXTERNAL LOCATION} | () | | main.rs:2323:13:2323:17 | vals3 | | {EXTERNAL LOCATION} | Vec | +| main.rs:2323:13:2323:17 | vals3 | A | {EXTERNAL LOCATION} | Global | | main.rs:2323:21:2323:33 | MacroExpr | | {EXTERNAL LOCATION} | Vec | +| main.rs:2323:21:2323:33 | MacroExpr | A | {EXTERNAL LOCATION} | Global | | main.rs:2323:26:2323:26 | 1 | | {EXTERNAL LOCATION} | i32 | | main.rs:2323:29:2323:29 | 2 | | {EXTERNAL LOCATION} | i32 | | main.rs:2323:32:2323:32 | 3 | | {EXTERNAL LOCATION} | i32 | | main.rs:2324:9:2324:25 | for ... in ... { ... } | | {EXTERNAL LOCATION} | () | | main.rs:2324:18:2324:22 | vals3 | | {EXTERNAL LOCATION} | Vec | +| main.rs:2324:18:2324:22 | vals3 | A | {EXTERNAL LOCATION} | Global | | main.rs:2324:24:2324:25 | { ... } | | {EXTERNAL LOCATION} | () | | main.rs:2326:13:2326:18 | vals4a | | {EXTERNAL LOCATION} | Vec | | main.rs:2326:13:2326:18 | vals4a | A | {EXTERNAL LOCATION} | Global | @@ -11246,18 +11292,25 @@ inferType | main.rs:2340:18:2340:22 | vals7 | T | {EXTERNAL LOCATION} | u8 | | main.rs:2340:24:2340:25 | { ... } | | {EXTERNAL LOCATION} | () | | main.rs:2342:13:2342:19 | matrix1 | | {EXTERNAL LOCATION} | Vec | +| main.rs:2342:13:2342:19 | matrix1 | A | {EXTERNAL LOCATION} | Global | | main.rs:2342:23:2342:50 | MacroExpr | | {EXTERNAL LOCATION} | Vec | +| main.rs:2342:23:2342:50 | MacroExpr | A | {EXTERNAL LOCATION} | Global | | main.rs:2342:28:2342:37 | (...) | | {EXTERNAL LOCATION} | Vec | +| main.rs:2342:28:2342:37 | (...) | A | {EXTERNAL LOCATION} | Global | | main.rs:2342:28:2342:37 | MacroExpr | | {EXTERNAL LOCATION} | Vec | +| main.rs:2342:28:2342:37 | MacroExpr | A | {EXTERNAL LOCATION} | Global | | main.rs:2342:33:2342:33 | 1 | | {EXTERNAL LOCATION} | i32 | | main.rs:2342:36:2342:36 | 2 | | {EXTERNAL LOCATION} | i32 | | main.rs:2342:40:2342:49 | (...) | | {EXTERNAL LOCATION} | Vec | +| main.rs:2342:40:2342:49 | (...) | A | {EXTERNAL LOCATION} | Global | | main.rs:2342:40:2342:49 | MacroExpr | | {EXTERNAL LOCATION} | Vec | +| main.rs:2342:40:2342:49 | MacroExpr | A | {EXTERNAL LOCATION} | Global | | main.rs:2342:45:2342:45 | 3 | | {EXTERNAL LOCATION} | i32 | | main.rs:2342:48:2342:48 | 4 | | {EXTERNAL LOCATION} | i32 | | main.rs:2344:13:2344:13 | _ | | {EXTERNAL LOCATION} | () | | main.rs:2344:17:2347:9 | for ... in ... { ... } | | {EXTERNAL LOCATION} | () | | main.rs:2344:28:2344:34 | matrix1 | | {EXTERNAL LOCATION} | Vec | +| main.rs:2344:28:2344:34 | matrix1 | A | {EXTERNAL LOCATION} | Global | | main.rs:2344:36:2347:9 | { ... } | | {EXTERNAL LOCATION} | () | | main.rs:2345:13:2346:13 | for ... in ... { ... } | | {EXTERNAL LOCATION} | () | | main.rs:2345:29:2346:13 | { ... } | | {EXTERNAL LOCATION} | () | @@ -11937,245 +11990,251 @@ inferType | main.rs:2633:18:2633:29 | { ... } | | {EXTERNAL LOCATION} | () | | main.rs:2633:29:2633:29 | a | | {EXTERNAL LOCATION} | () | | main.rs:2634:9:2634:9 | 0 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2639:16:2686:5 | { ... } | | {EXTERNAL LOCATION} | () | -| main.rs:2640:13:2640:13 | x | | {EXTERNAL LOCATION} | Option | -| main.rs:2640:13:2640:13 | x | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2640:17:2640:20 | None | | {EXTERNAL LOCATION} | Option | -| main.rs:2640:17:2640:20 | None | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2641:13:2641:13 | x | | {EXTERNAL LOCATION} | Option | -| main.rs:2641:13:2641:13 | x | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2641:30:2641:30 | x | | {EXTERNAL LOCATION} | Option | -| main.rs:2641:30:2641:30 | x | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2642:13:2642:13 | x | | {EXTERNAL LOCATION} | Option | -| main.rs:2642:13:2642:13 | x | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2642:17:2642:35 | ...::None | | {EXTERNAL LOCATION} | Option | -| main.rs:2642:17:2642:35 | ...::None | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2643:13:2643:13 | x | | {EXTERNAL LOCATION} | Option | -| main.rs:2643:13:2643:13 | x | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2643:17:2643:35 | ...::None::<...> | | {EXTERNAL LOCATION} | Option | -| main.rs:2643:17:2643:35 | ...::None::<...> | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2645:26:2645:28 | opt | | {EXTERNAL LOCATION} | Option | -| main.rs:2645:26:2645:28 | opt | T | main.rs:2645:23:2645:23 | T | -| main.rs:2645:42:2645:42 | x | | main.rs:2645:23:2645:23 | T | -| main.rs:2645:48:2645:49 | { ... } | | {EXTERNAL LOCATION} | () | +| main.rs:2643:14:2643:17 | SelfParam | | main.rs:2639:5:2640:13 | S | +| main.rs:2643:20:2643:21 | { ... } | | {EXTERNAL LOCATION} | () | +| main.rs:2646:16:2696:5 | { ... } | | {EXTERNAL LOCATION} | () | | main.rs:2647:13:2647:13 | x | | {EXTERNAL LOCATION} | Option | | main.rs:2647:13:2647:13 | x | T | {EXTERNAL LOCATION} | i32 | | main.rs:2647:17:2647:20 | None | | {EXTERNAL LOCATION} | Option | | main.rs:2647:17:2647:20 | None | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2648:9:2648:24 | pin_option(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2648:20:2648:20 | x | | {EXTERNAL LOCATION} | Option | -| main.rs:2648:20:2648:20 | x | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2648:23:2648:23 | 0 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2655:13:2655:13 | x | | main.rs:2650:9:2653:9 | MyEither | -| main.rs:2655:13:2655:13 | x | T1 | {EXTERNAL LOCATION} | i32 | -| main.rs:2655:13:2655:13 | x | T2 | {EXTERNAL LOCATION} | String | -| main.rs:2655:17:2655:39 | ...::A {...} | | main.rs:2650:9:2653:9 | MyEither | -| main.rs:2655:17:2655:39 | ...::A {...} | T1 | {EXTERNAL LOCATION} | i32 | -| main.rs:2655:17:2655:39 | ...::A {...} | T2 | {EXTERNAL LOCATION} | String | -| main.rs:2655:37:2655:37 | 0 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2656:13:2656:13 | x | | main.rs:2650:9:2653:9 | MyEither | -| main.rs:2656:13:2656:13 | x | T1 | {EXTERNAL LOCATION} | i32 | -| main.rs:2656:13:2656:13 | x | T2 | {EXTERNAL LOCATION} | String | -| main.rs:2656:40:2656:40 | x | | main.rs:2650:9:2653:9 | MyEither | -| main.rs:2656:40:2656:40 | x | T1 | {EXTERNAL LOCATION} | i32 | -| main.rs:2656:40:2656:40 | x | T2 | {EXTERNAL LOCATION} | String | -| main.rs:2657:13:2657:13 | x | | main.rs:2650:9:2653:9 | MyEither | -| main.rs:2657:13:2657:13 | x | T1 | {EXTERNAL LOCATION} | i32 | -| main.rs:2657:13:2657:13 | x | T2 | {EXTERNAL LOCATION} | String | -| main.rs:2657:17:2657:52 | ...::A {...} | | main.rs:2650:9:2653:9 | MyEither | -| main.rs:2657:17:2657:52 | ...::A {...} | T1 | {EXTERNAL LOCATION} | i32 | -| main.rs:2657:17:2657:52 | ...::A {...} | T2 | {EXTERNAL LOCATION} | String | -| main.rs:2657:50:2657:50 | 0 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2659:13:2659:13 | x | | main.rs:2650:9:2653:9 | MyEither | -| main.rs:2659:13:2659:13 | x | T1 | {EXTERNAL LOCATION} | i32 | -| main.rs:2659:13:2659:13 | x | T2 | {EXTERNAL LOCATION} | String | -| main.rs:2659:17:2661:9 | ...::B::<...> {...} | | main.rs:2650:9:2653:9 | MyEither | -| main.rs:2659:17:2661:9 | ...::B::<...> {...} | T1 | {EXTERNAL LOCATION} | i32 | -| main.rs:2659:17:2661:9 | ...::B::<...> {...} | T2 | {EXTERNAL LOCATION} | String | -| main.rs:2660:20:2660:32 | ...::new(...) | | {EXTERNAL LOCATION} | String | -| main.rs:2663:29:2663:29 | e | | main.rs:2650:9:2653:9 | MyEither | -| main.rs:2663:29:2663:29 | e | T1 | main.rs:2663:26:2663:26 | T | -| main.rs:2663:29:2663:29 | e | T2 | {EXTERNAL LOCATION} | String | -| main.rs:2663:53:2663:53 | x | | main.rs:2663:26:2663:26 | T | -| main.rs:2663:59:2663:60 | { ... } | | {EXTERNAL LOCATION} | () | -| main.rs:2666:13:2666:13 | x | | main.rs:2650:9:2653:9 | MyEither | +| main.rs:2648:13:2648:13 | x | | {EXTERNAL LOCATION} | Option | +| main.rs:2648:13:2648:13 | x | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2648:30:2648:30 | x | | {EXTERNAL LOCATION} | Option | +| main.rs:2648:30:2648:30 | x | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2649:13:2649:13 | x | | {EXTERNAL LOCATION} | Option | +| main.rs:2649:13:2649:13 | x | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2649:17:2649:35 | ...::None | | {EXTERNAL LOCATION} | Option | +| main.rs:2649:17:2649:35 | ...::None | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2650:13:2650:13 | x | | {EXTERNAL LOCATION} | Option | +| main.rs:2650:13:2650:13 | x | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2650:17:2650:35 | ...::None::<...> | | {EXTERNAL LOCATION} | Option | +| main.rs:2650:17:2650:35 | ...::None::<...> | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2652:26:2652:28 | opt | | {EXTERNAL LOCATION} | Option | +| main.rs:2652:26:2652:28 | opt | T | main.rs:2652:23:2652:23 | T | +| main.rs:2652:42:2652:42 | x | | main.rs:2652:23:2652:23 | T | +| main.rs:2652:48:2652:49 | { ... } | | {EXTERNAL LOCATION} | () | +| main.rs:2654:13:2654:13 | x | | {EXTERNAL LOCATION} | Option | +| main.rs:2654:13:2654:13 | x | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2654:17:2654:20 | None | | {EXTERNAL LOCATION} | Option | +| main.rs:2654:17:2654:20 | None | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2655:9:2655:24 | pin_option(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2655:20:2655:20 | x | | {EXTERNAL LOCATION} | Option | +| main.rs:2655:20:2655:20 | x | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2655:23:2655:23 | 0 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2662:13:2662:13 | x | | main.rs:2657:9:2660:9 | MyEither | +| main.rs:2662:13:2662:13 | x | T1 | {EXTERNAL LOCATION} | i32 | +| main.rs:2662:13:2662:13 | x | T2 | {EXTERNAL LOCATION} | String | +| main.rs:2662:17:2662:39 | ...::A {...} | | main.rs:2657:9:2660:9 | MyEither | +| main.rs:2662:17:2662:39 | ...::A {...} | T1 | {EXTERNAL LOCATION} | i32 | +| main.rs:2662:17:2662:39 | ...::A {...} | T2 | {EXTERNAL LOCATION} | String | +| main.rs:2662:37:2662:37 | 0 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2663:13:2663:13 | x | | main.rs:2657:9:2660:9 | MyEither | +| main.rs:2663:13:2663:13 | x | T1 | {EXTERNAL LOCATION} | i32 | +| main.rs:2663:13:2663:13 | x | T2 | {EXTERNAL LOCATION} | String | +| main.rs:2663:40:2663:40 | x | | main.rs:2657:9:2660:9 | MyEither | +| main.rs:2663:40:2663:40 | x | T1 | {EXTERNAL LOCATION} | i32 | +| main.rs:2663:40:2663:40 | x | T2 | {EXTERNAL LOCATION} | String | +| main.rs:2664:13:2664:13 | x | | main.rs:2657:9:2660:9 | MyEither | +| main.rs:2664:13:2664:13 | x | T1 | {EXTERNAL LOCATION} | i32 | +| main.rs:2664:13:2664:13 | x | T2 | {EXTERNAL LOCATION} | String | +| main.rs:2664:17:2664:52 | ...::A {...} | | main.rs:2657:9:2660:9 | MyEither | +| main.rs:2664:17:2664:52 | ...::A {...} | T1 | {EXTERNAL LOCATION} | i32 | +| main.rs:2664:17:2664:52 | ...::A {...} | T2 | {EXTERNAL LOCATION} | String | +| main.rs:2664:50:2664:50 | 0 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2666:13:2666:13 | x | | main.rs:2657:9:2660:9 | MyEither | | main.rs:2666:13:2666:13 | x | T1 | {EXTERNAL LOCATION} | i32 | | main.rs:2666:13:2666:13 | x | T2 | {EXTERNAL LOCATION} | String | -| main.rs:2666:17:2668:9 | ...::B {...} | | main.rs:2650:9:2653:9 | MyEither | -| main.rs:2666:17:2668:9 | ...::B {...} | T1 | {EXTERNAL LOCATION} | i32 | -| main.rs:2666:17:2668:9 | ...::B {...} | T2 | {EXTERNAL LOCATION} | String | +| main.rs:2666:17:2668:9 | ...::B::<...> {...} | | main.rs:2657:9:2660:9 | MyEither | +| main.rs:2666:17:2668:9 | ...::B::<...> {...} | T1 | {EXTERNAL LOCATION} | i32 | +| main.rs:2666:17:2668:9 | ...::B::<...> {...} | T2 | {EXTERNAL LOCATION} | String | | main.rs:2667:20:2667:32 | ...::new(...) | | {EXTERNAL LOCATION} | String | -| main.rs:2669:9:2669:27 | pin_my_either(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2669:23:2669:23 | x | | main.rs:2650:9:2653:9 | MyEither | -| main.rs:2669:23:2669:23 | x | T1 | {EXTERNAL LOCATION} | i32 | -| main.rs:2669:23:2669:23 | x | T2 | {EXTERNAL LOCATION} | String | -| main.rs:2669:26:2669:26 | 0 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2671:13:2671:13 | x | | {EXTERNAL LOCATION} | Result | -| main.rs:2671:13:2671:13 | x | E | {EXTERNAL LOCATION} | String | -| main.rs:2671:13:2671:13 | x | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2671:17:2671:29 | ...::Ok(...) | | {EXTERNAL LOCATION} | Result | -| main.rs:2671:17:2671:29 | ...::Ok(...) | E | {EXTERNAL LOCATION} | String | -| main.rs:2671:17:2671:29 | ...::Ok(...) | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2671:28:2671:28 | 0 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2672:13:2672:13 | x | | {EXTERNAL LOCATION} | Result | -| main.rs:2672:13:2672:13 | x | E | {EXTERNAL LOCATION} | String | -| main.rs:2672:13:2672:13 | x | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2672:38:2672:38 | x | | {EXTERNAL LOCATION} | Result | -| main.rs:2672:38:2672:38 | x | E | {EXTERNAL LOCATION} | String | -| main.rs:2672:38:2672:38 | x | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2673:13:2673:13 | x | | {EXTERNAL LOCATION} | Result | -| main.rs:2673:13:2673:13 | x | E | {EXTERNAL LOCATION} | String | -| main.rs:2673:13:2673:13 | x | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2673:17:2673:44 | ...::Ok(...) | | {EXTERNAL LOCATION} | Result | -| main.rs:2673:17:2673:44 | ...::Ok(...) | E | {EXTERNAL LOCATION} | String | -| main.rs:2673:17:2673:44 | ...::Ok(...) | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2673:43:2673:43 | 0 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2674:13:2674:13 | x | | {EXTERNAL LOCATION} | Result | -| main.rs:2674:13:2674:13 | x | E | {EXTERNAL LOCATION} | String | -| main.rs:2674:13:2674:13 | x | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2674:17:2674:44 | ...::Ok::<...>(...) | | {EXTERNAL LOCATION} | Result | -| main.rs:2674:17:2674:44 | ...::Ok::<...>(...) | E | {EXTERNAL LOCATION} | String | -| main.rs:2674:17:2674:44 | ...::Ok::<...>(...) | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2674:43:2674:43 | 0 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2676:29:2676:31 | res | | {EXTERNAL LOCATION} | Result | -| main.rs:2676:29:2676:31 | res | E | main.rs:2676:26:2676:26 | E | -| main.rs:2676:29:2676:31 | res | T | main.rs:2676:23:2676:23 | T | -| main.rs:2676:48:2676:48 | x | | main.rs:2676:26:2676:26 | E | -| main.rs:2676:54:2676:55 | { ... } | | {EXTERNAL LOCATION} | () | +| main.rs:2670:29:2670:29 | e | | main.rs:2657:9:2660:9 | MyEither | +| main.rs:2670:29:2670:29 | e | T1 | main.rs:2670:26:2670:26 | T | +| main.rs:2670:29:2670:29 | e | T2 | {EXTERNAL LOCATION} | String | +| main.rs:2670:53:2670:53 | x | | main.rs:2670:26:2670:26 | T | +| main.rs:2670:59:2670:60 | { ... } | | {EXTERNAL LOCATION} | () | +| main.rs:2673:13:2673:13 | x | | main.rs:2657:9:2660:9 | MyEither | +| main.rs:2673:13:2673:13 | x | T1 | {EXTERNAL LOCATION} | i32 | +| main.rs:2673:13:2673:13 | x | T2 | {EXTERNAL LOCATION} | String | +| main.rs:2673:17:2675:9 | ...::B {...} | | main.rs:2657:9:2660:9 | MyEither | +| main.rs:2673:17:2675:9 | ...::B {...} | T1 | {EXTERNAL LOCATION} | i32 | +| main.rs:2673:17:2675:9 | ...::B {...} | T2 | {EXTERNAL LOCATION} | String | +| main.rs:2674:20:2674:32 | ...::new(...) | | {EXTERNAL LOCATION} | String | +| main.rs:2676:9:2676:27 | pin_my_either(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2676:23:2676:23 | x | | main.rs:2657:9:2660:9 | MyEither | +| main.rs:2676:23:2676:23 | x | T1 | {EXTERNAL LOCATION} | i32 | +| main.rs:2676:23:2676:23 | x | T2 | {EXTERNAL LOCATION} | String | +| main.rs:2676:26:2676:26 | 0 | | {EXTERNAL LOCATION} | i32 | | main.rs:2678:13:2678:13 | x | | {EXTERNAL LOCATION} | Result | -| main.rs:2678:13:2678:13 | x | E | {EXTERNAL LOCATION} | bool | +| main.rs:2678:13:2678:13 | x | E | {EXTERNAL LOCATION} | String | | main.rs:2678:13:2678:13 | x | T | {EXTERNAL LOCATION} | i32 | | main.rs:2678:17:2678:29 | ...::Ok(...) | | {EXTERNAL LOCATION} | Result | -| main.rs:2678:17:2678:29 | ...::Ok(...) | E | {EXTERNAL LOCATION} | bool | +| main.rs:2678:17:2678:29 | ...::Ok(...) | E | {EXTERNAL LOCATION} | String | | main.rs:2678:17:2678:29 | ...::Ok(...) | T | {EXTERNAL LOCATION} | i32 | | main.rs:2678:28:2678:28 | 0 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2679:9:2679:28 | pin_result(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2679:20:2679:20 | x | | {EXTERNAL LOCATION} | Result | -| main.rs:2679:20:2679:20 | x | E | {EXTERNAL LOCATION} | bool | -| main.rs:2679:20:2679:20 | x | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2679:23:2679:27 | false | | {EXTERNAL LOCATION} | bool | -| main.rs:2681:17:2681:17 | x | | {EXTERNAL LOCATION} | Vec | -| main.rs:2681:17:2681:17 | x | A | {EXTERNAL LOCATION} | Global | -| main.rs:2681:17:2681:17 | x | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2681:21:2681:30 | ...::new(...) | | {EXTERNAL LOCATION} | Vec | -| main.rs:2681:21:2681:30 | ...::new(...) | A | {EXTERNAL LOCATION} | Global | -| main.rs:2681:21:2681:30 | ...::new(...) | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2682:9:2682:9 | x | | {EXTERNAL LOCATION} | Vec | -| main.rs:2682:9:2682:9 | x | A | {EXTERNAL LOCATION} | Global | -| main.rs:2682:9:2682:9 | x | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2682:9:2682:17 | x.push(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2682:16:2682:16 | 0 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2684:13:2684:13 | y | | {EXTERNAL LOCATION} | i32 | -| main.rs:2684:17:2684:34 | ...::default(...) | | {EXTERNAL LOCATION} | i32 | -| main.rs:2685:9:2685:9 | x | | {EXTERNAL LOCATION} | Vec | -| main.rs:2685:9:2685:9 | x | A | {EXTERNAL LOCATION} | Global | -| main.rs:2685:9:2685:9 | x | T | {EXTERNAL LOCATION} | i32 | -| main.rs:2685:9:2685:17 | x.push(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2685:16:2685:16 | y | | {EXTERNAL LOCATION} | i32 | -| main.rs:2692:14:2692:17 | SelfParam | | main.rs:2690:5:2698:5 | Self [trait MyTrait] | -| main.rs:2695:14:2695:18 | SelfParam | | {EXTERNAL LOCATION} | & | -| main.rs:2695:14:2695:18 | SelfParam | TRef | main.rs:2690:5:2698:5 | Self [trait MyTrait] | -| main.rs:2695:21:2695:25 | other | | {EXTERNAL LOCATION} | & | -| main.rs:2695:21:2695:25 | other | TRef | main.rs:2690:5:2698:5 | Self [trait MyTrait] | -| main.rs:2695:44:2697:9 | { ... } | | {EXTERNAL LOCATION} | & | -| main.rs:2695:44:2697:9 | { ... } | TRef | main.rs:2690:5:2698:5 | Self [trait MyTrait] | -| main.rs:2696:13:2696:16 | self | | {EXTERNAL LOCATION} | & | -| main.rs:2696:13:2696:16 | self | TRef | main.rs:2690:5:2698:5 | Self [trait MyTrait] | -| main.rs:2696:13:2696:20 | self.f() | | {EXTERNAL LOCATION} | & | -| main.rs:2696:13:2696:20 | self.f() | TRef | main.rs:2690:5:2698:5 | Self [trait MyTrait] | -| main.rs:2702:14:2702:17 | SelfParam | | {EXTERNAL LOCATION} | i32 | -| main.rs:2702:28:2704:9 | { ... } | | {EXTERNAL LOCATION} | i32 | -| main.rs:2703:13:2703:16 | self | | {EXTERNAL LOCATION} | i32 | -| main.rs:2709:14:2709:17 | SelfParam | | {EXTERNAL LOCATION} | usize | -| main.rs:2709:28:2711:9 | { ... } | | {EXTERNAL LOCATION} | usize | -| main.rs:2710:13:2710:16 | self | | {EXTERNAL LOCATION} | usize | -| main.rs:2716:14:2716:17 | SelfParam | | {EXTERNAL LOCATION} | & | -| main.rs:2716:14:2716:17 | SelfParam | TRef | main.rs:2714:10:2714:10 | T | -| main.rs:2716:28:2718:9 | { ... } | | {EXTERNAL LOCATION} | & | -| main.rs:2716:28:2718:9 | { ... } | TRef | main.rs:2714:10:2714:10 | T | -| main.rs:2717:13:2717:16 | self | | {EXTERNAL LOCATION} | & | -| main.rs:2717:13:2717:16 | self | TRef | main.rs:2714:10:2714:10 | T | -| main.rs:2721:25:2725:5 | { ... } | | {EXTERNAL LOCATION} | usize | -| main.rs:2722:17:2722:17 | x | | {EXTERNAL LOCATION} | i32 | -| main.rs:2722:17:2722:17 | x | | {EXTERNAL LOCATION} | usize | -| main.rs:2722:21:2722:21 | 0 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2722:21:2722:21 | 0 | | {EXTERNAL LOCATION} | usize | -| main.rs:2723:9:2723:9 | x | | {EXTERNAL LOCATION} | i32 | -| main.rs:2723:9:2723:9 | x | | {EXTERNAL LOCATION} | usize | -| main.rs:2723:9:2723:17 | ... = ... | | {EXTERNAL LOCATION} | () | -| main.rs:2723:13:2723:13 | x | | {EXTERNAL LOCATION} | i32 | -| main.rs:2723:13:2723:13 | x | | {EXTERNAL LOCATION} | usize | -| main.rs:2723:13:2723:17 | x.f() | | {EXTERNAL LOCATION} | i32 | -| main.rs:2723:13:2723:17 | x.f() | | {EXTERNAL LOCATION} | usize | -| main.rs:2724:9:2724:9 | x | | {EXTERNAL LOCATION} | i32 | -| main.rs:2724:9:2724:9 | x | | {EXTERNAL LOCATION} | usize | -| main.rs:2727:12:2735:5 | { ... } | | {EXTERNAL LOCATION} | () | -| main.rs:2728:13:2728:13 | x | | {EXTERNAL LOCATION} | usize | -| main.rs:2728:24:2728:24 | 0 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2728:24:2728:24 | 0 | | {EXTERNAL LOCATION} | usize | -| main.rs:2729:13:2729:13 | y | | {EXTERNAL LOCATION} | & | -| main.rs:2729:13:2729:13 | y | TRef | {EXTERNAL LOCATION} | i32 | -| main.rs:2729:17:2729:18 | &1 | | {EXTERNAL LOCATION} | & | -| main.rs:2729:17:2729:18 | &1 | TRef | {EXTERNAL LOCATION} | i32 | -| main.rs:2729:18:2729:18 | 1 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2730:13:2730:13 | z | | {EXTERNAL LOCATION} | & | -| main.rs:2730:13:2730:13 | z | TRef | {EXTERNAL LOCATION} | usize | -| main.rs:2730:17:2730:17 | x | | {EXTERNAL LOCATION} | usize | -| main.rs:2730:17:2730:22 | x.g(...) | | {EXTERNAL LOCATION} | & | -| main.rs:2730:17:2730:22 | x.g(...) | TRef | {EXTERNAL LOCATION} | usize | -| main.rs:2730:21:2730:21 | y | | {EXTERNAL LOCATION} | & | -| main.rs:2730:21:2730:21 | y | TRef | {EXTERNAL LOCATION} | i32 | -| main.rs:2732:13:2732:13 | x | | {EXTERNAL LOCATION} | i32 | -| main.rs:2732:17:2732:17 | 0 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2733:13:2733:13 | y | | {EXTERNAL LOCATION} | usize | -| main.rs:2733:24:2733:24 | 1 | | {EXTERNAL LOCATION} | i32 | -| main.rs:2733:24:2733:24 | 1 | | {EXTERNAL LOCATION} | usize | -| main.rs:2734:13:2734:13 | z | | {EXTERNAL LOCATION} | i32 | -| main.rs:2734:17:2734:17 | x | | {EXTERNAL LOCATION} | i32 | -| main.rs:2734:17:2734:24 | x.max(...) | | {EXTERNAL LOCATION} | i32 | -| main.rs:2734:23:2734:23 | y | | {EXTERNAL LOCATION} | usize | -| main.rs:2744:11:2779:1 | { ... } | | {EXTERNAL LOCATION} | () | -| main.rs:2745:5:2745:21 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2746:5:2746:20 | ...::f(...) | | main.rs:72:5:72:21 | Foo | -| main.rs:2747:5:2747:60 | ...::g(...) | | main.rs:72:5:72:21 | Foo | -| main.rs:2747:20:2747:38 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | -| main.rs:2747:41:2747:59 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | -| main.rs:2748:5:2748:35 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2749:5:2749:41 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2750:5:2750:45 | ...::test(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2751:5:2751:30 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2752:5:2752:21 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2753:5:2753:27 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2754:5:2754:32 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2755:5:2755:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2756:5:2756:36 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2757:5:2757:35 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2758:5:2758:29 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2759:5:2759:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2760:5:2760:24 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2761:5:2761:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2762:5:2762:18 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2763:5:2763:15 | ...::f(...) | | {EXTERNAL LOCATION} | dyn Future | -| main.rs:2763:5:2763:15 | ...::f(...) | dyn(Output) | {EXTERNAL LOCATION} | () | -| main.rs:2764:5:2764:19 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2765:5:2765:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2766:5:2766:14 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2767:5:2767:27 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2768:5:2768:15 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2769:5:2769:43 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2770:5:2770:15 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2771:5:2771:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2772:5:2772:28 | ...::test(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2773:5:2773:23 | ...::test(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2774:5:2774:41 | ...::test_all_patterns(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2775:5:2775:49 | ...::box_patterns(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2776:5:2776:20 | ...::test(...) | | {EXTERNAL LOCATION} | () | -| main.rs:2777:5:2777:20 | ...::f(...) | | {EXTERNAL LOCATION} | Box | -| main.rs:2777:5:2777:20 | ...::f(...) | A | {EXTERNAL LOCATION} | Global | -| main.rs:2777:5:2777:20 | ...::f(...) | T | main.rs:2547:5:2549:5 | dyn MyTrait | -| main.rs:2777:5:2777:20 | ...::f(...) | T.dyn(T) | {EXTERNAL LOCATION} | i32 | -| main.rs:2777:16:2777:19 | true | | {EXTERNAL LOCATION} | bool | -| main.rs:2778:5:2778:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2679:13:2679:13 | x | | {EXTERNAL LOCATION} | Result | +| main.rs:2679:13:2679:13 | x | E | {EXTERNAL LOCATION} | String | +| main.rs:2679:13:2679:13 | x | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2679:38:2679:38 | x | | {EXTERNAL LOCATION} | Result | +| main.rs:2679:38:2679:38 | x | E | {EXTERNAL LOCATION} | String | +| main.rs:2679:38:2679:38 | x | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2680:13:2680:13 | x | | {EXTERNAL LOCATION} | Result | +| main.rs:2680:13:2680:13 | x | E | {EXTERNAL LOCATION} | String | +| main.rs:2680:13:2680:13 | x | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2680:17:2680:44 | ...::Ok(...) | | {EXTERNAL LOCATION} | Result | +| main.rs:2680:17:2680:44 | ...::Ok(...) | E | {EXTERNAL LOCATION} | String | +| main.rs:2680:17:2680:44 | ...::Ok(...) | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2680:43:2680:43 | 0 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2681:13:2681:13 | x | | {EXTERNAL LOCATION} | Result | +| main.rs:2681:13:2681:13 | x | E | {EXTERNAL LOCATION} | String | +| main.rs:2681:13:2681:13 | x | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2681:17:2681:44 | ...::Ok::<...>(...) | | {EXTERNAL LOCATION} | Result | +| main.rs:2681:17:2681:44 | ...::Ok::<...>(...) | E | {EXTERNAL LOCATION} | String | +| main.rs:2681:17:2681:44 | ...::Ok::<...>(...) | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2681:43:2681:43 | 0 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2683:29:2683:31 | res | | {EXTERNAL LOCATION} | Result | +| main.rs:2683:29:2683:31 | res | E | main.rs:2683:26:2683:26 | E | +| main.rs:2683:29:2683:31 | res | T | main.rs:2683:23:2683:23 | T | +| main.rs:2683:48:2683:48 | x | | main.rs:2683:26:2683:26 | E | +| main.rs:2683:54:2683:55 | { ... } | | {EXTERNAL LOCATION} | () | +| main.rs:2685:13:2685:13 | x | | {EXTERNAL LOCATION} | Result | +| main.rs:2685:13:2685:13 | x | E | {EXTERNAL LOCATION} | bool | +| main.rs:2685:13:2685:13 | x | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2685:17:2685:29 | ...::Ok(...) | | {EXTERNAL LOCATION} | Result | +| main.rs:2685:17:2685:29 | ...::Ok(...) | E | {EXTERNAL LOCATION} | bool | +| main.rs:2685:17:2685:29 | ...::Ok(...) | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2685:28:2685:28 | 0 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2686:9:2686:28 | pin_result(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2686:20:2686:20 | x | | {EXTERNAL LOCATION} | Result | +| main.rs:2686:20:2686:20 | x | E | {EXTERNAL LOCATION} | bool | +| main.rs:2686:20:2686:20 | x | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2686:23:2686:27 | false | | {EXTERNAL LOCATION} | bool | +| main.rs:2688:17:2688:17 | x | | {EXTERNAL LOCATION} | Vec | +| main.rs:2688:17:2688:17 | x | A | {EXTERNAL LOCATION} | Global | +| main.rs:2688:17:2688:17 | x | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2688:21:2688:30 | ...::new(...) | | {EXTERNAL LOCATION} | Vec | +| main.rs:2688:21:2688:30 | ...::new(...) | A | {EXTERNAL LOCATION} | Global | +| main.rs:2688:21:2688:30 | ...::new(...) | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2689:9:2689:9 | x | | {EXTERNAL LOCATION} | Vec | +| main.rs:2689:9:2689:9 | x | A | {EXTERNAL LOCATION} | Global | +| main.rs:2689:9:2689:9 | x | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2689:9:2689:17 | x.push(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2689:16:2689:16 | 0 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2691:13:2691:13 | y | | {EXTERNAL LOCATION} | i32 | +| main.rs:2691:17:2691:34 | ...::default(...) | | {EXTERNAL LOCATION} | i32 | +| main.rs:2692:9:2692:9 | x | | {EXTERNAL LOCATION} | Vec | +| main.rs:2692:9:2692:9 | x | A | {EXTERNAL LOCATION} | Global | +| main.rs:2692:9:2692:9 | x | T | {EXTERNAL LOCATION} | i32 | +| main.rs:2692:9:2692:17 | x.push(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2692:16:2692:16 | y | | {EXTERNAL LOCATION} | i32 | +| main.rs:2694:13:2694:13 | s | | main.rs:2639:5:2640:13 | S | +| main.rs:2694:17:2694:34 | ...::default(...) | | main.rs:2639:5:2640:13 | S | +| main.rs:2695:9:2695:15 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2695:14:2695:14 | s | | main.rs:2639:5:2640:13 | S | +| main.rs:2702:14:2702:17 | SelfParam | | main.rs:2700:5:2708:5 | Self [trait MyTrait] | +| main.rs:2705:14:2705:18 | SelfParam | | {EXTERNAL LOCATION} | & | +| main.rs:2705:14:2705:18 | SelfParam | TRef | main.rs:2700:5:2708:5 | Self [trait MyTrait] | +| main.rs:2705:21:2705:25 | other | | {EXTERNAL LOCATION} | & | +| main.rs:2705:21:2705:25 | other | TRef | main.rs:2700:5:2708:5 | Self [trait MyTrait] | +| main.rs:2705:44:2707:9 | { ... } | | {EXTERNAL LOCATION} | & | +| main.rs:2705:44:2707:9 | { ... } | TRef | main.rs:2700:5:2708:5 | Self [trait MyTrait] | +| main.rs:2706:13:2706:16 | self | | {EXTERNAL LOCATION} | & | +| main.rs:2706:13:2706:16 | self | TRef | main.rs:2700:5:2708:5 | Self [trait MyTrait] | +| main.rs:2706:13:2706:20 | self.f() | | {EXTERNAL LOCATION} | & | +| main.rs:2706:13:2706:20 | self.f() | TRef | main.rs:2700:5:2708:5 | Self [trait MyTrait] | +| main.rs:2712:14:2712:17 | SelfParam | | {EXTERNAL LOCATION} | i32 | +| main.rs:2712:28:2714:9 | { ... } | | {EXTERNAL LOCATION} | i32 | +| main.rs:2713:13:2713:16 | self | | {EXTERNAL LOCATION} | i32 | +| main.rs:2719:14:2719:17 | SelfParam | | {EXTERNAL LOCATION} | usize | +| main.rs:2719:28:2721:9 | { ... } | | {EXTERNAL LOCATION} | usize | +| main.rs:2720:13:2720:16 | self | | {EXTERNAL LOCATION} | usize | +| main.rs:2726:14:2726:17 | SelfParam | | {EXTERNAL LOCATION} | & | +| main.rs:2726:14:2726:17 | SelfParam | TRef | main.rs:2724:10:2724:10 | T | +| main.rs:2726:28:2728:9 | { ... } | | {EXTERNAL LOCATION} | & | +| main.rs:2726:28:2728:9 | { ... } | TRef | main.rs:2724:10:2724:10 | T | +| main.rs:2727:13:2727:16 | self | | {EXTERNAL LOCATION} | & | +| main.rs:2727:13:2727:16 | self | TRef | main.rs:2724:10:2724:10 | T | +| main.rs:2731:25:2735:5 | { ... } | | {EXTERNAL LOCATION} | usize | +| main.rs:2732:17:2732:17 | x | | {EXTERNAL LOCATION} | i32 | +| main.rs:2732:17:2732:17 | x | | {EXTERNAL LOCATION} | usize | +| main.rs:2732:21:2732:21 | 0 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2732:21:2732:21 | 0 | | {EXTERNAL LOCATION} | usize | +| main.rs:2733:9:2733:9 | x | | {EXTERNAL LOCATION} | i32 | +| main.rs:2733:9:2733:9 | x | | {EXTERNAL LOCATION} | usize | +| main.rs:2733:9:2733:17 | ... = ... | | {EXTERNAL LOCATION} | () | +| main.rs:2733:13:2733:13 | x | | {EXTERNAL LOCATION} | i32 | +| main.rs:2733:13:2733:13 | x | | {EXTERNAL LOCATION} | usize | +| main.rs:2733:13:2733:17 | x.f() | | {EXTERNAL LOCATION} | i32 | +| main.rs:2733:13:2733:17 | x.f() | | {EXTERNAL LOCATION} | usize | +| main.rs:2734:9:2734:9 | x | | {EXTERNAL LOCATION} | i32 | +| main.rs:2734:9:2734:9 | x | | {EXTERNAL LOCATION} | usize | +| main.rs:2737:12:2745:5 | { ... } | | {EXTERNAL LOCATION} | () | +| main.rs:2738:13:2738:13 | x | | {EXTERNAL LOCATION} | usize | +| main.rs:2738:24:2738:24 | 0 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2738:24:2738:24 | 0 | | {EXTERNAL LOCATION} | usize | +| main.rs:2739:13:2739:13 | y | | {EXTERNAL LOCATION} | & | +| main.rs:2739:13:2739:13 | y | TRef | {EXTERNAL LOCATION} | i32 | +| main.rs:2739:17:2739:18 | &1 | | {EXTERNAL LOCATION} | & | +| main.rs:2739:17:2739:18 | &1 | TRef | {EXTERNAL LOCATION} | i32 | +| main.rs:2739:18:2739:18 | 1 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2740:13:2740:13 | z | | {EXTERNAL LOCATION} | & | +| main.rs:2740:13:2740:13 | z | TRef | {EXTERNAL LOCATION} | usize | +| main.rs:2740:17:2740:17 | x | | {EXTERNAL LOCATION} | usize | +| main.rs:2740:17:2740:22 | x.g(...) | | {EXTERNAL LOCATION} | & | +| main.rs:2740:17:2740:22 | x.g(...) | TRef | {EXTERNAL LOCATION} | usize | +| main.rs:2740:21:2740:21 | y | | {EXTERNAL LOCATION} | & | +| main.rs:2740:21:2740:21 | y | TRef | {EXTERNAL LOCATION} | i32 | +| main.rs:2742:13:2742:13 | x | | {EXTERNAL LOCATION} | i32 | +| main.rs:2742:17:2742:17 | 0 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2743:13:2743:13 | y | | {EXTERNAL LOCATION} | usize | +| main.rs:2743:24:2743:24 | 1 | | {EXTERNAL LOCATION} | i32 | +| main.rs:2743:24:2743:24 | 1 | | {EXTERNAL LOCATION} | usize | +| main.rs:2744:13:2744:13 | z | | {EXTERNAL LOCATION} | i32 | +| main.rs:2744:17:2744:17 | x | | {EXTERNAL LOCATION} | i32 | +| main.rs:2744:17:2744:24 | x.max(...) | | {EXTERNAL LOCATION} | i32 | +| main.rs:2744:23:2744:23 | y | | {EXTERNAL LOCATION} | usize | +| main.rs:2755:11:2790:1 | { ... } | | {EXTERNAL LOCATION} | () | +| main.rs:2756:5:2756:21 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2757:5:2757:20 | ...::f(...) | | main.rs:72:5:72:21 | Foo | +| main.rs:2758:5:2758:60 | ...::g(...) | | main.rs:72:5:72:21 | Foo | +| main.rs:2758:20:2758:38 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | +| main.rs:2758:41:2758:59 | ...::Foo {...} | | main.rs:72:5:72:21 | Foo | +| main.rs:2759:5:2759:35 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2760:5:2760:41 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2761:5:2761:45 | ...::test(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2762:5:2762:30 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2763:5:2763:21 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2764:5:2764:27 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2765:5:2765:32 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2766:5:2766:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2767:5:2767:36 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2768:5:2768:35 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2769:5:2769:29 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2770:5:2770:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2771:5:2771:24 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2772:5:2772:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2773:5:2773:18 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2774:5:2774:15 | ...::f(...) | | {EXTERNAL LOCATION} | dyn Future | +| main.rs:2774:5:2774:15 | ...::f(...) | dyn(Output) | {EXTERNAL LOCATION} | () | +| main.rs:2775:5:2775:19 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2776:5:2776:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2777:5:2777:14 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2778:5:2778:27 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2779:5:2779:15 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2780:5:2780:43 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2781:5:2781:15 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2782:5:2782:17 | ...::f(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2783:5:2783:28 | ...::test(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2784:5:2784:23 | ...::test(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2785:5:2785:41 | ...::test_all_patterns(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2786:5:2786:49 | ...::box_patterns(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2787:5:2787:20 | ...::test(...) | | {EXTERNAL LOCATION} | () | +| main.rs:2788:5:2788:20 | ...::f(...) | | {EXTERNAL LOCATION} | Box | +| main.rs:2788:5:2788:20 | ...::f(...) | A | {EXTERNAL LOCATION} | Global | +| main.rs:2788:5:2788:20 | ...::f(...) | T | main.rs:2547:5:2549:5 | dyn MyTrait | +| main.rs:2788:5:2788:20 | ...::f(...) | T.dyn(T) | {EXTERNAL LOCATION} | i32 | +| main.rs:2788:16:2788:19 | true | | {EXTERNAL LOCATION} | bool | +| main.rs:2789:5:2789:23 | ...::f(...) | | {EXTERNAL LOCATION} | () | | overloading.rs:4:19:4:23 | SelfParam | | {EXTERNAL LOCATION} | & | | overloading.rs:4:19:4:23 | SelfParam | TRef | overloading.rs:2:5:11:5 | Self [trait FirstTrait] | | overloading.rs:4:34:6:9 | { ... } | | {EXTERNAL LOCATION} | bool | @@ -14468,7 +14527,9 @@ inferType | pattern_matching.rs:788:41:788:45 | tuple | T2 | {EXTERNAL LOCATION} | bool | | pattern_matching.rs:792:35:824:1 | { ... } | | {EXTERNAL LOCATION} | () | | pattern_matching.rs:794:9:794:14 | points | | {EXTERNAL LOCATION} | Vec | +| pattern_matching.rs:794:9:794:14 | points | A | {EXTERNAL LOCATION} | Global | | pattern_matching.rs:794:18:794:65 | MacroExpr | | {EXTERNAL LOCATION} | Vec | +| pattern_matching.rs:794:18:794:65 | MacroExpr | A | {EXTERNAL LOCATION} | Global | | pattern_matching.rs:794:23:794:42 | (...) | | pattern_matching.rs:135:1:140:1 | Point | | pattern_matching.rs:794:23:794:42 | Point {...} | | pattern_matching.rs:135:1:140:1 | Point | | pattern_matching.rs:794:34:794:34 | 1 | | {EXTERNAL LOCATION} | i32 | @@ -14482,6 +14543,7 @@ inferType | pattern_matching.rs:795:17:795:17 | x | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:795:20:795:20 | y | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:795:27:795:32 | points | | {EXTERNAL LOCATION} | Vec | +| pattern_matching.rs:795:27:795:32 | points | A | {EXTERNAL LOCATION} | Global | | pattern_matching.rs:795:34:799:5 | { ... } | | {EXTERNAL LOCATION} | () | | pattern_matching.rs:796:13:796:18 | loop_x | | {EXTERNAL LOCATION} | i32 | | pattern_matching.rs:796:22:796:22 | x | | {EXTERNAL LOCATION} | i32 | @@ -14681,4 +14743,101 @@ inferType | raw_pointer.rs:58:19:58:23 | false | | {EXTERNAL LOCATION} | bool | | raw_pointer.rs:59:5:59:30 | raw_type_from_deref(...) | | {EXTERNAL LOCATION} | () | | raw_pointer.rs:59:25:59:29 | false | | {EXTERNAL LOCATION} | bool | +| regressions.rs:10:17:10:17 | s | | regressions.rs:3:5:3:23 | S | +| regressions.rs:10:17:10:17 | s | T | regressions.rs:9:10:9:10 | T | +| regressions.rs:10:34:12:9 | { ... } | | {EXTERNAL LOCATION} | Option | +| regressions.rs:10:34:12:9 | { ... } | T | regressions.rs:9:10:9:10 | T | +| regressions.rs:11:13:11:21 | Some(...) | | {EXTERNAL LOCATION} | Option | +| regressions.rs:11:13:11:21 | Some(...) | T | regressions.rs:9:10:9:10 | T | +| regressions.rs:11:18:11:18 | s | | regressions.rs:3:5:3:23 | S | +| regressions.rs:11:18:11:18 | s | T | regressions.rs:9:10:9:10 | T | +| regressions.rs:11:18:11:20 | s.0 | | regressions.rs:9:10:9:10 | T | +| regressions.rs:15:21:33:5 | { ... } | | regressions.rs:5:5:7:5 | E | +| regressions.rs:16:17:16:21 | vec_e | | {EXTERNAL LOCATION} | Vec | +| regressions.rs:16:17:16:21 | vec_e | A | {EXTERNAL LOCATION} | Global | +| regressions.rs:16:17:16:21 | vec_e | T | regressions.rs:5:5:7:5 | E | +| regressions.rs:16:25:16:34 | ...::new(...) | | {EXTERNAL LOCATION} | Vec | +| regressions.rs:16:25:16:34 | ...::new(...) | A | {EXTERNAL LOCATION} | Global | +| regressions.rs:16:25:16:34 | ...::new(...) | T | regressions.rs:5:5:7:5 | E | +| regressions.rs:17:17:17:21 | opt_e | | {EXTERNAL LOCATION} | Option | +| regressions.rs:17:17:17:21 | opt_e | T | regressions.rs:5:5:7:5 | E | +| regressions.rs:17:25:17:28 | None | | {EXTERNAL LOCATION} | Option | +| regressions.rs:17:25:17:28 | None | T | regressions.rs:5:5:7:5 | E | +| regressions.rs:19:13:19:13 | e | | regressions.rs:5:5:7:5 | E | +| regressions.rs:19:17:19:40 | ...::V {...} | | regressions.rs:5:5:7:5 | E | +| regressions.rs:19:29:19:38 | ...::new(...) | | {EXTERNAL LOCATION} | Vec | +| regressions.rs:19:29:19:38 | ...::new(...) | A | {EXTERNAL LOCATION} | Global | +| regressions.rs:19:29:19:38 | ...::new(...) | T | regressions.rs:5:5:7:5 | E | +| regressions.rs:21:9:23:9 | if ... {...} | | {EXTERNAL LOCATION} | () | +| regressions.rs:21:16:21:22 | Some(...) | | {EXTERNAL LOCATION} | Option | +| regressions.rs:21:16:21:22 | Some(...) | T | regressions.rs:5:5:7:5 | E | +| regressions.rs:21:21:21:21 | e | | regressions.rs:5:5:7:5 | E | +| regressions.rs:21:26:21:30 | opt_e | | {EXTERNAL LOCATION} | Option | +| regressions.rs:21:26:21:30 | opt_e | T | regressions.rs:5:5:7:5 | E | +| regressions.rs:21:32:23:9 | { ... } | | {EXTERNAL LOCATION} | () | +| regressions.rs:22:13:22:17 | vec_e | | {EXTERNAL LOCATION} | Vec | +| regressions.rs:22:13:22:17 | vec_e | A | {EXTERNAL LOCATION} | Global | +| regressions.rs:22:13:22:17 | vec_e | T | regressions.rs:5:5:7:5 | E | +| regressions.rs:22:13:22:25 | vec_e.push(...) | | {EXTERNAL LOCATION} | () | +| regressions.rs:22:24:22:24 | e | | regressions.rs:5:5:7:5 | E | +| regressions.rs:24:9:24:13 | opt_e | | {EXTERNAL LOCATION} | Option | +| regressions.rs:24:9:24:13 | opt_e | T | regressions.rs:5:5:7:5 | E | +| regressions.rs:24:9:24:24 | ... = ... | | {EXTERNAL LOCATION} | () | +| regressions.rs:24:17:24:17 | e | | regressions.rs:5:5:7:5 | E | +| regressions.rs:24:17:24:24 | e.into() | | {EXTERNAL LOCATION} | Option | +| regressions.rs:24:17:24:24 | e.into() | T | regressions.rs:5:5:7:5 | E | +| regressions.rs:27:13:27:13 | _ | | {EXTERNAL LOCATION} | () | +| regressions.rs:27:17:30:9 | if ... {...} | | {EXTERNAL LOCATION} | () | +| regressions.rs:27:24:27:33 | Some(...) | | {EXTERNAL LOCATION} | Option | +| regressions.rs:27:24:27:33 | Some(...) | T | regressions.rs:5:5:7:5 | E | +| regressions.rs:27:29:27:32 | last | | regressions.rs:5:5:7:5 | E | +| regressions.rs:27:37:27:41 | vec_e | | {EXTERNAL LOCATION} | Vec | +| regressions.rs:27:37:27:41 | vec_e | A | {EXTERNAL LOCATION} | Global | +| regressions.rs:27:37:27:41 | vec_e | T | regressions.rs:5:5:7:5 | E | +| regressions.rs:27:37:27:47 | vec_e.pop() | | {EXTERNAL LOCATION} | Option | +| regressions.rs:27:37:27:47 | vec_e.pop() | T | regressions.rs:5:5:7:5 | E | +| regressions.rs:28:9:30:9 | { ... } | | {EXTERNAL LOCATION} | () | +| regressions.rs:29:13:29:17 | opt_e | | {EXTERNAL LOCATION} | Option | +| regressions.rs:29:13:29:17 | opt_e | T | regressions.rs:5:5:7:5 | E | +| regressions.rs:29:13:29:31 | ... = ... | | {EXTERNAL LOCATION} | () | +| regressions.rs:29:21:29:24 | last | | regressions.rs:5:5:7:5 | E | +| regressions.rs:29:21:29:31 | last.into() | | {EXTERNAL LOCATION} | Option | +| regressions.rs:29:21:29:31 | last.into() | T | regressions.rs:5:5:7:5 | E | +| regressions.rs:32:9:32:13 | opt_e | | {EXTERNAL LOCATION} | Option | +| regressions.rs:32:9:32:13 | opt_e | T | regressions.rs:5:5:7:5 | E | +| regressions.rs:32:9:32:22 | opt_e.unwrap() | | regressions.rs:5:5:7:5 | E | +| regressions.rs:40:20:40:24 | value | | regressions.rs:39:18:39:18 | T | +| regressions.rs:44:20:44:20 | s | | regressions.rs:43:10:43:10 | T | +| regressions.rs:44:34:46:9 | { ... } | | regressions.rs:43:10:43:10 | T | +| regressions.rs:45:13:45:13 | s | | regressions.rs:43:10:43:10 | T | +| regressions.rs:50:20:50:22 | val | | regressions.rs:49:10:49:10 | T | +| regressions.rs:50:41:52:9 | { ... } | | {EXTERNAL LOCATION} | Option | +| regressions.rs:50:41:52:9 | { ... } | T | regressions.rs:49:10:49:10 | T | +| regressions.rs:51:13:51:21 | Some(...) | | {EXTERNAL LOCATION} | Option | +| regressions.rs:51:13:51:21 | Some(...) | T | regressions.rs:49:10:49:10 | T | +| regressions.rs:51:18:51:20 | val | | regressions.rs:49:10:49:10 | T | +| regressions.rs:58:20:58:20 | s | | regressions.rs:55:5:55:23 | S | +| regressions.rs:58:20:58:20 | s | T | regressions.rs:57:10:57:10 | T | +| regressions.rs:58:37:60:9 | { ... } | | {EXTERNAL LOCATION} | Option | +| regressions.rs:58:37:60:9 | { ... } | T | regressions.rs:57:10:57:10 | T | +| regressions.rs:59:13:59:21 | Some(...) | | {EXTERNAL LOCATION} | Option | +| regressions.rs:59:13:59:21 | Some(...) | T | regressions.rs:57:10:57:10 | T | +| regressions.rs:59:18:59:18 | s | | regressions.rs:55:5:55:23 | S | +| regressions.rs:59:18:59:18 | s | T | regressions.rs:57:10:57:10 | T | +| regressions.rs:59:18:59:20 | s.0 | | regressions.rs:57:10:57:10 | T | +| regressions.rs:63:22:63:22 | x | | regressions.rs:63:18:63:19 | T2 | +| regressions.rs:67:5:71:5 | { ... } | | regressions.rs:63:18:63:19 | T2 | +| regressions.rs:68:13:68:13 | y | | {EXTERNAL LOCATION} | Option | +| regressions.rs:68:13:68:13 | y | T | regressions.rs:63:14:63:15 | T1 | +| regressions.rs:68:13:68:13 | y | T | regressions.rs:63:18:63:19 | T2 | +| regressions.rs:68:17:68:34 | ...::my_from(...) | | {EXTERNAL LOCATION} | Option | +| regressions.rs:68:17:68:34 | ...::my_from(...) | T | regressions.rs:63:14:63:15 | T1 | +| regressions.rs:68:17:68:34 | ...::my_from(...) | T | regressions.rs:63:18:63:19 | T2 | +| regressions.rs:68:33:68:33 | x | | regressions.rs:63:18:63:19 | T2 | +| regressions.rs:69:13:69:13 | z | | regressions.rs:63:18:63:19 | T2 | +| regressions.rs:69:17:69:34 | ...::my_from(...) | | regressions.rs:63:18:63:19 | T2 | +| regressions.rs:69:33:69:33 | y | | {EXTERNAL LOCATION} | Option | +| regressions.rs:69:33:69:33 | y | T | regressions.rs:63:14:63:15 | T1 | +| regressions.rs:69:33:69:33 | y | T | regressions.rs:63:18:63:19 | T2 | +| regressions.rs:70:9:70:9 | z | | regressions.rs:63:18:63:19 | T2 | testFailures diff --git a/rust/ql/test/query-tests/security/CWE-327/BrokenCryptoAlgorithm/BrokenCryptoAlgorithm.expected b/rust/ql/test/query-tests/security/CWE-327/BrokenCryptoAlgorithm/BrokenCryptoAlgorithm.expected index ef0a9e0d8063..a04fd96739cd 100644 --- a/rust/ql/test/query-tests/security/CWE-327/BrokenCryptoAlgorithm/BrokenCryptoAlgorithm.expected +++ b/rust/ql/test/query-tests/security/CWE-327/BrokenCryptoAlgorithm/BrokenCryptoAlgorithm.expected @@ -21,3 +21,9 @@ | test_cipher.rs:109:23:109:56 | ...::new_with_eff_key_len(...) | $@ is broken or weak, and should not be used. | test_cipher.rs:109:23:109:56 | ...::new_with_eff_key_len(...) | The cryptographic algorithm RC2 | | test_cipher.rs:114:23:114:50 | ...::new(...) | $@ is broken or weak, and should not be used. | test_cipher.rs:114:23:114:50 | ...::new(...) | The cryptographic algorithm RC5 | | test_cipher.rs:118:23:118:55 | ...::new_from_slice(...) | $@ is broken or weak, and should not be used. | test_cipher.rs:118:23:118:55 | ...::new_from_slice(...) | The cryptographic algorithm RC5 | +| test_cipher.rs:136:23:136:76 | ...::new(...) | $@ is broken or weak, and should not be used. | test_cipher.rs:136:23:136:76 | ...::new(...) | The cryptographic algorithm DES | +| test_cipher.rs:139:23:139:64 | ...::new(...) | $@ is broken or weak, and should not be used. | test_cipher.rs:139:23:139:64 | ...::new(...) | The cryptographic algorithm DES | +| test_cipher.rs:142:23:142:76 | ...::new_from_slices(...) | $@ is broken or weak, and should not be used. | test_cipher.rs:142:23:142:76 | ...::new_from_slices(...) | The cryptographic algorithm DES | +| test_cipher.rs:145:23:145:76 | ...::new(...) | $@ is broken or weak, and should not be used. | test_cipher.rs:145:23:145:76 | ...::new(...) | The cryptographic algorithm DES | +| test_cipher.rs:171:23:171:65 | ...::new(...) | $@ is broken or weak, and should not be used. | test_cipher.rs:171:23:171:65 | ...::new(...) | The cryptographic algorithm DES | +| test_cipher.rs:175:23:175:65 | ...::new(...) | $@ is broken or weak, and should not be used. | test_cipher.rs:175:23:175:65 | ...::new(...) | The cryptographic algorithm RC2 | diff --git a/rust/ql/test/query-tests/security/CWE-327/BrokenCryptoAlgorithm/CONSISTENCY/PathResolutionConsistency.expected b/rust/ql/test/query-tests/security/CWE-327/BrokenCryptoAlgorithm/CONSISTENCY/PathResolutionConsistency.expected deleted file mode 100644 index 18400b7ab59b..000000000000 --- a/rust/ql/test/query-tests/security/CWE-327/BrokenCryptoAlgorithm/CONSISTENCY/PathResolutionConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -multipleResolvedTargets -| test_cipher.rs:114:23:114:50 | ...::new(...) | diff --git a/rust/ql/test/query-tests/security/CWE-327/BrokenCryptoAlgorithm/test_cipher.rs b/rust/ql/test/query-tests/security/CWE-327/BrokenCryptoAlgorithm/test_cipher.rs index 17db0f9ceb19..81964436720d 100644 --- a/rust/ql/test/query-tests/security/CWE-327/BrokenCryptoAlgorithm/test_cipher.rs +++ b/rust/ql/test/query-tests/security/CWE-327/BrokenCryptoAlgorithm/test_cipher.rs @@ -133,16 +133,16 @@ fn test_cbc( _ = aes_cipher1.encrypt_padded_mut::(data, data_len).unwrap(); // des (broken) - let des_cipher1 = cbc::Encryptor::::new(key.into(), iv.into()); // $ MISSING: Alert[rust/weak-cryptographic-algorithm] + let des_cipher1 = cbc::Encryptor::::new(key.into(), iv.into()); // $ Alert[rust/weak-cryptographic-algorithm] _ = des_cipher1.encrypt_padded_mut::(data, data_len).unwrap(); - let des_cipher2 = MyDesEncryptor::new(key.into(), iv.into()); // $ MISSING: Alert[rust/weak-cryptographic-algorithm] + let des_cipher2 = MyDesEncryptor::new(key.into(), iv.into()); // $ Alert[rust/weak-cryptographic-algorithm] _ = des_cipher2.encrypt_padded_mut::(data, data_len).unwrap(); - let des_cipher3 = cbc::Encryptor::::new_from_slices(&key, &iv).unwrap(); // $ MISSING: Alert[rust/weak-cryptographic-algorithm] + let des_cipher3 = cbc::Encryptor::::new_from_slices(&key, &iv).unwrap(); // $ Alert[rust/weak-cryptographic-algorithm] _ = des_cipher3.encrypt_padded_mut::(data, data_len).unwrap(); - let des_cipher4 = cbc::Encryptor::::new(key.into(), iv.into()); // $ MISSING: Alert[rust/weak-cryptographic-algorithm] + let des_cipher4 = cbc::Encryptor::::new(key.into(), iv.into()); // $ Alert[rust/weak-cryptographic-algorithm] _ = des_cipher4.encrypt_padded_b2b_mut::(input, data).unwrap(); } @@ -168,10 +168,10 @@ fn test_ecb( _ = aes_cipher4.encrypt_padded_b2b_mut::(input, data).unwrap(); // des with ECB (broken cipher + weak block mode) - let des_cipher1 = ecb::Encryptor::::new(key.into()); // $ MISSING: Alert[rust/weak-cryptographic-algorithm] + let des_cipher1 = ecb::Encryptor::::new(key.into()); // $ Alert[rust/weak-cryptographic-algorithm] _ = des_cipher1.encrypt_padded_mut::(data, data_len).unwrap(); // rc2 with ECB (broken cipher + weak block mode) - let rc2_cipher1 = ecb::Encryptor::::new(key.into()); // $ MISSING: Alert[rust/weak-cryptographic-algorithm] + let rc2_cipher1 = ecb::Encryptor::::new(key.into()); // $ Alert[rust/weak-cryptographic-algorithm] _ = rc2_cipher1.encrypt_padded_mut::(data, data_len).unwrap(); } diff --git a/rust/ql/test/query-tests/security/CWE-825/AccessAfterLifetime.expected b/rust/ql/test/query-tests/security/CWE-825/AccessAfterLifetime.expected index 92e11e895cdc..40da53dca45b 100644 --- a/rust/ql/test/query-tests/security/CWE-825/AccessAfterLifetime.expected +++ b/rust/ql/test/query-tests/security/CWE-825/AccessAfterLifetime.expected @@ -155,6 +155,10 @@ edges | lifetime.rs:798:9:798:12 | &val | lifetime.rs:798:2:798:12 | return ... | provenance | | | lifetime.rs:802:6:802:8 | ptr | lifetime.rs:808:23:808:25 | ptr | provenance | | | lifetime.rs:802:12:802:24 | get_pointer(...) | lifetime.rs:802:6:802:8 | ptr | provenance | | +| lifetime.rs:841:13:841:27 | ...: ... | lifetime.rs:843:12:843:14 | ptr | provenance | | +| lifetime.rs:851:6:851:8 | ptr | lifetime.rs:853:20:853:22 | ptr | provenance | | +| lifetime.rs:851:12:851:23 | &local_value | lifetime.rs:851:6:851:8 | ptr | provenance | | +| lifetime.rs:853:20:853:22 | ptr | lifetime.rs:841:13:841:27 | ...: ... | provenance | | | main.rs:18:9:18:10 | p1 [&ref] | main.rs:21:19:21:20 | p1 | provenance | | | main.rs:18:9:18:10 | p1 [&ref] | main.rs:29:19:29:20 | p1 | provenance | | | main.rs:18:14:18:29 | ...::as_ptr(...) [&ref] | main.rs:18:9:18:10 | p1 [&ref] | provenance | | @@ -330,6 +334,11 @@ nodes | lifetime.rs:802:6:802:8 | ptr | semmle.label | ptr | | lifetime.rs:802:12:802:24 | get_pointer(...) | semmle.label | get_pointer(...) | | lifetime.rs:808:23:808:25 | ptr | semmle.label | ptr | +| lifetime.rs:841:13:841:27 | ...: ... | semmle.label | ...: ... | +| lifetime.rs:843:12:843:14 | ptr | semmle.label | ptr | +| lifetime.rs:851:6:851:8 | ptr | semmle.label | ptr | +| lifetime.rs:851:12:851:23 | &local_value | semmle.label | &local_value | +| lifetime.rs:853:20:853:22 | ptr | semmle.label | ptr | | main.rs:18:9:18:10 | p1 [&ref] | semmle.label | p1 [&ref] | | main.rs:18:14:18:29 | ...::as_ptr(...) [&ref] | semmle.label | ...::as_ptr(...) [&ref] | | main.rs:18:26:18:28 | &b1 | semmle.label | &b1 |