From 545340337364664c5bdfdc92e8ca04214bd124c6 Mon Sep 17 00:00:00 2001 From: Hamza Remmal Date: Mon, 28 Jul 2025 12:21:30 +0100 Subject: [PATCH] Revert "Emit mixin forwarders as ordinary, non-bridge methods again" --- .gitmodules | 1 - .../scala-parallel-collections | 2 +- .../tools/backend/jvm/BCodeHelpers.scala | 18 +++------ .../tools/backend/jvm/BTypesFromSymbols.scala | 2 +- .../src/dotty/tools/dotc/core/Phases.scala | 4 -- .../dotty/tools/dotc/transform/Mixin.scala | 29 +------------- .../test/dotc/run-test-pickling.excludelist | 2 + ...Scala2LibraryBootstrappedMiMaFilters.scala | 40 +------------------ tests/pos/11484/A_2.java | 1 - tests/pos/11484/C_1.scala | 6 --- tests/pos/11512/A_2.java | 1 - tests/pos/11512/C_1.scala | 7 ---- .../ExtensionId_1.scala | 18 --------- .../JavaExtension_2.java | 8 ---- tests/run/i19270.scala | 17 -------- tests/run/mixin-bridge-methods.scala | 16 -------- tests/run/mixin-final-def-object-lucre.scala | 19 --------- tests/run/mixin-forwarder-overload/A.scala | 9 +++++ tests/run/mixin-forwarder-overload/Test.java | 9 +++++ tests/run/mixin-signatures.check | 14 +++---- tests/run/t11485.scala | 18 +++++++++ tests/run/t3452b-bcode/J_2.java | 6 --- tests/run/t3452b-bcode/S_1.scala | 17 -------- tests/run/t3452b-bcode/S_3.scala | 7 ---- tests/run/t3452d/A.scala | 2 +- tests/run/t3452d/Test.java | 4 +- tests/run/t3452g/A.scala | 4 +- tests/run/t3452g/Test.java | 15 +++---- tests/run/t3452h.scala | 17 ++------ tests/run/t7932.check | 4 +- tests/run/t8905/DoubleRDD.scala | 9 +++++ tests/run/t8905/Test.java | 22 ++++++++++ 32 files changed, 103 insertions(+), 245 deletions(-) delete mode 100644 tests/pos/11484/A_2.java delete mode 100644 tests/pos/11484/C_1.scala delete mode 100644 tests/pos/11512/A_2.java delete mode 100644 tests/pos/11512/C_1.scala delete mode 100644 tests/pos/mixin-generic-extended-by-java/ExtensionId_1.scala delete mode 100644 tests/pos/mixin-generic-extended-by-java/JavaExtension_2.java delete mode 100644 tests/run/i19270.scala delete mode 100644 tests/run/mixin-bridge-methods.scala delete mode 100644 tests/run/mixin-final-def-object-lucre.scala create mode 100644 tests/run/mixin-forwarder-overload/A.scala create mode 100644 tests/run/mixin-forwarder-overload/Test.java create mode 100644 tests/run/t11485.scala delete mode 100644 tests/run/t3452b-bcode/J_2.java delete mode 100644 tests/run/t3452b-bcode/S_1.scala delete mode 100644 tests/run/t3452b-bcode/S_3.scala create mode 100644 tests/run/t8905/DoubleRDD.scala create mode 100644 tests/run/t8905/Test.java diff --git a/.gitmodules b/.gitmodules index 411e17a9e5a9..8f87e992013a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -100,7 +100,6 @@ [submodule "community-build/community-projects/scala-parallel-collections"] path = community-build/community-projects/scala-parallel-collections url = https://github.com/dotty-staging/scala-parallel-collections.git - branch = serialisation-stability-fix [submodule "community-build/community-projects/scala-collection-compat"] path = community-build/community-projects/scala-collection-compat url = https://github.com/dotty-staging/scala-collection-compat.git diff --git a/community-build/community-projects/scala-parallel-collections b/community-build/community-projects/scala-parallel-collections index 8f8eadf31c6f..7d0e41ae4d09 160000 --- a/community-build/community-projects/scala-parallel-collections +++ b/community-build/community-projects/scala-parallel-collections @@ -1 +1 @@ -Subproject commit 8f8eadf31c6f7a5afc874b972d44d3df99e0fa60 +Subproject commit 7d0e41ae4d09e1ddf063651e377921ec493fc5bf diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index ab264fe4889d..f8866f40d9d4 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -31,7 +31,6 @@ import dotty.tools.dotc.core.Types.* import dotty.tools.dotc.core.TypeErasure import dotty.tools.dotc.transform.GenericSignatures import dotty.tools.dotc.transform.ElimErasedValueType -import dotty.tools.dotc.transform.Mixin import dotty.tools.io.AbstractFile import dotty.tools.dotc.report @@ -396,20 +395,12 @@ trait BCodeHelpers extends BCodeIdiomatic { */ def getGenericSignature(sym: Symbol, owner: Symbol): String = { atPhase(erasurePhase) { - def computeMemberTpe(): Type = + val memberTpe = if (sym.is(Method)) sym.denot.info else if sym.denot.validFor.phaseId > erasurePhase.id && sym.isField && sym.getter.exists then // Memoization field of getter entered after erasure, see run/i17069 for an example sym.getter.denot.info.resultType else owner.denot.thisType.memberInfo(sym) - - val memberTpe = if sym.is(MixedIn) then - mixinPhase.asInstanceOf[Mixin].mixinForwarderGenericInfos.get(sym) match - case Some(genericInfo) => genericInfo - case none => computeMemberTpe() - else - computeMemberTpe() - getGenericSignatureHelper(sym, owner, memberTpe).orNull } } @@ -500,7 +491,7 @@ trait BCodeHelpers extends BCodeIdiomatic { report.debuglog(s"Potentially conflicting names for forwarders: $conflictingNames") for (m0 <- sortedMembersBasedOnFlags(moduleClass.info, required = Method, excluded = ExcludedForwarder)) { - val m = if (m0.isOneOf(Bridge | MixedIn)) m0.nextOverriddenSymbol else m0 + val m = if (m0.is(Bridge)) m0.nextOverriddenSymbol else m0 if (m == NoSymbol) report.log(s"$m0 is a bridge method that overrides nothing, something went wrong in a previous phase.") else if (m.isType || m.is(Deferred) || (m.owner eq defn.ObjectClass) || m.isConstructor || m.name.is(ExpandedName)) @@ -516,7 +507,10 @@ trait BCodeHelpers extends BCodeIdiomatic { // we generate ACC_SYNTHETIC forwarders so Java compilers ignore them. val isSynthetic = m0.name.is(NameKinds.SyntheticSetterName) || - m0.is(Bridge) + // Only hide bridges generated at Erasure, mixin forwarders are also + // marked as bridge but shouldn't be hidden since they don't have a + // non-bridge overload. + m0.is(Bridge) && m0.initial.validFor.firstPhaseId == erasurePhase.next.id addForwarder(jclass, moduleClass, m, isSynthetic) } } diff --git a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala index 68c6add4ef13..817d0be54d26 100644 --- a/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala +++ b/compiler/src/dotty/tools/backend/jvm/BTypesFromSymbols.scala @@ -299,7 +299,7 @@ class BTypesFromSymbols[I <: DottyBackendInterface](val int: I, val frontendAcce // illegal combination of modifiers at the bytecode level so // suppress final if abstract if present. && !sym.isOneOf(AbstractOrTrait) - // Bridges can be final, but final bridges confuse some frameworks + // Mixin forwarders are bridges and can be final, but final bridges confuse some frameworks && !sym.is(Bridge), ACC_FINAL) .addFlagIf(sym.isStaticMember, ACC_STATIC) .addFlagIf(sym.is(Bridge), ACC_BRIDGE | ACC_SYNTHETIC) diff --git a/compiler/src/dotty/tools/dotc/core/Phases.scala b/compiler/src/dotty/tools/dotc/core/Phases.scala index b24dbf2e8d7d..ee9ee4006919 100644 --- a/compiler/src/dotty/tools/dotc/core/Phases.scala +++ b/compiler/src/dotty/tools/dotc/core/Phases.scala @@ -239,7 +239,6 @@ object Phases { private var myErasurePhase: Phase = uninitialized private var myElimErasedValueTypePhase: Phase = uninitialized private var myLambdaLiftPhase: Phase = uninitialized - private var myMixinPhase: Phase = uninitialized private var myCountOuterAccessesPhase: Phase = uninitialized private var myFlattenPhase: Phase = uninitialized private var myGenBCodePhase: Phase = uninitialized @@ -267,7 +266,6 @@ object Phases { final def gettersPhase: Phase = myGettersPhase final def erasurePhase: Phase = myErasurePhase final def elimErasedValueTypePhase: Phase = myElimErasedValueTypePhase - final def mixinPhase: Phase = myMixinPhase final def lambdaLiftPhase: Phase = myLambdaLiftPhase final def countOuterAccessesPhase = myCountOuterAccessesPhase final def flattenPhase: Phase = myFlattenPhase @@ -297,7 +295,6 @@ object Phases { myErasurePhase = phaseOfClass(classOf[Erasure]) myElimErasedValueTypePhase = phaseOfClass(classOf[ElimErasedValueType]) myPatmatPhase = phaseOfClass(classOf[PatternMatcher]) - myMixinPhase = phaseOfClass(classOf[Mixin]) myLambdaLiftPhase = phaseOfClass(classOf[LambdaLift]) myCountOuterAccessesPhase = phaseOfClass(classOf[CountOuterAccesses]) myFlattenPhase = phaseOfClass(classOf[Flatten]) @@ -553,7 +550,6 @@ object Phases { def gettersPhase(using Context): Phase = ctx.base.gettersPhase def erasurePhase(using Context): Phase = ctx.base.erasurePhase def elimErasedValueTypePhase(using Context): Phase = ctx.base.elimErasedValueTypePhase - def mixinPhase(using Context): Phase = ctx.base.mixinPhase def lambdaLiftPhase(using Context): Phase = ctx.base.lambdaLiftPhase def flattenPhase(using Context): Phase = ctx.base.flattenPhase def genBCodePhase(using Context): Phase = ctx.base.genBCodePhase diff --git a/compiler/src/dotty/tools/dotc/transform/Mixin.scala b/compiler/src/dotty/tools/dotc/transform/Mixin.scala index 34a43f0ceeb6..b3285f62c062 100644 --- a/compiler/src/dotty/tools/dotc/transform/Mixin.scala +++ b/compiler/src/dotty/tools/dotc/transform/Mixin.scala @@ -16,7 +16,6 @@ import StdNames.* import Names.* import NameKinds.* import NameOps.* -import Phases.erasurePhase import ast.Trees.* import dotty.tools.dotc.transform.sjs.JSSymUtils.isJSType @@ -116,15 +115,6 @@ object Mixin { class Mixin extends MiniPhase with SymTransformer { thisPhase => import ast.tpd.* - /** Infos before erasure of the generated mixin forwarders. - * - * These will be used to generate Java generic signatures of the mixin - * forwarders. Normally we use the types before erasure; we cannot do that - * for mixin forwarders since they are created after erasure, and therefore - * their type history does not have anything recorded for before erasure. - */ - val mixinForwarderGenericInfos = MutableSymbolMap[Type]() - override def phaseName: String = Mixin.name override def description: String = Mixin.description @@ -315,25 +305,8 @@ class Mixin extends MiniPhase with SymTransformer { thisPhase => for (meth <- mixin.info.decls.toList if needsMixinForwarder(meth)) yield { util.Stats.record("mixin forwarders") - transformFollowing(DefDef(mkMixinForwarderSym(meth.asTerm), forwarderRhsFn(meth))) - } - - def mkMixinForwarderSym(target: TermSymbol): TermSymbol = - val sym = mkForwarderSym(target, extraFlags = MixedIn) - val (infoBeforeErasure, isDifferentThanInfoNow) = atPhase(erasurePhase) { - val beforeErasure = cls.thisType.memberInfo(target) - (beforeErasure, !(beforeErasure =:= sym.info)) + transformFollowing(DefDef(mkForwarderSym(meth.asTerm, Bridge), forwarderRhsFn(meth))) } - if isDifferentThanInfoNow then - // The info before erasure would not have been the same as the info now. - // We want to store it for the backend to compute the generic Java signature. - // However, we must still avoid doing that if erasing that signature would - // not give the same erased type. If it doesn't, we'll just give a completely - // incorrect Java signature. (This could be improved by generating dedicated - // bridges, but we don't go that far; scalac doesn't either.) - if TypeErasure.transformInfo(target, infoBeforeErasure) =:= sym.info then - mixinForwarderGenericInfos(sym) = infoBeforeErasure - sym cpy.Template(impl)( constr = diff --git a/compiler/test/dotc/run-test-pickling.excludelist b/compiler/test/dotc/run-test-pickling.excludelist index 0122276739c0..3cc9bc5a4a9e 100644 --- a/compiler/test/dotc/run-test-pickling.excludelist +++ b/compiler/test/dotc/run-test-pickling.excludelist @@ -12,11 +12,13 @@ i9473.scala i13433.scala i13433b.scala macros-in-same-project1 +mixin-forwarder-overload t10889 t3452d t3452e t3452g t7374 +t8905 tuple-drop.scala tuple-ops.scala tuple-ops.scala diff --git a/project/Scala2LibraryBootstrappedMiMaFilters.scala b/project/Scala2LibraryBootstrappedMiMaFilters.scala index 1e401da16dc9..dd0a885731b2 100644 --- a/project/Scala2LibraryBootstrappedMiMaFilters.scala +++ b/project/Scala2LibraryBootstrappedMiMaFilters.scala @@ -193,45 +193,7 @@ object Scala2LibraryBootstrappedMiMaFilters { "scala.util.matching.Regex.Groups", "scala.util.matching.Regex.Match", "scala.util.package.chaining", "scala.util.Using.Manager", "scala.util.Using.Releasable", "scala.util.Using#Releasable.AutoCloseableIsReleasable", - ).map(ProblemFilters.exclude[MissingFieldProblem]) ++ Seq( - // DirectMissingMethodProblem by flags being changed from ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC to ACC_PUBLIC in mixin forwarders: - // * from java.util.Comparator: - Seq("reversed", "thenComparing", "thenComparingInt", "thenComparingLong", "thenComparingInt", "thenComparingDouble").flatMap { method => - Seq( - ProblemFilters.exclude[DirectMissingMethodProblem](s"scala.Enumeration#ValueOrdering.$method"), - ProblemFilters.exclude[DirectMissingMethodProblem](s"scala.concurrent.duration.Deadline#DeadlineIsOrdered.$method"), - ProblemFilters.exclude[DirectMissingMethodProblem](s"scala.concurrent.duration.Duration#DurationIsOrdered.$method"), - ProblemFilters.exclude[DirectMissingMethodProblem](s"scala.concurrent.duration.FiniteDuration#FiniteDurationIsOrdered.$method"), - ProblemFilters.exclude[DirectMissingMethodProblem](s"scala.math.Numeric#*.$method"), - ProblemFilters.exclude[DirectMissingMethodProblem](s"scala.math.Ordering#*.$method"), - ) - }, - // * from java.util.Spliterator: - Seq("getExactSizeIfKnown", "hasCharacteristics", "getComparator").flatMap { method => - Seq( - ProblemFilters.exclude[DirectMissingMethodProblem](s"scala.collection.DoubleStepper#DoubleStepperSpliterator.$method"), - ProblemFilters.exclude[DirectMissingMethodProblem](s"scala.collection.IntStepper#IntStepperSpliterator.$method"), - ProblemFilters.exclude[DirectMissingMethodProblem](s"scala.collection.LongStepper#LongStepperSpliterator.$method"), - ) - }, - // * from java.util.Enumeration: - Seq( - ProblemFilters.exclude[DirectMissingMethodProblem]("scala.collection.convert.JavaCollectionWrappers#IteratorWrapper.asIterator"), - ), - // * from java.lang.CharSequence: - Seq( - ProblemFilters.exclude[DirectMissingMethodProblem]("scala.Predef#ArrayCharSequence.isEmpty"), - ProblemFilters.exclude[DirectMissingMethodProblem]("scala.Predef#SeqCharSequence.isEmpty"), - ProblemFilters.exclude[DirectMissingMethodProblem]("scala.runtime.ArrayCharSequence.isEmpty") - ), - // FinalMethodProblem - seems to be a bug in MiMa, as neither new or old version do not have final modifier. - // What did change is that sizeHint, and requireBounds had `final` added, but that does not get reported. - Seq( - ProblemFilters.exclude[FinalMethodProblem]("scala.**.sizeHint$default$2"), - ProblemFilters.exclude[FinalMethodProblem]("scala.collection.mutable.ArrayDeque.requireBounds$default$2") - ) - ).flatten - + ).map(ProblemFilters.exclude[MissingFieldProblem]) } ) } diff --git a/tests/pos/11484/A_2.java b/tests/pos/11484/A_2.java deleted file mode 100644 index aa8ef2cf5a42..000000000000 --- a/tests/pos/11484/A_2.java +++ /dev/null @@ -1 +0,0 @@ -public class A_2 extends C { } diff --git a/tests/pos/11484/C_1.scala b/tests/pos/11484/C_1.scala deleted file mode 100644 index 48f5bd8174cf..000000000000 --- a/tests/pos/11484/C_1.scala +++ /dev/null @@ -1,6 +0,0 @@ -class B[A] -sealed trait T[A] { - def overloaded(that: List[T[A]]): T[A] = that.head - def overloaded(that: List[B[A]]): B[A] = that.head -} -abstract class C[A] extends T[A] diff --git a/tests/pos/11512/A_2.java b/tests/pos/11512/A_2.java deleted file mode 100644 index ed549568a5f4..000000000000 --- a/tests/pos/11512/A_2.java +++ /dev/null @@ -1 +0,0 @@ -public class A_2 extends C { } diff --git a/tests/pos/11512/C_1.scala b/tests/pos/11512/C_1.scala deleted file mode 100644 index 8e791e333a82..000000000000 --- a/tests/pos/11512/C_1.scala +++ /dev/null @@ -1,7 +0,0 @@ -trait T { this: U => - def m: Int -} -trait U { - def m: Int = ??? -} -abstract class C extends U with T diff --git a/tests/pos/mixin-generic-extended-by-java/ExtensionId_1.scala b/tests/pos/mixin-generic-extended-by-java/ExtensionId_1.scala deleted file mode 100644 index f54f39879ac4..000000000000 --- a/tests/pos/mixin-generic-extended-by-java/ExtensionId_1.scala +++ /dev/null @@ -1,18 +0,0 @@ -trait Extension - -class ClassicActorSystemProvider - -/** - * Identifies an Extension - * Lookup of Extensions is done by object identity, so the Id must be the same wherever it's used, - * otherwise you'll get the same extension loaded multiple times. - */ -trait ExtensionId[T <: Extension] { - - def get(system: ClassicActorSystemProvider): T = ??? -} - -/** - * Java API for ExtensionId - */ -abstract class AbstractExtensionId[T <: Extension] extends ExtensionId[T] diff --git a/tests/pos/mixin-generic-extended-by-java/JavaExtension_2.java b/tests/pos/mixin-generic-extended-by-java/JavaExtension_2.java deleted file mode 100644 index 1711379d039e..000000000000 --- a/tests/pos/mixin-generic-extended-by-java/JavaExtension_2.java +++ /dev/null @@ -1,8 +0,0 @@ - -public class JavaExtension_2 { - static class TestExtensionId extends AbstractExtensionId { - } - - static class TestExtension implements Extension { - } -} diff --git a/tests/run/i19270.scala b/tests/run/i19270.scala deleted file mode 100644 index 128e5c108f94..000000000000 --- a/tests/run/i19270.scala +++ /dev/null @@ -1,17 +0,0 @@ -// scalajs: --skip - -trait T { - def foo(x: Int): Int = x + 1 -} - -class C extends T - -object Test { - def main(args: Array[String]): Unit = { - println("i19270") - val m = classOf[C].getDeclaredMethod("foo", classOf[Int]) - assert(m.getDeclaringClass() == classOf[C], m.getDeclaringClass()) - assert(!m.isBridge(), "foo should not have the ACC_BRIDGE flag") - assert(!m.isSynthetic(), "foo should not have the ACC_SYNTHETIC flag") - } -} diff --git a/tests/run/mixin-bridge-methods.scala b/tests/run/mixin-bridge-methods.scala deleted file mode 100644 index b14cd0caf150..000000000000 --- a/tests/run/mixin-bridge-methods.scala +++ /dev/null @@ -1,16 +0,0 @@ -// scalajs: --skip - -trait Foo { - def getFoo() = "foo" -} - -class Sub extends Foo { - def getBar() = "bar" -} - -object Test { - def main(args: Array[String]): Unit = { - val ms = classOf[Sub].getDeclaredMethods - assert(ms forall (x => !x.isBridge), ms mkString " ") - } -} diff --git a/tests/run/mixin-final-def-object-lucre.scala b/tests/run/mixin-final-def-object-lucre.scala deleted file mode 100644 index 676efb46c977..000000000000 --- a/tests/run/mixin-final-def-object-lucre.scala +++ /dev/null @@ -1,19 +0,0 @@ -trait EventLike - -trait GrandParent: - def changed: EventLike - -trait HasChanged extends GrandParent: - override def changed: EventLike - -abstract class Parent extends GrandParent: - object changed extends EventLike - -class Child extends Parent with HasChanged - -object Test: - def main(args: Array[String]): Unit = - val child = Child() - println(child.changed) - println((child: HasChanged).changed) -end Test diff --git a/tests/run/mixin-forwarder-overload/A.scala b/tests/run/mixin-forwarder-overload/A.scala new file mode 100644 index 000000000000..9eb20ac21414 --- /dev/null +++ b/tests/run/mixin-forwarder-overload/A.scala @@ -0,0 +1,9 @@ +case class Foo(x: Int) + +trait A[X] { + def concat[Dummy](suffix: Int): Dummy = ??? +} + +class Bar extends A[Foo] { + def concat(suffix: Int): Foo = Foo(0) +} diff --git a/tests/run/mixin-forwarder-overload/Test.java b/tests/run/mixin-forwarder-overload/Test.java new file mode 100644 index 000000000000..7bbd8dc9c7cb --- /dev/null +++ b/tests/run/mixin-forwarder-overload/Test.java @@ -0,0 +1,9 @@ +// scalajs: --skip + +public class Test { + public static void main(String[] args) { + Bar bar = new Bar(); + Foo x = bar.concat(0); + System.out.println(x); + } +} diff --git a/tests/run/mixin-signatures.check b/tests/run/mixin-signatures.check index 77bff79ac8f1..98979ab8d99b 100644 --- a/tests/run/mixin-signatures.check +++ b/tests/run/mixin-signatures.check @@ -1,19 +1,19 @@ class Test$bar1$ { - public java.lang.String Test$bar1$.f(java.lang.Object) public java.lang.Object Test$bar1$.f(java.lang.Object) + public java.lang.String Test$bar1$.f(java.lang.Object) public java.lang.String Test$bar1$.g(java.lang.String) public java.lang.Object Test$bar1$.g(java.lang.Object) public java.lang.String Test$bar1$.g(java.lang.Object) - public java.lang.Object Test$bar1$.h(java.lang.Object) + public java.lang.Object Test$bar1$.h(java.lang.Object) } class Test$bar2$ { - public java.lang.Object Test$bar2$.f(java.lang.String) public java.lang.Object Test$bar2$.f(java.lang.Object) + public java.lang.Object Test$bar2$.f(java.lang.String) public java.lang.String Test$bar2$.g(java.lang.String) public java.lang.Object Test$bar2$.g(java.lang.Object) public java.lang.Object Test$bar2$.g(java.lang.String) - public java.lang.Object Test$bar2$.h(java.lang.Object) + public java.lang.Object Test$bar2$.h(java.lang.Object) } class Test$bar3$ { @@ -23,7 +23,7 @@ class Test$bar3$ { public java.lang.String Test$bar3$.g(java.lang.String) public java.lang.Object Test$bar3$.g(java.lang.Object) public java.lang.String Test$bar3$.g(java.lang.Object) - public java.lang.Object Foo3.h(java.lang.Object) + public java.lang.Object Foo3.h(java.lang.Object) } class Test$bar4$ { @@ -33,7 +33,7 @@ class Test$bar4$ { public java.lang.String Test$bar4$.g(java.lang.String) public java.lang.Object Test$bar4$.g(java.lang.Object) public java.lang.Object Test$bar4$.g(java.lang.String) - public java.lang.Object Foo4.h(java.lang.Object) + public java.lang.Object Foo4.h(java.lang.Object) } class Test$bar5$ { @@ -45,7 +45,7 @@ class Test$bar5$ { public java.lang.Object Test$bar5$.g(java.lang.Object) public java.lang.Object Test$bar5$.g(java.lang.String) public java.lang.String Test$bar5$.g(java.lang.Object) - public java.lang.Object Test$bar5$.h(java.lang.Object) + public java.lang.Object Test$bar5$.h(java.lang.Object) } interface Foo1 { diff --git a/tests/run/t11485.scala b/tests/run/t11485.scala new file mode 100644 index 000000000000..3e339577b4a8 --- /dev/null +++ b/tests/run/t11485.scala @@ -0,0 +1,18 @@ +// scalajs: --skip + +import java.lang.reflect.Modifier + +trait HaveFinalMethod { + final def finalMethod: String = "final" +} + +class Child extends HaveFinalMethod + +object Test { + def main(args: Array[String]): Unit = { + val meth = classOf[Child].getMethod("finalMethod") + assert(meth.isBridge) + val mods = meth.getModifiers + assert(!Modifier.isFinal(mods)) + } +} diff --git a/tests/run/t3452b-bcode/J_2.java b/tests/run/t3452b-bcode/J_2.java deleted file mode 100644 index 839f334508e7..000000000000 --- a/tests/run/t3452b-bcode/J_2.java +++ /dev/null @@ -1,6 +0,0 @@ -public class J_2 { - public static void j() { - StringSearch.search("test"); - StringSearch.searchC("test"); - } -} diff --git a/tests/run/t3452b-bcode/S_1.scala b/tests/run/t3452b-bcode/S_1.scala deleted file mode 100644 index a209f1203539..000000000000 --- a/tests/run/t3452b-bcode/S_1.scala +++ /dev/null @@ -1,17 +0,0 @@ -trait Search[M] { - def search(input: M): C[Int] = { - println("Search received: " + input) - null - } -} - -class SearchC[M] { - def searchC(input: M): C[Int] = { - println("SearchC received: " + input) - null - } -} - -object StringSearch extends SearchC[String] with Search[String] - -trait C[T] diff --git a/tests/run/t3452b-bcode/S_3.scala b/tests/run/t3452b-bcode/S_3.scala deleted file mode 100644 index 6373d39e9137..000000000000 --- a/tests/run/t3452b-bcode/S_3.scala +++ /dev/null @@ -1,7 +0,0 @@ -// scalajs: --skip - -object Test { - def main(args: Array[String]): Unit = { - J_2.j() - } -} diff --git a/tests/run/t3452d/A.scala b/tests/run/t3452d/A.scala index 67a2080d273b..fd88a98793ab 100644 --- a/tests/run/t3452d/A.scala +++ b/tests/run/t3452d/A.scala @@ -2,6 +2,6 @@ trait TraversableLike[A, Repr] { def tail: Repr = null.asInstanceOf[Repr] } -abstract class AbstractTrav[A] extends TraversableLike[A, Traversable[A]] +abstract class AbstractTrav[A] extends TraversableLike[A, Iterable[A]] class C[A] extends AbstractTrav[A] diff --git a/tests/run/t3452d/Test.java b/tests/run/t3452d/Test.java index 5760bc6460eb..9ee02ed092a8 100644 --- a/tests/run/t3452d/Test.java +++ b/tests/run/t3452d/Test.java @@ -3,8 +3,6 @@ public class Test { public static void main(String[] args) { C c = new C(); - // TODO add a bridge during mixin so we can expose - // sharper generic signature for `tail`. - /*Traversable*/ Object ls = c.tail(); + scala.collection.Iterable ls = c.tail(); } } diff --git a/tests/run/t3452g/A.scala b/tests/run/t3452g/A.scala index a3f74c1e1e4c..df151d5313b3 100644 --- a/tests/run/t3452g/A.scala +++ b/tests/run/t3452g/A.scala @@ -4,6 +4,8 @@ trait TraversableLike[A, Repr] { abstract class AbstractTrav[A] extends TraversableLike[A, AbstractTrav[A]] +class C1 extends AbstractTrav[String] + object O extends AbstractTrav[String] -class C[A] extends AbstractTrav[A] +class C2[A] extends AbstractTrav[A] diff --git a/tests/run/t3452g/Test.java b/tests/run/t3452g/Test.java index 8f4cf96e45c8..594abc898ffe 100644 --- a/tests/run/t3452g/Test.java +++ b/tests/run/t3452g/Test.java @@ -1,15 +1,12 @@ // scalajs: --skip public class Test { - public static void main(String[] args) { - // To get better types here, we would need to - // add bridge during mixin so we can expose - // a generic return type of Traversable, because the erasure - // of this (Traversable) differs from the erasure of the mixed - // method (erasure(Repr) = Object) + public static void main(String[] args) { + AbstractTrav lsSharp1 = new C1().tail(); - Object lsSharp = O.tail(); + // Object is the result type for the static forwarder (might be because of #11305) + Object lsSharp2 = O.tail(); - Object lsSharp2 = new C().tail(); - } + AbstractTrav lsSharp3 = new C2().tail(); + } } diff --git a/tests/run/t3452h.scala b/tests/run/t3452h.scala index 5ccc8aecc10e..6237d3ea641a 100644 --- a/tests/run/t3452h.scala +++ b/tests/run/t3452h.scala @@ -1,17 +1,8 @@ -class Mix extends Foo with Bar { f; } +class Mix___eFoo_I_wBar__f extends Foo_I_ with Bar__f { f; } trait T -abstract class Foo { - class I extends T - def f: I - f -} -trait Bar { - type I >: Null <: T - def f: I = null - f - def gobble: I = null -} +abstract class Foo_I_ { class I extends T ; def f: I ; f; } +trait Bar__f { type I>:Null<:T; def f: I = {null}; f; def gobble: I = {null}} object Test extends App { - new Mix + new Mix___eFoo_I_wBar__f } diff --git a/tests/run/t7932.check b/tests/run/t7932.check index b7e516d73a41..5ba7ec1a3216 100644 --- a/tests/run/t7932.check +++ b/tests/run/t7932.check @@ -1,5 +1,5 @@ -public Category C.category() -public Category C.category1() +public Category C.category() +public Category C.category1() public abstract Category M2.category3() public abstract Category M2.category2() public default Category M1.category() diff --git a/tests/run/t8905/DoubleRDD.scala b/tests/run/t8905/DoubleRDD.scala new file mode 100644 index 000000000000..65e993ffe02b --- /dev/null +++ b/tests/run/t8905/DoubleRDD.scala @@ -0,0 +1,9 @@ +import java.util.Comparator + +trait RDDLike[T] { + def max(comp: Comparator[T]): T = { + (1.0).asInstanceOf[T] + } +} + +class DoubleRDD extends RDDLike[java.lang.Double] { } diff --git a/tests/run/t8905/Test.java b/tests/run/t8905/Test.java new file mode 100644 index 000000000000..e327beb3c819 --- /dev/null +++ b/tests/run/t8905/Test.java @@ -0,0 +1,22 @@ +// scalajs: --skip + +import java.util.Comparator; + +public class Test { + private static class DoubleComparator implements Comparator { + public int compare(Double o1, Double o2) { + return o1.compareTo(o2); + } + } + + public static void main(String[] args) { + DoubleRDD rdd = new DoubleRDD(); + RDDLike rddLike = rdd; + + // This call works fine: + double rddLikeMax = rddLike.max(new DoubleComparator()); + // In Scala 2.10.4, this code compiles but this call fails at runtime: + // java.lang.NoSuchMethodError: DoubleRDD.max(Ljava/util/Comparator;)Ljava/lang/Double; + double rddMax = rdd.max(new DoubleComparator()); + } +}