From 27ce72f1b30a06f56782d88c6c4f96d261d4a44e Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 7 Jun 2013 16:14:05 +0200 Subject: 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. --- src/dotty/tools/dotc/core/Definitions.scala | 57 ++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 5 deletions(-) (limited to 'src/dotty/tools/dotc/core/Definitions.scala') 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 -- cgit v1.2.3