diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index f1959b79705e..c05c4231dc24 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -1716,6 +1716,19 @@ object Types { else funType } + final def dropJavaMethod(using Context): Type = this match + case pt: PolyType => pt.derivedLambdaType(resType = pt.resType.dropJavaMethod) + + case mt: MethodType => + if mt.isJavaMethod then + MethodType.apply(mt.paramNames, mt.paramInfos, mt.resType.dropJavaMethod) + else + mt.derivedLambdaType(resType = mt.resType.dropJavaMethod) + + case _ => this + + end dropJavaMethod + /** The signature of this type. This is by default NotAMethod, * but is overridden for PolyTypes, MethodTypes, and TermRef types. * (the reason why we deviate from the "final-method-with-pattern-match-in-base-class" diff --git a/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala b/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala index 9db5d7dbf697..9bc7d999b834 100644 --- a/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala +++ b/compiler/src/dotty/tools/dotc/typer/ErrorReporting.scala @@ -111,15 +111,8 @@ object ErrorReporting { /** A subtype log explaining why `found` does not conform to `expected` */ def whyNoMatchStr(found: Type, expected: Type): String = { - def dropJavaMethod(tp: Type): Type = tp match { - case tp: PolyType => - tp.derivedLambdaType(resType = dropJavaMethod(tp.resultType)) - case tp: MethodType if tp.isJavaMethod => - MethodType(tp.paramNames, tp.paramInfos, dropJavaMethod(tp.resultType)) - case tp => tp - } - val found1 = dropJavaMethod(found) - val expected1 = dropJavaMethod(expected) + val found1 = found.dropJavaMethod + val expected1 = expected.dropJavaMethod if ((found1 eq found) != (expected eq expected1) && (found1 <:< expected1)) i""" |(Note that Scala's and Java's representation of this type differs)""" diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index c40800862a31..be16039b4dde 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -1024,7 +1024,7 @@ class Namer { typer: Typer => if sym.isStableMember && sym.isPublic && !refersToPrivate(path.tpe) then (StableRealizable, ExprType(path.tpe.select(sym))) else - (EmptyFlags, mbr.info.ensureMethodic) + (EmptyFlags, mbr.info.ensureMethodic.dropJavaMethod) var mbrFlags = Exported | Method | Final | maybeStable | sym.flags & RetainedExportFlags if sym.is(ExtensionMethod) then mbrFlags |= ExtensionMethod val forwarderName = checkNoConflict(alias, isPrivate = false, span) diff --git a/tests/run/i10884/JavaExporter_1.java b/tests/run/i10884/JavaExporter_1.java new file mode 100644 index 000000000000..8fa4c41ab3a5 --- /dev/null +++ b/tests/run/i10884/JavaExporter_1.java @@ -0,0 +1,7 @@ +import java.util.Arrays; + +public class JavaExporter_1 { + public static String varargExample(String... args) { + return Arrays.toString(args); + } +} diff --git a/tests/run/i10884/Test_2.scala b/tests/run/i10884/Test_2.scala new file mode 100644 index 000000000000..72e7fafa9674 --- /dev/null +++ b/tests/run/i10884/Test_2.scala @@ -0,0 +1,7 @@ +object Exporter: + export JavaExporter_1._ + +import Exporter._ + +@main def Test = + println(varargExample("a", "b", "c"))