diff options
author | Martin Odersky <odersky@gmail.com> | 2013-06-07 16:14:05 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-06-07 16:14:05 +0200 |
commit | 27ce72f1b30a06f56782d88c6c4f96d261d4a44e (patch) | |
tree | 7f0ee9f70a6bbf5fd1de0d3deb2016340f0be3d6 /src/dotty/tools/dotc/core/Definitions.scala | |
parent | c76cffe04fd690378337971c78736f920b9a479d (diff) | |
download | dotty-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.scala | 57 |
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 |