Fix #15199: Exclude JavaDefined Modules from bridge generation. #15499
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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)
.