Skip to content

Commit f618e47

Browse files
committed
Fixes to Unit handling in erasure
1. Erase unit results in getters to BoxedUnit. 2. Erase => Unit to ()Unit; was ()BoxedUnit 3. Make sure ValDefs have same type in tpt as in symbol, analogous to DefDefs.
1 parent 0f7934d commit f618e47

File tree

2 files changed

+23
-5
lines changed

2 files changed

+23
-5
lines changed

src/dotty/tools/dotc/TypeErasure.scala

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package core
44

55
import Symbols._, Types._, Contexts._, Flags._, Names._, StdNames._, Decorators._, Flags.JavaDefined
66
import dotc.transform.ExplicitOuter._
7+
import typer.Mode
78
import util.DotClass
89

910
/** Erased types are:
@@ -89,7 +90,7 @@ object TypeErasure {
8990

9091
/** The current context with a phase no later than erasure */
9192
private def erasureCtx(implicit ctx: Context) =
92-
if (ctx.erasedTypes) ctx.withPhase(ctx.erasurePhase) else ctx
93+
if (ctx.erasedTypes) ctx.withPhase(ctx.erasurePhase).addMode(Mode.FutureDefsOK) else ctx
9394

9495
def erasure(tp: Type)(implicit ctx: Context): Type = scalaErasureFn(tp)(erasureCtx)
9596
def semiErasure(tp: Type)(implicit ctx: Context): Type = semiErasureFn(tp)(erasureCtx)
@@ -141,7 +142,12 @@ object TypeErasure {
141142
if ((sym eq defn.Any_asInstanceOf) || (sym eq defn.Any_isInstanceOf)) eraseParamBounds(sym.info.asInstanceOf[PolyType])
142143
else if (sym.isAbstractType) TypeAlias(WildcardType)
143144
else if (sym.isConstructor) outer.addParam(sym.owner.asClass, erase(tp)(erasureCtx))
144-
else eraseInfo(tp)(erasureCtx)
145+
else eraseInfo(tp)(erasureCtx) match {
146+
case einfo: MethodType if sym.isGetter && einfo.resultType.isRef(defn.UnitClass) =>
147+
defn.BoxedUnitClass.typeRef
148+
case einfo =>
149+
einfo
150+
}
145151
}
146152

147153
def isUnboundedGeneric(tp: Type)(implicit ctx: Context) = !(
@@ -319,7 +325,7 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
319325
}
320326

321327
def eraseInfo(tp: Type)(implicit ctx: Context) = tp match {
322-
case ExprType(rt) => MethodType(Nil, Nil, erasure(rt))
328+
case ExprType(rt) => MethodType(Nil, Nil, eraseResult(rt))
323329
case tp => erasure(tp)
324330
}
325331

src/dotty/tools/dotc/transform/Erasure.scala

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,10 @@ object Erasure extends TypeTestsCasts{
247247
tree.withType(erased)
248248
}
249249

250+
override def typedLiteral(tree: untpd.Literal)(implicit ctc: Context): Literal =
251+
if (tree.typeOpt.isRef(defn.UnitClass)) tree.withType(tree.typeOpt)
252+
else super.typedLiteral(tree)
253+
250254
/** Type check select nodes, applying the following rewritings exhaustively
251255
* on selections `e.m`, where `OT` is the type of the owner of `m` and `ET`
252256
* is the erased type of the selection's original qualifier expression.
@@ -369,12 +373,20 @@ object Erasure extends TypeTestsCasts{
369373
}
370374
}
371375

376+
override def typedValDef(vdef: untpd.ValDef, sym: Symbol)(implicit ctx: Context): ValDef =
377+
super.typedValDef(untpd.cpy.ValDef(vdef)(
378+
tpt = untpd.TypedSplice(TypeTree(sym.info).withPos(vdef.tpt.pos))), sym)
379+
372380
override def typedDefDef(ddef: untpd.DefDef, sym: Symbol)(implicit ctx: Context) = {
381+
val restpe = sym.info.resultType
373382
val ddef1 = untpd.cpy.DefDef(ddef)(
374383
tparams = Nil,
375384
vparamss = ddef.vparamss.flatten :: Nil,
376-
tpt = // keep UnitTypes intact in result position
377-
untpd.TypedSplice(TypeTree(eraseResult(ddef.tpt.typeOpt)).withPos(ddef.tpt.pos)))
385+
tpt = untpd.TypedSplice(TypeTree(restpe).withPos(ddef.tpt.pos)),
386+
rhs = ddef.rhs match {
387+
case id @ Ident(nme.WILDCARD) => untpd.TypedSplice(id.withType(restpe))
388+
case _ => ddef.rhs
389+
})
378390
super.typedDefDef(ddef1, sym)
379391
}
380392

0 commit comments

Comments
 (0)