aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-07-20 13:59:34 +0200
committerMartin Odersky <odersky@gmail.com>2015-09-18 18:12:16 +0200
commit38ac02916ec0beef0cb93f0fdd48ad1f9dfdcf48 (patch)
treeed5255fab168a5d0eecac8e052ce843b43dc3536 /src
parent5a9a48d21038b78545aba15d0d99238c3c395d47 (diff)
downloaddotty-38ac02916ec0beef0cb93f0fdd48ad1f9dfdcf48.tar.gz
dotty-38ac02916ec0beef0cb93f0fdd48ad1f9dfdcf48.tar.bz2
dotty-38ac02916ec0beef0cb93f0fdd48ad1f9dfdcf48.zip
Replace isLambda with ifHK
Replace occurrences of isLambda with isHK, because isHK is a bit faster and simplier.
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/core/TypeApplications.scala55
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala7
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala7
5 files changed, 21 insertions, 52 deletions
diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala
index 75a0b9957..66542d02d 100644
--- a/src/dotty/tools/dotc/core/TypeApplications.scala
+++ b/src/dotty/tools/dotc/core/TypeApplications.scala
@@ -141,13 +141,11 @@ class TypeApplications(val self: Type) extends AnyVal {
def isInstantiatedLambda(implicit ctx: Context): Boolean =
isSafeLambda && typeParams.isEmpty
+ /** Is receiver type higher-kinded (i.e. of kind != "*")? */
def isHK(implicit ctx: Context): Boolean = self.dealias match {
- case self: TypeRef =>
- self.info match {
- case TypeBounds(_, hi) => hi.isHK
- case _ => false
- }
+ case self: TypeRef => self.info.isHK
case RefinedType(_, name) => name == tpnme.hkApply || name.isLambdaArgName
+ case TypeBounds(_, hi) => hi.isHK
case _ => false
}
@@ -160,24 +158,7 @@ class TypeApplications(val self: Type) extends AnyVal {
println(s"precomplete decls = ${self.typeSymbol.unforcedDecls.toList.map(_.denot).mkString("\n ")}")
}
val tparam = tparams.head
- val needsEtaExpand =
- try {
- (tparam is HigherKinded) && !arg.isLambda && arg.typeParams.nonEmpty
- }
- catch {
- case ex: CyclicReference =>
- if (ctx.mode.is(Mode.Scala2Unpickling))
- // When unpickling Scala2, we might run into cyclic references when
- // checking whether eta expansion is needed or eta expanding.
- // (e.g. try compile collection/generic/GenericTraversableTemplate.scala).
- // In that case, back out gracefully. Ideally, we should not have
- // underdefined pickling data that requires post-transformations like
- // eta expansion, but we can't change Scala2's.
- false
- else throw ex
- }
- val arg1 = if (needsEtaExpand) arg.EtaExpand else arg
- val tp1 = RefinedType(tp, tparam.name, arg1.toBounds(tparam))
+ val tp1 = RefinedType(tp, tparam.name, arg.toBounds(tparam))
matchParams(tp1, tparams.tail, args1)
case nil => tp
}
@@ -216,29 +197,23 @@ class TypeApplications(val self: Type) extends AnyVal {
tp
}
- def isHK(tp: Type): Boolean = tp match {
+ /** Same as isHK, except we classify all abstract types as HK,
+ * (they must be, because the are applied). This avoids some forcing and
+ * CyclicReference errors of the standard isHK.
+ */
+ def isKnownHK(tp: Type): Boolean = tp match {
case tp: TypeRef =>
val sym = tp.symbol
if (sym.isClass) sym.isLambdaTrait
- else !sym.isAliasType || isHK(tp.info)
- case tp: TypeProxy => isHK(tp.underlying)
+ else !sym.isAliasType || isKnownHK(tp.info)
+ case tp: TypeProxy => isKnownHK(tp.underlying)
case _ => false
}
if (args.isEmpty || ctx.erasedTypes) self
else {
val res = instantiate(self, self)
- if (isHK(res))
- // Note: isHK needs to be conservative, using isSafeLambda
- // in order to avoid cyclic reference errors. But this means that some fully
- // instantiated types will remain unprojected, which essentially means
- // that they stay as higher-kinded types. checkNonCyclic checks the type again
- // and potentially inserts an #Apply then. Hopefully, this catches all types
- // that fall through the hole. Not adding an #Apply typically manifests itself
- // with a <:< failure of two types that "look the same". An example is #779,
- // where compiling scala.immutable.Map gives a bounds violation.
- TypeRef(res, tpnme.hkApply)
- else res
+ if (isKnownHK(res)) TypeRef(res, tpnme.hkApply) else res
}
}
@@ -510,9 +485,9 @@ class TypeApplications(val self: Type) extends AnyVal {
//.ensuring(res => res.EtaReduce =:= self, s"res = $res, core = ${res.EtaReduce}, self = $self, hc = ${res.hashCode}")
}
- /** Eta expand if `bound` is a type lambda */
- def EtaExpandIfLambda(bound: Type)(implicit ctx: Context): Type =
- if (bound.isLambda && self.typeSymbol.isClass && typeParams.nonEmpty && !isLambda) EtaExpand
+ /** Eta expand if `bound` is a higher-kinded type */
+ def EtaExpandIfHK(bound: Type)(implicit ctx: Context): Type =
+ if (bound.isHK && !isHK && self.typeSymbol.isClass && typeParams.nonEmpty) EtaExpand
else self
/** If `self` is an eta expansion of type T, return T, otherwise NoType */
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala
index a8598ae44..35e4d804b 100644
--- a/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -633,11 +633,10 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
/** Does `tp` need to be eta lifted to be comparable to `target`? */
private def needsEtaLift(tp: Type, target: RefinedType): Boolean = {
- //default.echo(i"needs eta $tp $target?", { // @@@ rewrite
+ // if (tp.isLambda != tp.isHK) println(i"discrepancy for $tp, isLambda = ${tp.isLambda}, isHK = ${tp.isHK}")
val name = target.refinedName
- (name.isLambdaArgName || (name eq tpnme.hkApply)) && target.isLambda &&
- tp.exists && !tp.isLambda
- //})
+ (name.isLambdaArgName || (name eq tpnme.hkApply)) &&
+ tp.exists && !tp.isLambda // we do encounter Lambda classes without any arguments here @@@ check whether this makes sense.
}
/** Narrow gadt.bounds for the type parameter referenced by `tr` to include
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala
index 8800c1a55..c7d8acb37 100644
--- a/src/dotty/tools/dotc/typer/Applications.scala
+++ b/src/dotty/tools/dotc/typer/Applications.scala
@@ -613,7 +613,7 @@ trait Applications extends Compatibility { self: Typer =>
}
def adaptTypeArg(tree: tpd.Tree, bound: Type)(implicit ctx: Context): tpd.Tree =
- tree.withType(tree.tpe.EtaExpandIfLambda(bound))
+ tree.withType(tree.tpe.EtaExpandIfHK(bound))
/** Rewrite `new Array[T](....)` trees to calls of newXYZArray methods. */
def convertNewArray(tree: tpd.Tree)(implicit ctx: Context): tpd.Tree = tree match {
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index 225235822..c1341a9ae 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -822,7 +822,7 @@ class Namer { typer: Typer =>
val tycon = tp.withoutArgs(args)
val tparams = tycon.typeParams
if (args.length == tparams.length) { // if lengths differ, problem is caught in typedTypeApply
- val args1 = args.zipWithConserve(tparams)((arg, tparam) => arg.EtaExpandIfLambda(tparam.info))
+ val args1 = args.zipWithConserve(tparams)((arg, tparam) => arg.EtaExpandIfHK(tparam.info))
if (args1 ne args) return this(tycon).appliedTo(args1)
}
}
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 3f7e0b81c..d35356a85 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -1434,12 +1434,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
case Select(New(tpt), nme.CONSTRUCTOR) => tpt.tpe.dealias.argTypesLo
case _ => Nil
}
- if (typeArgs.isEmpty) {
- //for ((pname, pbound) <- poly.paramNames.zip(poly.paramBounds))
- // if (pbound.hi.isSafeLambda)
- // ctx.error(d"cannot infer argument for higher-kinded type parameter $pname", tree.pos)
- typeArgs = constrained(poly, tree)._2
- }
+ if (typeArgs.isEmpty) typeArgs = constrained(poly, tree)._2
convertNewArray(
adaptInterpolated(tree.appliedToTypes(typeArgs), pt, original))
}