@@ -45,16 +45,18 @@ class JavaPlatform extends Platform {
4545
4646 def rootLoader (root : TermSymbol )(using Context ): SymbolLoader = new SymbolLoaders .PackageLoader (root, classPath)
4747
48- private def samMethodHasCompatibleErasedSignature (cls : ClassSymbol )(using Context ): Boolean = atPhase(erasurePhase):
49- cls.typeRef.possibleSamMethods.toList match
50- case samDenot :: Nil =>
51- val samMethod = samDenot.symbol
52- val samErasedResult = TypeErasure .erasure(samMethod.info.resultType)
53- samMethod.allOverriddenSymbols.forall { overridden =>
54- val overriddenErasedResult = TypeErasure .erasure(overridden.info.resultType)
55- samErasedResult =:= overriddenErasedResult
56- }
57- case _ => false // No SAM method or multiple - handled elsewhere
48+ private def samMethodHasCompatibleBridge (cls : ClassSymbol )(using Context ): Boolean =
49+ cls.typeRef.possibleSamMethods match
50+ case Seq (samMeth) =>
51+ val samResultType = samMeth.info.resultType
52+ if samResultType.isRef(defn.UnitClass ) then
53+ // If the result type of the SAM method is Unit, but the result type of the overridden
54+ // methods is not Unit, the bridge will return Object, which is not compatible with Void
55+ // required by LambdaMetaFactory.
56+ // See issue #24573 for details.
57+ samMeth.symbol.allOverriddenSymbols.forall(_.info.resultType.isRef(defn.UnitClass ))
58+ else true
59+ case _ => false
5860
5961 /** Is the SAMType `cls` also a SAM under the rules of the JVM? */
6062 def isSam (cls : ClassSymbol )(using Context ): Boolean =
@@ -64,10 +66,8 @@ class JavaPlatform extends Platform {
6466 ! ExplicitOuter .needsOuterIfReferenced(cls) &&
6567 // Superaccessors already show up as abstract methods here, so no test necessary
6668 cls.typeRef.fields.isEmpty &&
67- // Check that SAM method's erased signature is compatible with all overridden methods
68- // For example, `void apply(Object)` is not compatible with `Object apply(Object)`
69- // even though both can have the same type signature `def apply(o: Object): Unit` before erasure.
70- samMethodHasCompatibleErasedSignature(cls)
69+ // Check if SAM method will have a compatible bridge for LambdaMetaFactory
70+ samMethodHasCompatibleBridge(cls)
7171
7272 /** We could get away with excluding BoxedBooleanClass for the
7373 * purpose of equality testing since it need not compare equal
0 commit comments