diff options
author | Martin Odersky <odersky@gmail.com> | 2013-08-06 12:48:28 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-08-06 12:48:28 +0200 |
commit | 2985d1806b66d4bf59807f35a6427b81ef66961e (patch) | |
tree | 7564a183711cd993eff378469e37a3ac28c61513 /src/dotty/tools/dotc/core | |
parent | 71e59bb45db6f9f8abd8d42041583d56c88fe289 (diff) | |
download | dotty-2985d1806b66d4bf59807f35a6427b81ef66961e.tar.gz dotty-2985d1806b66d4bf59807f35a6427b81ef66961e.tar.bz2 dotty-2985d1806b66d4bf59807f35a6427b81ef66961e.zip |
Refined treatment of unapply
Diffstat (limited to 'src/dotty/tools/dotc/core')
-rw-r--r-- | src/dotty/tools/dotc/core/Definitions.scala | 10 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 52 |
2 files changed, 52 insertions, 10 deletions
diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala index bde325897..df0173467 100644 --- a/src/dotty/tools/dotc/core/Definitions.scala +++ b/src/dotty/tools/dotc/core/Definitions.scala @@ -142,7 +142,7 @@ class Definitions(implicit ctx: Context) { ScalaPackageClass, tpnme.Null, AbstractFinal, List(AnyRefAlias.typeConstructor)).entered lazy val PredefModule = requiredModule("scala.Predef") - lazy val NilModule = requiredModule("scala.collection.immutable.Nil") + lazy val NilModule = requiredModule("scala.collection.immutable.Nil") // lazy val FunctionClass: ClassSymbol = requiredClass("scala.Function") lazy val SingletonClass: ClassSymbol = @@ -330,7 +330,7 @@ class Definitions(implicit ctx: Context) { * - 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(variances: List[Int]) = { + def hkTrait(vcs: List[Int]) = { def varianceSuffix(v: Int) = v match { case -1 => "N" @@ -348,14 +348,14 @@ class Definitions(implicit ctx: Context) { def complete(denot: SymDenotation): Unit = { val cls = denot.asClass.classSymbol val paramDecls = newScope - for ((v, i) <- variances.zipWithIndex) + for ((v, i) <- vcs.zipWithIndex) newTypeParam(cls, tpnme.higherKindedParamName(i), varianceFlags(v), paramDecls) denot.info = ClassInfo(ScalaPackageClass.thisType, cls, List(ObjectClass.typeConstructor), paramDecls) } } val traitName = - tpnme.higherKindedTraitName(variances.length) ++ (variances map varianceSuffix).mkString + tpnme.higherKindedTraitName(vcs.length) ++ (vcs map varianceSuffix).mkString def createTrait = { val cls = ctx.newClassSymbol( @@ -367,7 +367,7 @@ class Definitions(implicit ctx: Context) { cls } - hkTraitOfArity.getOrElseUpdate(variances, createTrait) + hkTraitOfArity.getOrElseUpdate(vcs, createTrait) } diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 07f3f284f..ff0f2e990 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -940,6 +940,31 @@ object Types { */ def varianceOf(tp: Type): FlagSet = ??? + type VarianceMap = Map[TypeVar, Int] + + /** All occurrences of type vars in this type that satisfy predicate + * `include` mapped to their variances (-1/0/1) in this type, where + * -1 means: only covariant occurrences + * +1 means: only covariant occurrences + * 0 means: mixed or non-variant occurrences + */ + def variances(include: TypeVar => Boolean)(implicit ctx: Context): VarianceMap = { + val accu = new TypeAccumulator[VarianceMap] { + def apply(vmap: VarianceMap, t: Type): VarianceMap = t match { + case t: TypeVar if include(t) => + vmap get t match { + case Some(v) => + if (v == variance) vmap else vmap updated (t, 0) + case None => + vmap updated (t, variance) + } + case _ => + foldOver(vmap, t) + } + } + accu(Map.empty, this) + } + // ----- hashing ------------------------------------------------------ /** customized hash code of this type. @@ -2086,6 +2111,8 @@ object Types { protected def apply(x: T, annot: Annotation): T = x // don't go into annotations + protected var variance = 1 + def foldOver(x: T, tp: Type): T = tp match { case tp: NamedType => this(x, tp.prefix) @@ -2097,21 +2124,36 @@ object Types { this(this(x, tp.parent), tp.refinedInfo) case tp @ MethodType(pnames, ptypes) => - this((x /: ptypes)(this), tp.resultType) + variance = -variance + val y = (x /: ptypes)(this) + variance = -variance + this(y, tp.resultType) case ExprType(restpe) => this(x, restpe) case tp @ PolyType(pnames) => - this((x /: tp.paramBounds)(this), tp.resultType) + variance = -variance + val y = (x /: tp.paramBounds)(this) + variance = -variance + this(y, tp.resultType) case SuperType(thistp, supertp) => this(this(x, thistp), supertp) case TypeBounds(lo, hi) => - if (lo eq hi) this(x, lo) - else this(this(x, lo), hi) - + if (lo eq hi) { + val saved = variance + variance = 0 + try this(x, lo) + finally variance = saved + } + else { + variance = -variance + val y = this(x, lo) + variance = -variance + this(y, hi) + } case AnnotatedType(annot, underlying) => this(this(x, annot), underlying) |