From 57aa63bf5e30784877c370b5d1525592943d560f Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 31 Dec 2012 12:38:13 -0800 Subject: Moved VariantTypeMap into Variances. --- src/reflect/scala/reflect/internal/Types.scala | 71 --------------------- src/reflect/scala/reflect/internal/Variances.scala | 74 ++++++++++++++++++++++ 2 files changed, 74 insertions(+), 71 deletions(-) diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 605e4e983a..ec7537daf3 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -3928,77 +3928,6 @@ trait Types extends api.Types { self: SymbolTable => def keepAnnotation(annot: AnnotationInfo) = annot matches TypeConstraintClass } - trait VariantTypeMap extends TypeMap { - private[this] var _variance: Variance = Covariant - - override def variance = _variance - def variance_=(x: Variance) = _variance = x - - override protected def noChangeToSymbols(origSyms: List[Symbol]) = - //OPT inline from forall to save on #closures - origSyms match { - case sym :: rest => - val v = variance - if (sym.isAliasType) variance = Invariant - val result = this(sym.info) - variance = v - (result eq sym.info) && noChangeToSymbols(rest) - case _ => - true - } - - override protected def mapOverArgs(args: List[Type], tparams: List[Symbol]): List[Type] = - map2Conserve(args, tparams) { (arg, tparam) => - val v = variance - if (tparam.isContravariant) variance = variance.flip - else if (!tparam.isCovariant) variance = Invariant - val arg1 = this(arg) - variance = v - arg1 - } - - /** Map this function over given type */ - override def mapOver(tp: Type): Type = tp match { - case MethodType(params, result) => - variance = variance.flip - val params1 = mapOver(params) - variance = variance.flip - val result1 = this(result) - if ((params1 eq params) && (result1 eq result)) tp - else copyMethodType(tp, params1, result1.substSym(params, params1)) - case PolyType(tparams, result) => - variance = variance.flip - val tparams1 = mapOver(tparams) - variance = variance.flip - val result1 = this(result) - if ((tparams1 eq tparams) && (result1 eq result)) tp - else PolyType(tparams1, result1.substSym(tparams, tparams1)) - case TypeBounds(lo, hi) => - variance = variance.flip - val lo1 = this(lo) - variance = variance.flip - val hi1 = this(hi) - if ((lo1 eq lo) && (hi1 eq hi)) tp - else TypeBounds(lo1, hi1) - case tr @ TypeRef(pre, sym, args) => - val pre1 = this(pre) - val args1 = - if (args.isEmpty) - args - else if (variance.isInvariant) // fast & safe path: don't need to look at typeparams - args mapConserve this - else { - val tparams = sym.typeParams - if (tparams.isEmpty) args - else mapOverArgs(args, tparams) - } - if ((pre1 eq pre) && (args1 eq args)) tp - else copyTypeRef(tp, pre1, tr.coevolveSym(pre1), args1) - case _ => - super.mapOver(tp) - } - } - // todo. move these into scala.reflect.api /** A prototype for mapping a function over all possible types diff --git a/src/reflect/scala/reflect/internal/Variances.scala b/src/reflect/scala/reflect/internal/Variances.scala index 6560f088c5..a619d7bef7 100644 --- a/src/reflect/scala/reflect/internal/Variances.scala +++ b/src/reflect/scala/reflect/internal/Variances.scala @@ -14,6 +14,80 @@ import scala.collection.{ mutable, immutable } trait Variances { self: SymbolTable => + /** Used by ExistentialExtrapolation and adaptConstrPattern(). + * TODO - eliminate duplication with all the rest. + */ + trait VariantTypeMap extends TypeMap { + private[this] var _variance: Variance = Covariant + + override def variance = _variance + def variance_=(x: Variance) = _variance = x + + override protected def noChangeToSymbols(origSyms: List[Symbol]) = + //OPT inline from forall to save on #closures + origSyms match { + case sym :: rest => + val v = variance + if (sym.isAliasType) variance = Invariant + val result = this(sym.info) + variance = v + (result eq sym.info) && noChangeToSymbols(rest) + case _ => + true + } + + override protected def mapOverArgs(args: List[Type], tparams: List[Symbol]): List[Type] = + map2Conserve(args, tparams) { (arg, tparam) => + val v = variance + if (tparam.isContravariant) variance = variance.flip + else if (!tparam.isCovariant) variance = Invariant + val arg1 = this(arg) + variance = v + arg1 + } + + /** Map this function over given type */ + override def mapOver(tp: Type): Type = tp match { + case MethodType(params, result) => + variance = variance.flip + val params1 = mapOver(params) + variance = variance.flip + val result1 = this(result) + if ((params1 eq params) && (result1 eq result)) tp + else copyMethodType(tp, params1, result1.substSym(params, params1)) + case PolyType(tparams, result) => + variance = variance.flip + val tparams1 = mapOver(tparams) + variance = variance.flip + val result1 = this(result) + if ((tparams1 eq tparams) && (result1 eq result)) tp + else PolyType(tparams1, result1.substSym(tparams, tparams1)) + case TypeBounds(lo, hi) => + variance = variance.flip + val lo1 = this(lo) + variance = variance.flip + val hi1 = this(hi) + if ((lo1 eq lo) && (hi1 eq hi)) tp + else TypeBounds(lo1, hi1) + case tr @ TypeRef(pre, sym, args) => + val pre1 = this(pre) + val args1 = + if (args.isEmpty) + args + else if (variance.isInvariant) // fast & safe path: don't need to look at typeparams + args mapConserve this + else { + val tparams = sym.typeParams + if (tparams.isEmpty) args + else mapOverArgs(args, tparams) + } + if ((pre1 eq pre) && (args1 eq args)) tp + else copyTypeRef(tp, pre1, tr.coevolveSym(pre1), args1) + case _ => + super.mapOver(tp) + } + } + /** Used in Refchecks. * TODO - eliminate duplication with varianceInType */ -- cgit v1.2.3