diff options
Diffstat (limited to 'src/dotty/tools/dotc/core')
-rw-r--r-- | src/dotty/tools/dotc/core/TypeOps.scala | 48 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 14 |
2 files changed, 13 insertions, 49 deletions
diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala index 6070b4f49..272e93dd3 100644 --- a/src/dotty/tools/dotc/core/TypeOps.scala +++ b/src/dotty/tools/dotc/core/TypeOps.scala @@ -113,54 +113,6 @@ trait TypeOps { this: Context => } } - type VarianceMap = SimpleMap[TypeVar, Integer] - - /** Add occurrences of type variables in type `tp` to variance map `vmap` */ - final def addVariances(vmap: VarianceMap, tp: Type, variance: Int, include: TypeVar => Boolean, accu: VariancesAccumulator): VarianceMap = tp match { - case tp: TypeRef => - if (tp.symbol.isStatic) vmap - else { - val prefix = tp.prefix - val tp1 = tp.lookupRefined(prefix, tp.name) - addVariances(vmap, if (tp1.exists) tp1 else prefix, variance, include, accu) - } - case tp: TermRef => - if (tp.symbol.isStatic) vmap - else addVariances(vmap, tp.prefix, variance, include, accu) - - case _: ThisType - | _: BoundType - | NoPrefix => vmap - - case tp: RefinedType => - addVariances( - addVariances(vmap, tp.parent, variance, include, accu), - tp.refinedInfo, variance, include, accu) - - case bounds @ TypeBounds(lo, hi) if lo eq hi => - addVariances(vmap, lo, variance * bounds.variance, include, accu) - - case tp: TypeVar if !tp.isInstantiated && (typerState.constraint contains tp) && include(tp) => - val v = vmap(tp) - if (v == null) vmap.updated(tp, variance) - else if (v == variance) vmap - else vmap.updated(tp, 0) - - case _ => - (if (accu != null) accu else new VariancesAccumulator(include)).runOver(vmap, tp, variance) - } - - class VariancesAccumulator(include: TypeVar => Boolean) extends TypeAccumulator[VarianceMap] { - def apply(vmap: VarianceMap, tp: Type): VarianceMap = addVariances(vmap, tp, variance, include, this) - def runOver(vmap: VarianceMap, tp: Type, variance: Int): VarianceMap = { - val saved = this.variance - this.variance = variance - val result = foldOver(vmap, tp) - this.variance = saved - result - } - } - private def enterArgBinding(formal: Symbol, info: Type, cls: ClassSymbol, decls: Scope) = { val lazyInfo = new LazyType { // needed so we do not force `formal`. def complete(denot: SymDenotation)(implicit ctx: Context): Unit = { diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 00d719acb..5c65b7ede 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -838,7 +838,19 @@ object Types { * 0 means: mixed or non-variant occurrences */ def variances(include: TypeVar => Boolean)(implicit ctx: Context): VarianceMap = track("variances") { - ctx.addVariances(SimpleMap.Empty, this, +1, include, null) + val accu = new TypeAccumulator[VarianceMap] { + def apply(vmap: VarianceMap, t: Type): VarianceMap = t match { + case t: TypeVar + if !t.isInstantiated && (ctx.typerState.constraint contains t) && include(t) => + val v = vmap(t) + if (v == null) vmap.updated(t, variance) + else if (v == variance) vmap + else vmap.updated(t, 0) + case _ => + foldOver(vmap, t) + } + } + accu(SimpleMap.Empty, this) } /** A simplified version of this type which is equivalent wrt =:= to this type. |