From 5c8188aeda2f325de2853771e8ba512aa8bfbfdc Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Fri, 4 Jun 2021 16:08:43 +0200 Subject: [PATCH] Fix generic signatures for static forwarders involving value classes --- .../tools/backend/jvm/BCodeHelpers.scala | 3 ++- .../dotc/transform/ElimErasedValueType.scala | 23 ++++++++++--------- tests/pos/i10347/A_1.scala | 3 +++ tests/pos/i10347/C_2.java | 2 ++ 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala index c9710f3bbb9d..2aa75e1bd934 100644 --- a/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala +++ b/compiler/src/dotty/tools/backend/jvm/BCodeHelpers.scala @@ -26,6 +26,7 @@ import dotty.tools.dotc.core.Types 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.io.AbstractFile import dotty.tools.dotc.report @@ -926,7 +927,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters { // (one that doesn't erase to the actual signature). See run/t3452b for a test case. val memberTpe = atPhase(erasurePhase) { moduleClass.denot.thisType.memberInfo(sym) } - val erasedMemberType = TypeErasure.transformInfo(sym, memberTpe) + val erasedMemberType = ElimErasedValueType.elimEVT(TypeErasure.transformInfo(sym, memberTpe)) if (erasedMemberType =:= sym.denot.info) getGenericSignatureHelper(sym, moduleClass, memberTpe).orNull else null diff --git a/compiler/src/dotty/tools/dotc/transform/ElimErasedValueType.scala b/compiler/src/dotty/tools/dotc/transform/ElimErasedValueType.scala index 6545d7653c6b..0e62d1357fa5 100644 --- a/compiler/src/dotty/tools/dotc/transform/ElimErasedValueType.scala +++ b/compiler/src/dotty/tools/dotc/transform/ElimErasedValueType.scala @@ -13,6 +13,17 @@ import NameKinds.SuperAccessorName object ElimErasedValueType { val name: String = "elimErasedValueType" + + def elimEVT(tp: Type)(using Context): Type = tp match { + case ErasedValueType(_, underlying) => + elimEVT(underlying) + case tp: MethodType => + val paramTypes = tp.paramInfos.mapConserve(elimEVT) + val retType = elimEVT(tp.resultType) + tp.derivedLambdaType(tp.paramNames, paramTypes, retType) + case _ => + tp + } } /** This phase erases ErasedValueType to their underlying type. @@ -25,6 +36,7 @@ object ElimErasedValueType { class ElimErasedValueType extends MiniPhase with InfoTransformer { thisPhase => import tpd._ + import ElimErasedValueType.elimEVT override def phaseName: String = ElimErasedValueType.name @@ -48,17 +60,6 @@ class ElimErasedValueType extends MiniPhase with InfoTransformer { thisPhase => elimEVT(tp) } - def elimEVT(tp: Type)(using Context): Type = tp match { - case ErasedValueType(_, underlying) => - elimEVT(underlying) - case tp: MethodType => - val paramTypes = tp.paramInfos.mapConserve(elimEVT) - val retType = elimEVT(tp.resultType) - tp.derivedLambdaType(tp.paramNames, paramTypes, retType) - case _ => - tp - } - def transformTypeOfTree(tree: Tree)(using Context): Tree = tree.withType(elimEVT(tree.tpe)) diff --git a/tests/pos/i10347/A_1.scala b/tests/pos/i10347/A_1.scala index dd7d42107655..e6a87f14edec 100644 --- a/tests/pos/i10347/A_1.scala +++ b/tests/pos/i10347/A_1.scala @@ -1,4 +1,7 @@ trait L[+T] { def head: T } +class K(val s: String) extends AnyVal object A { def foo: L[String] = ??? + def bar: L[K] = ??? + def baz(k: K): L[String] = ??? } diff --git a/tests/pos/i10347/C_2.java b/tests/pos/i10347/C_2.java index 0f861fca86b0..7525c5e7325d 100644 --- a/tests/pos/i10347/C_2.java +++ b/tests/pos/i10347/C_2.java @@ -1,3 +1,5 @@ public class C_2 { String hi = A.foo().head(); + String hy = A.bar().head(); + String hj = A.baz("").head(); }