-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix #9392: Allow overriding a Java method when a same-named field is present #9412
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
…d is present In scala#9126, Java fields were marked effectively finals to prevent false overrides. This poses a problem when a Java field and method of the same name are present, because a Scala val or def will match both of these according to Denotation#matches. We could tweak `matches` further to not consider the Java field to match any Scala definition, but that might introduce new problems (we couldn't trust `FullMatch` anymore and would need to check the info of any Java symbol which might cause cycles, we would also probably need to tweak overloading resolution to avoid ambiguity when trying to decide whether to select the Java field or the Scala override of the Java method). This commit takes a different approach: we allow a val or def to match a Java field, but we tweak the logic that checks whether the `override` modifier is correctly used to disallow definitions that _only_ match a Java field (thus preventing tests/neg/i9115 from compiling), while letting through definitions that both match a Java field and something else (thus making tests/pos/i9392 compile). This is all a bit messy but I can't think of a better solution which wouldn't be significantly more complicated.
Note that #9395 don't tweak Note2. When debugging compilation of
|
@ohze The problem with your PR (besides the code duplication it introduces) is that the
Yes, it's a bit weird, but as explained in the commit message, I can't think of a better approach that doesn't introduce other problems. |
My first reaction would be that |
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 am not sure about this. It seems wrong that a Java or Scala method is allowed to override a Java field. That's simply not the right semantics. So maybe it's better to tweak matches after all?
The issue is that when we have something like: package pkg;
public class J {
int i = 0;
public int i() { return 1; }
} class S2 extends pkg.J {
override def i: Int = 2
} We want |
I don't even know if we can do that in |
…d is present In scala#9126, Java fields were marked effectively finals to prevent false overrides. This poses a problem when a Java field and method of the same name are present, because a Scala val or def will match both of these according to Denotation#matches. This commit changes `matches` to prevent Java field from matching any Scala method, but we can't prevent them from matching Scala definitions with NotAMethod signature without introducing more complexity, so the following still doesn't compile unlike Scala 2: ```java package pkg; public class J { int i = 0; public int i() { return 1; } } ``` ```scala class S2 extends pkg.J { override def i: Int = 2 // error } ``` I have an alternative fix at scala#9412 which doesn't have this issue but is more hacky.
If we're OK with giving up on this requirement, I have an alternative fix which doesn't involve having OverridingPairs#matches and Denotation#matches do different things: #9452 |
…d is present In scala#9126, Java fields were marked effectively finals to prevent false overrides. This poses a problem when a Java field and method of the same name are present, because a Scala val or def will match both of these according to Denotation#matches. This commit changes `matches` to prevent Java field from matching any Scala method, but we can't prevent them from matching Scala definitions with NotAMethod signature without introducing more complexity, so the following still doesn't compile unlike Scala 2: ```java package pkg; public class J { int i = 0; public int i() { return 1; } } ``` ```scala class S2 extends pkg.J { override def i: Int = 2 // error } ``` I have an alternative fix at scala#9412 which doesn't have this issue but is more hacky.
Superceded by #9452 |
In #9126, Java fields were marked effectively finals to prevent false
overrides. This poses a problem when a Java field and method of the same
name are present, because a Scala val or def will match both of these
according to Denotation#matches. We could tweak
matches
further to notconsider the Java field to match any Scala definition, but that might
introduce new problems (we couldn't trust
FullMatch
anymore and wouldneed to check the info of any Java symbol which might cause cycles, we
would also probably need to tweak overloading resolution to avoid
ambiguity when trying to decide whether to select the Java field or the
Scala override of the Java method).
This commit takes a different approach: we allow a val or def to match a
Java field, but we tweak the logic that checks whether the
override
modifier is correctly used to disallow definitions that only match a
Java field (thus preventing tests/neg/i9115 from compiling), while
letting through definitions that both match a Java field and something
else (thus making tests/pos/i9392 compile).
This is all a bit messy but I can't think of a better solution which
wouldn't be significantly more complicated.