aboutsummaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2017-02-10 11:36:06 +1100
committerMartin Odersky <odersky@gmail.com>2017-04-04 13:29:38 +0200
commita5345a38c151472f80e56eaaa2ce764edde3ad79 (patch)
treecb30ec6b401476500027c2aaffd89d94cfa88f13 /compiler
parent7a7db73ae9738f6ed63772851fa5e9820628b015 (diff)
downloaddotty-a5345a38c151472f80e56eaaa2ce764edde3ad79.tar.gz
dotty-a5345a38c151472f80e56eaaa2ce764edde3ad79.tar.bz2
dotty-a5345a38c151472f80e56eaaa2ce764edde3ad79.zip
Be more systematic about result of apply method
The same type needs to be used as a result type for the copy method, and the function type implemented by the companion module.
Diffstat (limited to 'compiler')
-rw-r--r--compiler/src/dotty/tools/dotc/ast/Desugar.scala26
1 files changed, 18 insertions, 8 deletions
diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala
index 863c10cb0..83a23edf0 100644
--- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala
@@ -334,12 +334,19 @@ object desugar {
// a reference to the class type bound by `cdef`, with type parameters coming from the constructor
val classTypeRef = appliedRef(classTycon)
- // a refereence to `enumClass`, with type parameters coming from the constructor
+ // a reference to `enumClass`, with type parameters coming from the constructor
lazy val enumClassTypeRef = appliedRef(enumClassRef)
// new C[Ts](paramss)
lazy val creatorExpr = New(classTypeRef, constrVparamss nestedMap refOfDef)
+ // The return type of the `apply` and `copy` methods
+ val applyResultTpt =
+ if (isEnumCase)
+ if (parents.isEmpty) enumClassTypeRef
+ else parents.head
+ else TypeTree()
+
// Methods to add to a case class C[..](p1: T1, ..., pN: Tn)(moreParams)
// def isDefined = true
// def productArity = N
@@ -380,7 +387,7 @@ object desugar {
cpy.ValDef(vparam)(rhs = copyDefault(vparam)))
val copyRestParamss = derivedVparamss.tail.nestedMap(vparam =>
cpy.ValDef(vparam)(rhs = EmptyTree))
- DefDef(nme.copy, derivedTparams, copyFirstParams :: copyRestParamss, TypeTree(), creatorExpr)
+ DefDef(nme.copy, derivedTparams, copyFirstParams :: copyRestParamss, applyResultTpt, creatorExpr)
.withMods(synthetic) :: Nil
}
@@ -430,15 +437,15 @@ object desugar {
constrVparamss.length > 1 ||
mods.is(Abstract) ||
constr.mods.is(Private)) anyRef
+ else
// todo: also use anyRef if constructor has a dependent method type (or rule that out)!
- else (constrVparamss :\ classTypeRef) ((vparams, restpe) => Function(vparams map (_.tpt), restpe))
+ (constrVparamss :\ (if (isEnumCase) applyResultTpt else classTypeRef)) (
+ (vparams, restpe) => Function(vparams map (_.tpt), restpe))
val applyMeths =
if (mods is Abstract) Nil
- else {
- val restpe = if (isEnumCase) enumClassTypeRef else TypeTree()
- DefDef(nme.apply, derivedTparams, derivedVparamss, restpe, creatorExpr)
+ else
+ DefDef(nme.apply, derivedTparams, derivedVparamss, applyResultTpt, creatorExpr)
.withFlags(Synthetic | (constr1.mods.flags & DefaultParameterized)) :: Nil
- }
val unapplyMeth = {
val unapplyParam = makeSyntheticParameter(tpt = classTypeRef)
val unapplyRHS = if (arity == 0) Literal(Constant(true)) else Ident(unapplyParam.name)
@@ -505,7 +512,10 @@ object desugar {
case _ =>
}
- flatTree(cdef1 :: companions ::: implicitWrappers)
+ val result = val flatTree(cdef1 :: companions ::: implicitWrappers)
+ //if (isEnum) println(i"enum $cdef\n --->\n$result")
+ //if (isEnumCase) println(i"enum case $cdef\n --->\n$result")
+ result
}
val AccessOrSynthetic = AccessFlags | Synthetic