-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Java: Improve virtual dispatch via better unification check and deduplicate code with parameterised module #10097
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
Conversation
cc @ginsbach to check parameterised module usage. |
Looks good to me from a parameterised modules perspective. |
7e1dc89
to
cd88855
Compare
cd88855
to
92f2976
Compare
Finally managed to get a decent-looking dca run. |
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.
Some optional comments and factoring a duplicated line, otherwise LGTM
or | ||
failsUnification(t1.(Array).getComponentType(), t2.(Array).getComponentType()) | ||
or | ||
exists(RefType upperbound, RefType other | |
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.
exists(RefType upperbound, RefType other | | |
// Can't unify an `extends` bound against a concrete type that doesn't descend from that upper bound: | |
exists(RefType upperbound, RefType other | |
not other.getASourceSupertype*() = upperbound | ||
) | ||
or | ||
exists(RefType upperbound1, RefType upperbound2 | |
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.
exists(RefType upperbound1, RefType upperbound2 | | |
// Can't unify two `extends` bounds that don't intersect: | |
exists(RefType upperbound1, RefType upperbound2 | |
notHaveIntersection(upperbound1, upperbound2) | ||
) | ||
or | ||
exists(RefType lowerbound, RefType upperbound | |
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.
exists(RefType lowerbound, RefType upperbound | | |
// Can't unify `? super X` against `Y` or `? extends Y` where `Y` isn't an ancestor of `X`: | |
exists(RefType lowerbound, RefType upperbound | |
not lowerbound.getASourceSupertype*() = upperbound | ||
) | ||
or | ||
exists(BoundedType lowerbound, RefType upperbound | |
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.
exists(BoundedType lowerbound, RefType upperbound | | |
// Can't unify `? super T`, where `T` is a type variable `T extends S`, with a type that doesn't intersect with `S`: | |
exists(BoundedType lowerbound, RefType upperbound | |
not lowerbound instanceof BoundedType | ||
or | ||
t2.(Wildcard).getLowerBoundType().(RefType).getSourceDeclaration() = lowerbound and | ||
getUpperBound(t1).getSourceDeclaration() = upperbound and | ||
not lowerbound instanceof BoundedType | ||
| | ||
not lowerbound.getASourceSupertype*() = upperbound |
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.
not lowerbound instanceof BoundedType | |
or | |
t2.(Wildcard).getLowerBoundType().(RefType).getSourceDeclaration() = lowerbound and | |
getUpperBound(t1).getSourceDeclaration() = upperbound and | |
not lowerbound instanceof BoundedType | |
| | |
not lowerbound.getASourceSupertype*() = upperbound | |
or | |
t2.(Wildcard).getLowerBoundType().(RefType).getSourceDeclaration() = lowerbound and | |
getUpperBound(t1).getSourceDeclaration() = upperbound and | |
| | |
not lowerbound instanceof BoundedType | |
not lowerbound.getASourceSupertype*() = upperbound |
Fixed. |
The first commit is a pure refactor that changes all four copies of the unification code to instead use a single parameterised module.
The second commit improves the unification algorithm to account for the upper bounds of type variables and wildcards - until now the code assumed that all type variables and wildcards were merely
extends Object
and thus unifiable with anyRefType
.The third commit also accounts for wildcards with lower bounds.