aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc/core/Types.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2017-03-19 12:44:27 +0100
committerMartin Odersky <odersky@gmail.com>2017-04-06 13:15:29 +0200
commit8d33ca7460493427055daaecca53c66127772831 (patch)
tree2c8f539d138a1374dde36c58ffb2f1d4c0841dfa /compiler/src/dotty/tools/dotc/core/Types.scala
parent15317555c94f613f266d7b0fb0a75b0b6ed2da6d (diff)
downloaddotty-8d33ca7460493427055daaecca53c66127772831.tar.gz
dotty-8d33ca7460493427055daaecca53c66127772831.tar.bz2
dotty-8d33ca7460493427055daaecca53c66127772831.zip
Merge MethodType and PolyType functionality where possible
Two benefits: (1) less code. (2) finding subtle bugs about parameter dependent method types. By merging with PolyTypes we are forced to take parameter dependencies into account.
Diffstat (limited to 'compiler/src/dotty/tools/dotc/core/Types.scala')
-rw-r--r--compiler/src/dotty/tools/dotc/core/Types.scala61
1 files changed, 23 insertions, 38 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala
index 1855e3376..dd314c589 100644
--- a/compiler/src/dotty/tools/dotc/core/Types.scala
+++ b/compiler/src/dotty/tools/dotc/core/Types.scala
@@ -215,17 +215,15 @@ object Types {
/** Is this the type of a method that has a repeated parameter type as
* last parameter type?
*/
- def isVarArgsMethod(implicit ctx: Context): Boolean = this match {
- case tp: PolyType => tp.resultType.isVarArgsMethod
+ def isVarArgsMethod(implicit ctx: Context): Boolean = stripPoly match {
case mt: MethodType => mt.paramInfos.nonEmpty && mt.paramInfos.last.isRepeatedParam
case _ => false
}
/** Is this the type of a method with a leading empty parameter list?
*/
- def isNullaryMethod(implicit ctx: Context): Boolean = this match {
+ def isNullaryMethod(implicit ctx: Context): Boolean = stripPoly match {
case MethodType(Nil) => true
- case tp: PolyType => tp.resultType.isNullaryMethod
case _ => false
}
@@ -2355,7 +2353,11 @@ object Types {
override def resultType(implicit ctx: Context) = resType
+ def isJava: Boolean = false
+ def isImplicit = false
+
def isDependent(implicit ctx: Context): Boolean
+ def isParamDependent(implicit ctx: Context): Boolean
final def isTermLambda = paramNames.head.isTermName
final def isTypeLambda = paramNames.head.isTypeName
@@ -2369,7 +2371,7 @@ object Types {
if (isDependent) resultType.substParams(this, argTypes)
else resultType
- protected def companion: LambdaTypeCompanion[ThisName, PInfo, This]
+ def companion: LambdaTypeCompanion[ThisName, PInfo, This]
/** The type `[tparams := paramRefs] tp`, where `tparams` can be
* either a list of type parameter symbols or a list of lambda parameters
@@ -2519,11 +2521,6 @@ object Types {
type This = MethodType
- protected def companion: MethodTypeCompanion
-
- def isJava = false
- def isImplicit = false
-
val paramInfos = paramInfosExp(this)
val resType = resultTypeExp(this)
assert(resType.exists)
@@ -2554,7 +2551,12 @@ object Types {
}
abstract class LambdaTypeCompanion[N <: Name, PInfo <: Type, LT <: LambdaType] {
- def syntheticParamNames(n: Int): List[N]
+ def syntheticParamName(n: Int): N
+
+ @sharable private val memoizedNames = new mutable.HashMap[Int, List[N]]
+ def syntheticParamNames(n: Int): List[N] = synchronized {
+ memoizedNames.getOrElseUpdate(n, (0 until n).map(syntheticParamName).toList)
+ }
def apply(paramNames: List[N])(paramInfosExp: LT => List[PInfo], resultTypeExp: LT => Type)(implicit ctx: Context): LT
def apply(paramNames: List[N], paramInfos: List[PInfo], resultType: Type)(implicit ctx: Context): LT =
@@ -2576,12 +2578,12 @@ object Types {
abstract class TermLambdaCompanion[LT <: TermLambda]
extends LambdaTypeCompanion[TermName, Type, LT] {
- def syntheticParamNames(n: Int) = nme.syntheticParamNames(n)
+ def syntheticParamName(n: Int) = nme.syntheticParamName(n)
}
abstract class TypeLambdaCompanion[LT <: TypeLambda]
extends LambdaTypeCompanion[TypeName, TypeBounds, LT] {
- def syntheticParamNames(n: Int) = tpnme.syntheticTypeParamNames(n)
+ def syntheticParamName(n: Int) = tpnme.syntheticTypeParamName(n)
}
abstract class MethodTypeCompanion extends TermLambdaCompanion[MethodType] {
@@ -2653,6 +2655,7 @@ object Types {
type This <: TypeLambda
def isDependent(implicit ctx: Context): Boolean = true
+ def isParamDependent(implicit ctx: Context): Boolean = true
def newParamRef(n: Int) = TypeParamRef(this, n)
@@ -3422,8 +3425,7 @@ object Types {
object SAMType {
def zeroParamClass(tp: Type)(implicit ctx: Context): Type = tp match {
case tp: ClassInfo =>
- def zeroParams(tp: Type): Boolean = tp match {
- case pt: PolyType => zeroParams(pt.resultType)
+ def zeroParams(tp: Type): Boolean = tp.stripPoly match {
case mt: MethodType => mt.paramInfos.isEmpty && !mt.resultType.isInstanceOf[MethodType]
case et: ExprType => true
case _ => false
@@ -3541,27 +3543,18 @@ object Types {
variance = -variance
derivedTypeBounds(tp, lo1, this(tp.hi))
- case tp: MethodType =>
- def mapOverMethod = {
+ case tp: LambdaType =>
+ def mapOverLambda = {
variance = -variance
- val ptypes1 = tp.paramInfos mapConserve this
+ val ptypes1 = tp.paramInfos.mapConserve(this).asInstanceOf[List[tp.PInfo]]
variance = -variance
derivedLambdaType(tp)(ptypes1, this(tp.resultType))
}
- mapOverMethod
+ mapOverLambda
case tp: ExprType =>
derivedExprType(tp, this(tp.resultType))
- case tp: TypeLambda =>
- def mapOverPoly = {
- variance = -variance
- val bounds1 = tp.paramInfos.mapConserve(this).asInstanceOf[List[TypeBounds]]
- variance = -variance
- derivedLambdaType(tp)(bounds1, this(tp.resultType))
- }
- mapOverPoly
-
case tp: RecType =>
derivedRecType(tp, this(tp.parent))
@@ -3769,7 +3762,7 @@ object Types {
this(y, hi)
}
- case tp: MethodType =>
+ case tp: LambdaType =>
variance = -variance
val y = foldOver(x, tp.paramInfos)
variance = -variance
@@ -3778,12 +3771,6 @@ object Types {
case ExprType(restpe) =>
this(x, restpe)
- case tp: TypeLambda =>
- variance = -variance
- val y = foldOver(x, tp.paramInfos)
- variance = -variance
- this(y, tp.resultType)
-
case tp: RecType =>
this(x, tp.parent)
@@ -3884,9 +3871,7 @@ object Types {
apply(x, tp.tref)
case tp: ConstantType =>
apply(x, tp.underlying)
- case tp: TermParamRef =>
- apply(x, tp.underlying)
- case tp: TypeParamRef =>
+ case tp: ParamRef =>
apply(x, tp.underlying)
case _ =>
foldOver(x, tp)