-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Fix #15199: Exclude JavaDefined Modules from bridge generation. #15499
Fix #15199: Exclude JavaDefined Modules from bridge generation. #15499
Conversation
JavaDefined modules are imaginary symbols that dotc uses to refer to static methods of Java classes. They have no reification, and therefore it makes no sense for them to participate in bridge generation.
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.
LGTM
@sjrd Merging this PR failed in https://github.com/lampepfl/dotty/runs/7198532616?check_suite_focus=true [info] Test run dotty.tools.dotc.ScalaJSCompilationTests started Can you take a look? |
Ah yes of course: #15590 |
JavaDefined modules are imaginary symbols that dotc uses to refer to static methods of Java classes. They have no reification, and therefore it makes no sense for them to participate in bridge generation.
How I fixed it
First, I happen to know that bridges are generated in Erasure, so that's one thing to look at.
I looked at the JavaDoc of
javax.swing.plaf.metal.MetalTabbedPaneUI
to find out whatTabbedPaneLayout
. I discovered that it is an inner class, and that it shadows an inner class of the same name inbasic.BasicTabbedPaneUI
. Java inner classes should never have bridges, as they are types. But they also implicitly declare companion objects, which dotc uses to refer to static members.Apparently, dotc gets confused about those imaginary objects, and tries to create bridges for them. It shouldn't even consider them.
I reproduced the issue with my own Java-defined classes, to get rid of the dependency on the JDK Swing APIs, which is a beast.
I search for "Bridge" in
Erasure.scala
, which leads me to theclass Bridges
. I did not know that class, but it's not very big. A quick look atBridgesCursor
and its relationship toOverridingPairs.Cursor
(the latter is the thing that enumerates pairs of members where one overrides the other) tells me that I should exclude JavaDefined modules fromBridgesCursor
. Lucky me: there is adef exclude
in it, so I amend it to also excludesym.isAllOf(Module | JavaDefined)
.