aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/core/Types.scala8
-rw-r--r--src/dotty/tools/dotc/typer/Inferencing.scala31
2 files changed, 39 insertions, 0 deletions
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index beb867523..4b3dfe2b7 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -1035,6 +1035,8 @@ object Types {
/** A trait for proto-types, used as expected types in typer */
trait ProtoType extends Type {
def isMatchedBy(tp: Type)(implicit ctx: Context): Boolean
+ def fold[T](x: T, ta: TypeAccumulator[T]): T
+ def map(tm: TypeMap): ProtoType
}
// --- NamedTypes ------------------------------------------------------------------
@@ -2163,6 +2165,9 @@ object Types {
case tp @ WildcardType =>
tp.derivedWildcardType(mapOver(tp.optBounds))
+ case tp: ProtoType =>
+ tp.map(this)
+
case _ =>
tp
}
@@ -2299,6 +2304,9 @@ object Types {
case tp: WildcardType =>
this(x, tp.optBounds)
+ case tp: ProtoType =>
+ tp.fold(x, this)
+
case _ => x
}
}
diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala
index 85790094c..ae7334513 100644
--- a/src/dotty/tools/dotc/typer/Inferencing.scala
+++ b/src/dotty/tools/dotc/typer/Inferencing.scala
@@ -84,6 +84,8 @@ object Inferencing {
new SelectionProto(refinedName1, tp1.refinedInfo)
}
}
+ def map(tm: TypeMap) = tm(this).asInstanceOf[SelectionProto]
+ def fold[T](x: T, ta: TypeAccumulator[T]) = ta(x, this)
}
/** Create a selection proto-type, but only one level deep;
@@ -155,6 +157,14 @@ object Inferencing {
}
override def toString = s"FunProto(${args mkString ","} => $resultType)"
+
+ def map(tm: TypeMap): FunProto = {
+ val resultType1 = tm(resultType)
+ if (resultType1 eq resultType) this
+ else FunProto(args, resultType1, typer)
+ }
+
+ def fold[T](x: T, ta: TypeAccumulator[T]): T = ta(x, resultType)
}
/** A prototype for implicitly inferred views:
@@ -170,6 +180,16 @@ object Inferencing {
def isMatchedBy(tp: Type)(implicit ctx: Context) = /*ctx.conditionalTraceIndented(lookingForInfo, i"?.info isMatchedBy $tp ${tp.getClass}")*/ {
ctx.typer.isApplicable(tp, argType :: Nil, resultType)
}
+
+ def map(tm: TypeMap): ViewProto = {
+ val argType1 = tm(argType)
+ val resultType1 = tm(resultType)
+ if ((argType1 eq argType) && (resultType1 eq resultType)) this
+ else ViewProto(argType1, resultType1)
+ }
+
+ def fold[T](x: T, ta: TypeAccumulator[T]): T = ta(ta(x, argType), resultType)
+
override def namedPartsWith(p: NamedType => Boolean)(implicit ctx: Context): collection.Set[NamedType] =
AndType.unchecked(argType, resultType).namedPartsWith(p) // this is more efficient than oring two namedParts sets
override def computeHash = doHash(argType, resultType)
@@ -190,6 +210,15 @@ object Inferencing {
}
isInstantiatable(tp) || tp.member(nme.apply).hasAltWith(d => isInstantiatable(d.info))
}
+
+ def map(tm: TypeMap): PolyProto = {
+ val targs1 = targs mapConserve tm
+ val resultType1 = tm(resultType)
+ if ((targs1 eq targs) && (resultType1 eq resultType)) this
+ else PolyProto(targs1, resultType1)
+ }
+
+ def fold[T](x: T, ta: TypeAccumulator[T]): T = ta((x /: targs)(ta), resultType)
}
/** A prototype for expressions [] that are known to be functions:
@@ -198,6 +227,8 @@ object Inferencing {
*/
object AnyFunctionProto extends UncachedGroundType with ProtoType {
def isMatchedBy(tp: Type)(implicit ctx: Context) = true
+ def map(tm: TypeMap) = this
+ def fold[T](x: T, ta: TypeAccumulator[T]) = x
}
/** The normalized form of a type