diff options
author | Martin Odersky <odersky@gmail.com> | 2013-12-22 16:11:43 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-12-22 16:12:47 +0100 |
commit | 8216688420003002449313c8a4f419b09282bf84 (patch) | |
tree | ee3ba0a2e0215bf20c4369a27e9133dc65f7fa3e /src/dotty | |
parent | 115e13b323e9ca845302a2c0ee0367e03cb8379b (diff) | |
download | dotty-8216688420003002449313c8a4f419b09282bf84.tar.gz dotty-8216688420003002449313c8a4f419b09282bf84.tar.bz2 dotty-8216688420003002449313c8a4f419b09282bf84.zip |
Desugaring changes
1) Desugar type bounds containing empty trees
2) Include a productN parent for a case class, only if the case class has 2 or more parameters in its parameter section.
Also, handle type bounds appearing in AppliedTypeTrees (these represent wildcard types).
Diffstat (limited to 'src/dotty')
-rw-r--r-- | src/dotty/tools/dotc/ast/Desugar.scala | 36 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypeApplications.scala | 13 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 5 |
3 files changed, 31 insertions, 23 deletions
diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala index 70c3e76f6..600409188 100644 --- a/src/dotty/tools/dotc/ast/Desugar.scala +++ b/src/dotty/tools/dotc/ast/Desugar.scala @@ -136,22 +136,14 @@ object desugar { */ def typeDef(tdef: TypeDef)(implicit ctx: Context): Tree = { val TypeDef(mods, name, rhs) = tdef - val rhs1 = rhs match { - case TypeBoundsTree(lo, hi) => - val lo1 = if (lo.isEmpty) untpd.TypeTree(defn.NothingType) else lo - val hi1 = if (hi.isEmpty) untpd.TypeTree(defn.AnyType) else hi - cpy.TypeBoundsTree(rhs, lo1, hi1) - case _ => - rhs - } if (mods is PrivateLocalParam) { val tparam = cpy.TypeDef(tdef, - mods &~ PrivateLocal | ExpandedName, name.expandedName(ctx.owner), rhs1, tdef.tparams) + mods &~ PrivateLocal | ExpandedName, name.expandedName(ctx.owner), rhs, tdef.tparams) val alias = cpy.TypeDef(tdef, Modifiers(PrivateLocalParamAccessor | Synthetic), name, refOfDef(tparam)) Thicket(tparam, alias) } - else cpy.TypeDef(tdef, mods, name, rhs1, tdef.tparams) + else cpy.TypeDef(tdef, mods, name, rhs, tdef.tparams) } private val synthetic = Modifiers(Synthetic) @@ -226,18 +218,20 @@ object desugar { else Nil def anyRef = ref(defn.AnyRefAlias.typeRef) - def productConstr = { - val tycon = ref(defn.ProductNClass(vparamss.head.length).typeRef) + def productConstr(n: Int) = { + val tycon = ref(defn.ProductNClass(n).typeRef) val targs = vparamss.head map (_.tpt) New(AppliedTypeTree(tycon, targs), Nil) } // The desugared parents: AnyRef, in case parents are Nil. // Case classes also get a ProductN parent - val parents1 = { - val parents0 = if (mods is Case) parents :+ productConstr else parents - if (parents0.isEmpty) New(anyRef, Nil) :: Nil else parents0 - } + var parents1 = parents + val n = vparamss.head.length + if ((mods is Case) && 2 <= n && n <= Definitions.MaxTupleArity) + parents1 = parents1 :+ productConstr(n) + if (parents1.isEmpty) + parents1 = New(anyRef, Nil) :: Nil // The thicket which is the desugared version of the companion object // synthetic object C extends parentTpt { defs } @@ -392,6 +386,16 @@ object desugar { tree } + /** EmptyTree in lower bound ==> Nothing + * EmptyTree in upper bounds ==> Any + */ + def typeBoundsTree(tree: TypeBoundsTree)(implicit ctx: Context): TypeBoundsTree = { + val TypeBoundsTree(lo, hi) = tree + val lo1 = if (lo.isEmpty) untpd.TypeTree(defn.NothingType) else lo + val hi1 = if (hi.isEmpty) untpd.TypeTree(defn.AnyType) else hi + cpy.TypeBoundsTree(tree, lo1, hi1) + } + /** Make closure corresponding to function. * params => body * ==> diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala index 599e4b0f0..98249d8c9 100644 --- a/src/dotty/tools/dotc/core/TypeApplications.scala +++ b/src/dotty/tools/dotc/core/TypeApplications.scala @@ -127,11 +127,14 @@ class TypeApplications(val self: Type) extends AnyVal { /** Turn this type, which is used as an argument for * type parameter `tparam`, into a TypeBounds RHS */ - final def toBounds(tparam: Symbol)(implicit ctx: Context): TypeBounds = { - val v = tparam.variance - if (v > 0 && !(tparam is Local) && !(tparam is ExpandedTypeParam)) TypeBounds.upper(self) - else if (v < 0 && !(tparam is Local) && !(tparam is ExpandedTypeParam)) TypeBounds.lower(self) - else TypeAlias(self, v) + final def toBounds(tparam: Symbol)(implicit ctx: Context): TypeBounds = self match { + case self: TypeBounds => // this can happen for wildcard args + self + case _ => + val v = tparam.variance + if (v > 0 && !(tparam is Local) && !(tparam is ExpandedTypeParam)) TypeBounds.upper(self) + else if (v < 0 && !(tparam is Local) && !(tparam is ExpandedTypeParam)) TypeBounds.lower(self) + else TypeAlias(self, v) } /** The type arguments of the base type instance wrt `base` of this type */ diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index 69705cfce..54a299291 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -708,8 +708,9 @@ class Typer extends Namer with Applications with Implicits { } def typedTypeBoundsTree(tree: untpd.TypeBoundsTree)(implicit ctx: Context): TypeBoundsTree = track("typedTypeBoundsTree") { - val lo1 = typed(tree.lo) - val hi1 = typed(tree.hi) + val TypeBoundsTree(lo, hi) = desugar.typeBoundsTree(tree) + val lo1 = typed(lo) + val hi1 = typed(hi) if (!(lo1.tpe <:< hi1.tpe)) ctx.error(i"lower bound ${lo1.tpe} does not conform to upper bound ${hi1.tpe}", tree.pos) cpy.TypeBoundsTree(tree, lo1, hi1) withType TypeBounds(lo1.tpe, hi1.tpe) |