-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Rust: Unify call resolution logic #21355
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
ca7017f
1b6f3a4
7094fb0
7a6ab70
ca2838b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,17 +6,17 @@ private import TypeMention | |
| private import TypeInference | ||
|
|
||
| private newtype TFunctionPosition = | ||
| TArgumentFunctionPosition(ArgumentPosition pos) or | ||
| TArgumentFunctionPosition(ArgumentPosition pos) { not pos.isSelf() } or | ||
| TReturnFunctionPosition() | ||
|
|
||
| /** | ||
| * A position of a type related to a function. | ||
| * A function-call adjusted position of a type related to a function. | ||
| * | ||
| * Either `self`, `return`, or a positional parameter index. | ||
| * Either `return` or a positional parameter index, where `self` is translated | ||
| * to position `0` and subsequent positional parameters at index `i` are | ||
| * translated to position `i + 1`. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This might be a good spot to also explain why we need this. That "erasing" the difference between positions in methods and non-methods lets us handle calls of the form |
||
| */ | ||
| class FunctionPosition extends TFunctionPosition { | ||
| predicate isSelf() { this.asArgumentPosition().isSelf() } | ||
|
|
||
| int asPosition() { result = this.asArgumentPosition().asPosition() } | ||
|
|
||
| predicate isPosition() { exists(this.asPosition()) } | ||
|
|
@@ -25,29 +25,18 @@ class FunctionPosition extends TFunctionPosition { | |
|
|
||
| predicate isTypeQualifier() { this.asArgumentPosition().isTypeQualifier() } | ||
|
|
||
| predicate isSelfOrTypeQualifier() { this.isSelf() or this.isTypeQualifier() } | ||
|
|
||
| predicate isReturn() { this = TReturnFunctionPosition() } | ||
|
|
||
| /** Gets the corresponding position when `f` is invoked via a function call. */ | ||
| bindingset[f] | ||
| FunctionPosition getFunctionCallAdjusted(Function f) { | ||
| this.isReturn() and | ||
| result = this | ||
| or | ||
| if f.hasSelfParam() | ||
| then | ||
| this.isSelf() and result.asPosition() = 0 | ||
| or | ||
| result.asPosition() = this.asPosition() + 1 | ||
| else result = this | ||
| } | ||
|
|
||
| TypeMention getTypeMention(Function f) { | ||
| this.isSelf() and | ||
| result = getSelfParamTypeMention(f.getSelfParam()) | ||
| or | ||
| result = f.getParam(this.asPosition()).getTypeRepr() | ||
| ( | ||
| if f instanceof Method | ||
| then | ||
| result = f.getParam(this.asPosition() - 1).getTypeRepr() | ||
| or | ||
| result = getSelfParamTypeMention(f.getSelfParam()) and | ||
| this.asPosition() = 0 | ||
| else result = f.getParam(this.asPosition()).getTypeRepr() | ||
| ) | ||
| or | ||
| this.isReturn() and | ||
| result = getReturnTypeMention(f) | ||
|
|
@@ -197,8 +186,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 | ||
| not f.hasSelfParam() and | ||
| pos.isTypeQualifier() and | ||
| result = [i.(Impl).getSelfTy().(AstNode), i.(Trait).getName()] | ||
| ) | ||
| } | ||
|
|
@@ -209,7 +197,7 @@ class AssocFunctionType extends MkAssocFunctionType { | |
| } | ||
|
|
||
| pragma[nomagic] | ||
| private Trait getALookupTrait(Type t) { | ||
| Trait getALookupTrait(Type t) { | ||
| result = t.(TypeParamTypeParameter).getTypeParam().(TypeParamItemNode).resolveABound() | ||
| or | ||
| result = t.(SelfTypeParameter).getTrait() | ||
|
|
@@ -310,10 +298,11 @@ signature module ArgsAreInstantiationsOfInputSig { | |
| * Holds if `f` inside `i` needs to have the type corresponding to type parameter | ||
| * `tp` checked. | ||
| * | ||
| * If `i` is an inherent implementation, `tp` is a type parameter of the type being | ||
| * implemented, otherwise `tp` is a type parameter of the trait (being implemented). | ||
| * `tp` is a type parameter of the trait being implemented by `f` or the trait to which | ||
| * `f` belongs. | ||
| * | ||
| * `pos` is one of the positions in `f` in which the relevant type occours. | ||
| * `pos` is one of the function-call adjusted positions in `f` in which the relevant | ||
| * type occurs. | ||
| */ | ||
| predicate toCheck(ImplOrTraitItemNode i, Function f, TypeParameter tp, FunctionPosition pos); | ||
|
|
||
|
|
@@ -360,7 +349,7 @@ module ArgsAreInstantiationsOf<ArgsAreInstantiationsOfInputSig Input> { | |
| private newtype TCallAndPos = | ||
| MkCallAndPos(Input::Call call, FunctionPosition pos) { exists(call.getArgType(pos, _)) } | ||
|
|
||
| /** A call tagged with a position. */ | ||
| /** A call tagged with a function-call adjusted position. */ | ||
| private class CallAndPos extends MkCallAndPos { | ||
| Input::Call call; | ||
| FunctionPosition pos; | ||
|
|
@@ -413,20 +402,21 @@ module ArgsAreInstantiationsOf<ArgsAreInstantiationsOfInputSig Input> { | |
|
|
||
| pragma[nomagic] | ||
| private predicate argIsInstantiationOf( | ||
| Input::Call call, FunctionPosition pos, ImplOrTraitItemNode i, Function f, int rnk | ||
| Input::Call call, ImplOrTraitItemNode i, Function f, int rnk | ||
| ) { | ||
| ArgIsInstantiationOfToIndex::argIsInstantiationOf(MkCallAndPos(call, pos), i, _) and | ||
| toCheckRanked(i, f, _, pos, rnk) | ||
| exists(FunctionPosition pos | | ||
| ArgIsInstantiationOfToIndex::argIsInstantiationOf(MkCallAndPos(call, pos), i, _) and | ||
| toCheckRanked(i, f, _, pos, rnk) | ||
| ) | ||
| } | ||
|
|
||
| pragma[nomagic] | ||
| private predicate argsAreInstantiationsOfToIndex( | ||
| Input::Call call, ImplOrTraitItemNode i, Function f, int rnk | ||
| ) { | ||
| exists(FunctionPosition pos | | ||
| argIsInstantiationOf(call, pos, i, f, rnk) and | ||
| call.hasTargetCand(i, f) | ||
| | | ||
| argIsInstantiationOf(call, i, f, rnk) and | ||
| call.hasTargetCand(i, f) and | ||
| ( | ||
| rnk = 0 | ||
| or | ||
| argsAreInstantiationsOfToIndex(call, i, f, rnk - 1) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When looking at this in isolation the
- 1makes sense, so it might be worth it to add a comment mentioning that we also use this for adjusted positions where we need an extra index.