diff options
author | Sébastien Doeraene <sjrdoeraene@gmail.com> | 2016-03-23 11:51:25 +0100 |
---|---|---|
committer | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2016-04-18 14:44:23 +0200 |
commit | 27deb1e0d41a4dfc24a4cac8a311c30471d454e5 (patch) | |
tree | ef9001d9b1bf141f4e4887d1525315f8d20e404b /src/dotty/tools/dotc/transform/Erasure.scala | |
parent | 88baa04f2bc6b89d3e65226973d7b72fdf715095 (diff) | |
download | dotty-27deb1e0d41a4dfc24a4cac8a311c30471d454e5.tar.gz dotty-27deb1e0d41a4dfc24a4cac8a311c30471d454e5.tar.bz2 dotty-27deb1e0d41a4dfc24a4cac8a311c30471d454e5.zip |
Fix #1167: Remove the magic from Arrays.newRefArray.
Previously, the method `Arrays.newRefArray` was one of the only 3
methods that are kept generic after erasure. This commit removes
this magic, by making it take an actual `j.l.Class[T]` as
parameter.
Moreover, the methods `newXArray` all receive an actual body,
implemented on top of Java reflection, which means that a back-end
does not *have to* special-case those methods for correctness.
It might still be required for performance, though, depending on
the back-end.
The JVM back-end is made non-optimal in this commit, precisely
because it does not specialize that method anymore. Doing so
requires modifying the fork of scalac that we use, which should
be done separately.
The JS back-end is adapted simply by doing nothing at all on any
of the newXArray methods. It will normally call the user-space
implementations which use reflection. The Scala.js optimizer will
inline and intrinsify the reflective calls, producing optimal
code, at the end of the day.
Diffstat (limited to 'src/dotty/tools/dotc/transform/Erasure.scala')
-rw-r--r-- | src/dotty/tools/dotc/transform/Erasure.scala | 18 |
1 files changed, 4 insertions, 14 deletions
diff --git a/src/dotty/tools/dotc/transform/Erasure.scala b/src/dotty/tools/dotc/transform/Erasure.scala index 7acb14af4..4e7bcffd4 100644 --- a/src/dotty/tools/dotc/transform/Erasure.scala +++ b/src/dotty/tools/dotc/transform/Erasure.scala @@ -467,28 +467,18 @@ 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) = { - var effectiveSym = sym - if (sym == defn.newRefArrayMethod) { - // 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 - // (length: Int)Object - val MethodType(pnames, ptypes) = sym.info.resultType - effectiveSym = sym.copy(info = MethodType(pnames, ptypes, defn.ObjectType)) - } val restpe = - if (effectiveSym.isConstructor) defn.UnitType - else effectiveSym.info.resultType + if (sym.isConstructor) defn.UnitType + else sym.info.resultType val ddef1 = untpd.cpy.DefDef(ddef)( tparams = Nil, - vparamss = (outer.paramDefs(effectiveSym) ::: ddef.vparamss.flatten) :: Nil, + vparamss = (outer.paramDefs(sym) ::: 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, effectiveSym) + super.typedDefDef(ddef1, sym) } /** After erasure, we may have to replace the closure method by a bridge. |