diff options
author | Martin Odersky <odersky@gmail.com> | 2015-07-20 13:59:34 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2015-09-18 18:12:16 +0200 |
commit | 38ac02916ec0beef0cb93f0fdd48ad1f9dfdcf48 (patch) | |
tree | ed5255fab168a5d0eecac8e052ce843b43dc3536 /src/dotty | |
parent | 5a9a48d21038b78545aba15d0d99238c3c395d47 (diff) | |
download | dotty-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/dotty')
-rw-r--r-- | src/dotty/tools/dotc/core/TypeApplications.scala | 55 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypeComparer.scala | 7 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Applications.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 7 |
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)) } |