aboutsummaryrefslogtreecommitdiff
path: root/src/dotty
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-07-13 13:46:54 +0200
committerMartin Odersky <odersky@gmail.com>2016-07-13 13:47:44 +0200
commitf50cb2040494e622f17a1bcc323424a27129fc3a (patch)
tree34c77552d3b6f6b25797ba66494e679427dd35a2 /src/dotty
parent1443fd4c844c1c54e59479e156833d2cce9a349a (diff)
downloaddotty-f50cb2040494e622f17a1bcc323424a27129fc3a.tar.gz
dotty-f50cb2040494e622f17a1bcc323424a27129fc3a.tar.bz2
dotty-f50cb2040494e622f17a1bcc323424a27129fc3a.zip
Make rewritings of hk applications configurable
Beta-reduce only if `Config.simplifyApplications` is true. Turning off beta-reduction revealed two problems which are also fixed in this commit: 1. Bad treatement of higher-kinded argyments in cyclicity checking 2. Wrong variance for higher-kinded arguments in TypeAccumulator
Diffstat (limited to 'src/dotty')
-rw-r--r--src/dotty/tools/dotc/config/Config.scala7
-rw-r--r--src/dotty/tools/dotc/core/TypeApplications.scala28
-rw-r--r--src/dotty/tools/dotc/core/Types.scala23
-rw-r--r--src/dotty/tools/dotc/typer/Checking.scala2
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