From 07f346efac3e4187f6243f6348a944db41c05dc5 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 15 May 2015 15:25:38 +0200 Subject: [PATCH 1/3] Fix #569 - newRefArray newRefArray needs to be treated specially at and after erasure because it is the only source-defined method that's still polymoprhic. --- src/dotty/tools/dotc/transform/Erasure.scala | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/dotty/tools/dotc/transform/Erasure.scala b/src/dotty/tools/dotc/transform/Erasure.scala index 36d75b149c54..9c94d6ce0565 100644 --- a/src/dotty/tools/dotc/transform/Erasure.scala +++ b/src/dotty/tools/dotc/transform/Erasure.scala @@ -469,7 +469,11 @@ object Erasure extends TypeTestsCasts{ tpt = untpd.TypedSplice(TypeTree(sym.info).withPos(vdef.tpt.pos))), sym) override def typedDefDef(ddef: untpd.DefDef, sym: Symbol)(implicit ctx: Context) = { - val restpe = sym.info.resultType + val restpe = + if (sym == defn.newRefArrayMethod) defn.ObjectType + // newRefArray is the only source defined method that's polymorphic + // after erasure; needs to be treated specially + else sym.info.resultType val ddef1 = untpd.cpy.DefDef(ddef)( tparams = Nil, vparamss = (outer.paramDefs(sym) ::: ddef.vparamss.flatten) :: Nil, @@ -600,7 +604,7 @@ object Erasure extends TypeTestsCasts{ traverse(newStats, oldStats) } - + private final val NoBridgeFlags = Flags.Accessor | Flags.Deferred | Flags.Lazy /** Create a bridge DefDef which overrides a parent method. From d01a0c9fe994eaeec4a20f4d2486a1dc0d1081c3 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 15 May 2015 15:41:18 +0200 Subject: [PATCH 2/3] Better fix for $569 We now provide a ndew symbol for the `newRefArray` definition, which makes any further treatment after erasure unnecessary. --- src/dotty/tools/dotc/transform/Erasure.scala | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/dotty/tools/dotc/transform/Erasure.scala b/src/dotty/tools/dotc/transform/Erasure.scala index 9c94d6ce0565..7776117b6305 100644 --- a/src/dotty/tools/dotc/transform/Erasure.scala +++ b/src/dotty/tools/dotc/transform/Erasure.scala @@ -469,20 +469,26 @@ object Erasure extends TypeTestsCasts{ tpt = untpd.TypedSplice(TypeTree(sym.info).withPos(vdef.tpt.pos))), sym) override def typedDefDef(ddef: untpd.DefDef, sym: Symbol)(implicit ctx: Context) = { - val restpe = - if (sym == defn.newRefArrayMethod) defn.ObjectType - // newRefArray is the only source defined method that's polymorphic - // after erasure; needs to be treated specially - else sym.info.resultType + var effectiveSym = sym + if (sym == defn.newRefArrayMethod) { + // newRefArray is treated specially: It's new only method source-defined method + // that has a polymorphic type after erasure. But treating its (dummy) definition + // with a polymorphic type at and after erasure is an awkward special case. + // We therefore rewrite the method definition with a new Symbol of type + // (length: Int)Object + val MethodType(pnames, ptypes) = sym.info.resultType + effectiveSym = sym.copy(info = MethodType(pnames, ptypes, defn.ObjectType)) + } + val restpe = effectiveSym.info.resultType val ddef1 = untpd.cpy.DefDef(ddef)( tparams = Nil, - vparamss = (outer.paramDefs(sym) ::: ddef.vparamss.flatten) :: Nil, + vparamss = (outer.paramDefs(effectiveSym) ::: ddef.vparamss.flatten) :: Nil, tpt = untpd.TypedSplice(TypeTree(restpe).withPos(ddef.tpt.pos)), rhs = ddef.rhs match { case id @ Ident(nme.WILDCARD) => untpd.TypedSplice(id.withType(restpe)) case _ => ddef.rhs }) - super.typedDefDef(ddef1, sym) + super.typedDefDef(ddef1, effectiveSym) } /** After erasure, we may have to replace the closure method by a bridge. From 36ab621f5dc1fd9a9e2513a02059681478f25887 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 15 May 2015 15:46:12 +0200 Subject: [PATCH 3/3] Fix comment --- src/dotty/tools/dotc/transform/Erasure.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dotty/tools/dotc/transform/Erasure.scala b/src/dotty/tools/dotc/transform/Erasure.scala index 7776117b6305..749bbed9386e 100644 --- a/src/dotty/tools/dotc/transform/Erasure.scala +++ b/src/dotty/tools/dotc/transform/Erasure.scala @@ -471,7 +471,7 @@ object Erasure extends TypeTestsCasts{ override def typedDefDef(ddef: untpd.DefDef, sym: Symbol)(implicit ctx: Context) = { var effectiveSym = sym if (sym == defn.newRefArrayMethod) { - // newRefArray is treated specially: It's new only method source-defined method + // newRefArray is treated specially: It's the only source-defined method // that has a polymorphic type after erasure. But treating its (dummy) definition // with a polymorphic type at and after erasure is an awkward special case. // We therefore rewrite the method definition with a new Symbol of type