Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Moved VariantTypeMap into Variances.

  • Loading branch information...
commit 57aa63bf5e30784877c370b5d1525592943d560f 1 parent 91d8584
@paulp paulp authored
View
71 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
View
74 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
*/
Please sign in to comment.
Something went wrong with that request. Please try again.