diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 8 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Inferencing.scala | 31 |
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 |