diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/config/Config.scala | 7 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypeApplications.scala | 28 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 23 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Checking.scala | 2 |
4 files changed, 42 insertions, 18 deletions
diff --git a/src/dotty/tools/dotc/config/Config.scala b/src/dotty/tools/dotc/config/Config.scala index 3cc3091b5..0fad2e105 100644 --- a/src/dotty/tools/dotc/config/Config.scala +++ b/src/dotty/tools/dotc/config/Config.scala @@ -98,6 +98,13 @@ object Config { */ final val splitProjections = false + /** If this flag is on, always rewrite an application `S[Ts]` where `S` is an alias for + * `[Xs] -> U` to `[Xs := Ts]U`. If this flag is off, the rewriting is only done if `S` is a + * reference to an instantiated parameter. Turning this flag on was observed to + * give a ~6% speedup on the JUnit test suite. + */ + final val simplifyApplications = true + /** Initial size of superId table */ final val InitialSuperIdsSize = 4096 diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala index b9957ccb2..db6020e54 100644 --- a/src/dotty/tools/dotc/core/TypeApplications.scala +++ b/src/dotty/tools/dotc/core/TypeApplications.scala @@ -469,18 +469,21 @@ class TypeApplications(val self: Type) extends AnyVal { case dealiased: TypeLambda => def tryReduce = if (!args.exists(_.isInstanceOf[TypeBounds])) { - val reduced = dealiased.instantiate(args) - if (dealiased eq stripped) reduced - else reduced match { - case AppliedType(tycon, args) if variancesConform(typParams, tycon.typeParams) => - // Reducing is safe for type inference, as kind of type constructor does not change - //println(i"reduced: $reduced instead of ${HKApply(self, args)}") - reduced + val followAlias = stripped match { + case stripped: TypeRef => + stripped.symbol.is(BaseTypeArg) case _ => - // Reducing changes kind, keep hk application instead - //println(i"fallback: ${HKApply(self, args)} instead of $reduced") - HKApply(self, args) + Config.simplifyApplications && { + dealiased.resType match { + case AppliedType(tyconBody, _) => + variancesConform(typParams, tyconBody.typeParams) + // Reducing is safe for type inference, as kind of type constructor does not change + case _ => false + } + } } + if ((dealiased eq stripped) || followAlias) dealiased.instantiate(args) + else HKApply(self, args) } else dealiased.resType match { case AppliedType(tycon, args1) if tycon.safeDealias ne tycon => @@ -665,11 +668,6 @@ class TypeApplications(val self: Type) extends AnyVal { } } - final def typeConstructor(implicit ctx: Context): Type = self.stripTypeVar match { - case AppliedType(tycon, _) => tycon - case self => self - } - /** If this is the image of a type argument; recover the type argument, * otherwise NoType. */ diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index fc68740eb..d1e5ba47d 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -3422,8 +3422,9 @@ object Types { case tp: HKApply => def mapArg(arg: Type, tparam: TypeParamInfo): Type = { val saved = variance - if (tparam.paramVariance < 0) variance = -variance - else if (tparam.paramVariance == 0) variance = 0 + val pvariance = tparam.paramVariance + if (pvariance < 0) variance = -variance + else if (pvariance == 0) variance = 0 try this(arg) finally variance = saved } @@ -3629,7 +3630,23 @@ object Types { this(x, prefix) case tp @ HKApply(tycon, args) => - foldOver(this(x, tycon), args) + def foldArgs(x: T, tparams: List[TypeParamInfo], args: List[Type]): T = + if (args.isEmpty) { + assert(tparams.isEmpty) + x + } + else { + val tparam = tparams.head + val saved = variance + val pvariance = tparam.paramVariance + if (pvariance < 0) variance = -variance + else if (pvariance == 0) variance = 0 + val acc = + try this(x, args.head) + finally variance = saved + foldArgs(acc, tparams.tail, args.tail) + } + foldArgs(this(x, tycon), tp.typeParams, args) case tp: AndOrType => this(this(x, tp.tp1), tp.tp2) diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala index aa13bdc3d..b37216e6e 100644 --- a/src/dotty/tools/dotc/typer/Checking.scala +++ b/src/dotty/tools/dotc/typer/Checking.scala @@ -204,6 +204,8 @@ object Checking { tp.derivedRefinedType(this(parent), name, this(rinfo, nestedCycleOK, nestedCycleOK)) case tp: RecType => tp.rebind(this(tp.parent)) + case tp @ HKApply(tycon, args) => + tp.derivedAppliedType(this(tycon), args.map(this(_, nestedCycleOK, nestedCycleOK))) case tp @ TypeRef(pre, name) => try { // A prefix is interesting if it might contain (transitively) a reference |