From d89767858c4e3a7ad37d9a98ea1e87f58bd0eb02 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sat, 26 Mar 2016 14:49:17 +0100 Subject: Base deskolemize on ApproximatingTypeMap --- src/dotty/tools/dotc/core/TypeOps.scala | 97 +++------------------------------ 1 file changed, 9 insertions(+), 88 deletions(-) (limited to 'src/dotty/tools/dotc/core/TypeOps.scala') diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala index ff974400d..1288c0b23 100644 --- a/src/dotty/tools/dotc/core/TypeOps.scala +++ b/src/dotty/tools/dotc/core/TypeOps.scala @@ -122,100 +122,21 @@ trait TypeOps { this: Context => // TODO: Make standalone object. def currentVariance = variance } - /** Approximate a type `tp` with a type that does not contain skolem types. - */ - final def deskolemize(tp: Type): Type = deskolemize(tp, 1, Set()) - - private def deskolemize(tp: Type, variance: Int, seen: Set[SkolemType]): Type = { - def approx(lo: Type = defn.NothingType, hi: Type = defn.AnyType, newSeen: Set[SkolemType] = seen) = - if (variance == 0) NoType - else deskolemize(if (variance < 0) lo else hi, variance, newSeen) - tp match { + /** Approximate a type `tp` with a type that does not contain skolem types. */ + object deskolemize extends ApproximatingTypeMap { + private var seen: Set[SkolemType] = Set() + def apply(tp: Type) = tp match { case tp: SkolemType => if (seen contains tp) NoType - else approx(hi = tp.info, newSeen = seen + tp) - case tp: NamedType => - val sym = tp.symbol - if (sym.isStatic) tp else { - val pre1 = deskolemize(tp.prefix, variance, seen) - if (pre1 eq tp.prefix) tp - else { - val d = tp.prefix.member(tp.name) - d.info match { - case TypeAlias(alias) => deskolemize(alias, variance, seen) - case _ => - if (pre1.exists && !pre1.isRef(defn.NothingClass)) tp.derivedSelect(pre1) - else { - ctx.log(s"deskolem: $tp: ${tp.info}") - tp.info match { - case TypeBounds(lo, hi) => approx(lo, hi) - case info => NoType - } - } - } - } + val saved = seen + seen += tp + try approx(hi = tp.info) + finally seen = saved } - case _: ThisType | _: BoundType | _: SuperType | NoType | NoPrefix => - tp - case tp: RefinedType => - val parent1 = deskolemize(tp.parent, variance, seen) - if (parent1.exists) { - val refinedInfo1 = deskolemize(tp.refinedInfo, variance, seen) - if (refinedInfo1.exists) - tp.derivedRefinedType(parent1, tp.refinedName, refinedInfo1) - else - approx(hi = parent1) - } - else approx() - case tp: TypeAlias => - val alias1 = deskolemize(tp.alias, variance * tp.variance, seen) - if (alias1.exists) tp.derivedTypeAlias(alias1) - else approx(hi = TypeBounds.empty) - case tp: TypeBounds => - val lo1 = deskolemize(tp.lo, -variance, seen) - val hi1 = deskolemize(tp.hi, variance, seen) - if (lo1.exists && hi1.exists) tp.derivedTypeBounds(lo1, hi1) - else approx(hi = - if (lo1.exists) TypeBounds.lower(lo1) - else if (hi1.exists) TypeBounds.upper(hi1) - else TypeBounds.empty) - case tp: ClassInfo => - val pre1 = deskolemize(tp.prefix, variance, seen) - if (pre1.exists) tp.derivedClassInfo(pre1) - else NoType - case tp: AndOrType => - val tp1d = deskolemize(tp.tp1, variance, seen) - val tp2d = deskolemize(tp.tp2, variance, seen) - if (tp1d.exists && tp2d.exists) - tp.derivedAndOrType(tp1d, tp2d) - else if (tp.isAnd) - approx(hi = tp1d & tp2d) // if one of tp1d, tp2d exists, it is the result of tp1d & tp2d - else - approx(lo = tp1d & tp2d) - case tp: WildcardType => - val bounds1 = deskolemize(tp.optBounds, variance, seen) - if (bounds1.exists) tp.derivedWildcardType(bounds1) - else WildcardType case _ => if (tp.isInstanceOf[MethodicType]) assert(variance != 0, tp) - deskolemizeMap.mapOver(tp, variance, seen) - } - } - - object deskolemizeMap extends TypeMap { - private var seen: Set[SkolemType] = _ - def apply(tp: Type) = deskolemize(tp, variance, seen) - def mapOver(tp: Type, variance: Int, seen: Set[SkolemType]) = { - val savedVariance = this.variance - val savedSeen = this.seen - this.variance = variance - this.seen = seen - try super.mapOver(tp) - finally { - this.variance = savedVariance - this.seen = savedSeen - } + mapOver(tp) } } -- cgit v1.2.3