-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Rust: Data flow through overloaded operators #19685
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?
Conversation
7947dbf
to
0953436
Compare
0953436
to
c8746ba
Compare
For instance the binary `&` is overloadable but the prefix `&` is not. Similarly, `*` has a different target depending on if it's prefix or infix.
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.
Overall LGTM; mostly a question about whether to use codegen for the new Call
class. PR also needs to be rebased to resolve merge conflict.
* | ||
* This class abstract over the different ways in which a function can be called in Rust. | ||
*/ | ||
abstract class Call extends ExprImpl::Expr { |
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.
I wonder if this class should instead be added via annotations.py
and suitable replace_bases
?
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.
It seems to me that it would make sense to try an merge Call
and CallExprBase
into one class. But that will require adapting a lot of places, so I think it makes sense to defer that to a follow up PR.
|
||
override Declaration getTarget() { | ||
result = inferMethodCallTarget(this) // mutual recursion; resolving method calls requires resolving types and vice versa | ||
result = CallExprImpl::getResolvedFunction(this) | ||
} | ||
} | ||
|
||
predicate accessDeclarationPositionMatch(AccessPosition apos, DeclarationPosition dpos) { | ||
apos.isSelf() and |
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.
The body of this predicate can now simply be apos = dpos
.
c8746ba
to
eea6f52
Compare
The exact same problem occurs in Ruby, hence the `multipleArgumentCallExclude` implementation is adapted from Ruby's.
4d73871
to
5bdf989
Compare
The slowdown seems to be fixed in the most recent DCA run. |
) { | ||
if apos.isSelf() | ||
if apos.isSelf() and a.receiverImplicitlyBorrowed() |
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.
I'm not too fond of having a
in adjustAccessType
, it should be sufficient to know the position and not the actual access. That would require changing TDeclarationPosition
and TAccessPosition
back to how they were, which I also prefer anyway (that makes positions a purely syntactic property).
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.
What are the downside of having a
in adjustAccessType
? Given that they're all in the bindingset
I thought it wouldn't make a difference?
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.
You are right that it doesn't matter performance-wise, I just prefer the the simpler interface, which forces type-adjustment to be a property of the position alone.
This PR adds data flow through (simple) overloaded operators.
It does this by:
Call
class that abstracts away the different ways in which a call can occur.Call
in type inference which chops down some LOCs.Call
in data flow which then causes overloaded operators to be handled as calls.Future work:
+=
and the deref operator). In the tests writing out the desugaring doesn't work either, which seem to indicate this is blocked on other missing features in data flow.Call
withCallExprBase
. That seems doable but also has larger ramifications.