aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/Definitions.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-06-07 16:14:05 +0200
committerMartin Odersky <odersky@gmail.com>2013-06-07 16:14:05 +0200
commit27ce72f1b30a06f56782d88c6c4f96d261d4a44e (patch)
tree7f0ee9f70a6bbf5fd1de0d3deb2016340f0be3d6 /src/dotty/tools/dotc/core/Definitions.scala
parentc76cffe04fd690378337971c78736f920b9a479d (diff)
downloaddotty-27ce72f1b30a06f56782d88c6c4f96d261d4a44e.tar.gz
dotty-27ce72f1b30a06f56782d88c6c4f96d261d4a44e.tar.bz2
dotty-27ce72f1b30a06f56782d88c6c4f96d261d4a44e.zip
Added support for eliminating type parameters from TypeDefs.
(1) New scheme for higher-kinded types that deals also with F-bounds. (2) Type parameters in type aliases are eliminated in most cases by expressing as unparameterized aliases of some refinement type. We will issue an error where this is not possible.
Diffstat (limited to 'src/dotty/tools/dotc/core/Definitions.scala')
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala57
1 files changed, 52 insertions, 5 deletions
diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala
index 58878a493..ae8b7887f 100644
--- a/src/dotty/tools/dotc/core/Definitions.scala
+++ b/src/dotty/tools/dotc/core/Definitions.scala
@@ -20,11 +20,11 @@ class Definitions(implicit ctx: Context) {
import ctx.{requiredClass, requiredModule, requiredPackage}
- private def newSyntheticTypeParam(cls: ClassSymbol, scope: MutableScope, suffix: String = "T0") = {
- val tname = suffix.toTypeName.expandedName(cls)
- val tparam = ctx.newSymbol(cls, tname, TypeParamCreationFlags | ExpandedName, TypeBounds.empty)
- scope.enter(tparam)
- }
+ private def newTypeParam(cls: ClassSymbol, name: TypeName, flags: FlagSet, scope: MutableScope) =
+ scope.enter(ctx.newSymbol(cls, name, flags | TypeParamCreationFlags, TypeBounds.empty))
+
+ private def newSyntheticTypeParam(cls: ClassSymbol, scope: MutableScope, suffix: String = "T0") =
+ newTypeParam(cls, suffix.toTypeName.expandedName(cls), ExpandedName, scope)
private def specialPolyClass(name: TypeName, flags: FlagSet, parentConstrs: Type*): ClassSymbol = {
val completer = new LazyType {
@@ -322,6 +322,53 @@ class Definitions(implicit ctx: Context) {
}
}
+ private var hkTraitOfArity = mutable.Map[List[Int], ClassSymbol]()
+
+ /** The HigherKinded trait corresponding to symbols `boundSyms` (which are assumed
+ * to be the type parameters of a higher-kided type). This is a class symbol that
+ * would be generated by the following schema.
+ *
+ * class HigherKindedXYZ { type v_n _$hk$0; ...; type v_n _$Hk$n }
+ *
+ * Here:
+ *
+ * - XYZ is a string with one letter for each variant of a bound symbols,
+ * using `P` (positive variance), `N` (negative variance), `I` (invariant).
+ * - v_i are the variances of the bound symbols (i.e. +, -, or empty).
+ * - _$hk$i are hgiher-kinded parameter names, which are special treated in type application.
+ */
+ def hkTrait(boundSyms: List[Symbol]) = {
+
+ val completer = new LazyType {
+ def complete(denot: SymDenotation): Unit = {
+ val cls = denot.asClass.classSymbol
+ val paramDecls = newScope
+ for ((bsym, i) <- boundSyms.zipWithIndex)
+ newTypeParam(cls, tpnme.higherKindedParamName(i), bsym.flags & VarianceFlags, paramDecls)
+ denot.info = ClassInfo(ScalaPackageClass.thisType, cls, List(ObjectClass.typeConstructor), paramDecls)
+ }
+ }
+
+ def varianceSuffix(v: Int) = v match {
+ case -1 => "N"
+ case 0 => "I"
+ case 1 => "P"
+ }
+
+ val variances = boundSyms map (_.variance)
+ val traitName =
+ tpnme.higherKindedTraitName(boundSyms.length) ++ (variances map varianceSuffix).mkString
+
+ def createTrait = ctx.newClassSymbol(
+ ScalaPackageClass,
+ traitName,
+ Trait | Interface | Synthetic,
+ completer).entered
+
+ hkTraitOfArity.getOrElseUpdate(variances, createTrait)
+ }
+
+
/** The bounds trait corresponding to the given variance */
def hkBoundsClass(variance: Int) = variance match {
case 0 => InvariantBetweenClass