aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/TypeOps.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-03-26 14:49:17 +0100
committerMartin Odersky <odersky@gmail.com>2016-03-30 09:51:04 +0200
commitd89767858c4e3a7ad37d9a98ea1e87f58bd0eb02 (patch)
treebdedda1e297493c39cc3168b97e03dc343ad4463 /src/dotty/tools/dotc/core/TypeOps.scala
parent78545bbca89bafbee31fc5e4d9818e3173fb7131 (diff)
downloaddotty-d89767858c4e3a7ad37d9a98ea1e87f58bd0eb02.tar.gz
dotty-d89767858c4e3a7ad37d9a98ea1e87f58bd0eb02.tar.bz2
dotty-d89767858c4e3a7ad37d9a98ea1e87f58bd0eb02.zip
Base deskolemize on ApproximatingTypeMap
Diffstat (limited to 'src/dotty/tools/dotc/core/TypeOps.scala')
-rw-r--r--src/dotty/tools/dotc/core/TypeOps.scala97
1 files changed, 9 insertions, 88 deletions
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)
}
}