aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-06-29 19:46:39 +0200
committerMartin Odersky <odersky@gmail.com>2016-07-11 13:35:01 +0200
commit0a5f8394a4a226bd3dcf9c966495e653a25ed7d2 (patch)
tree278a5a4d717bab8a60fcafca02af7563b69e9599 /src/dotty/tools
parent463e99a48996fbf7148aa62ec6d2f8b28000d2d4 (diff)
downloaddotty-0a5f8394a4a226bd3dcf9c966495e653a25ed7d2.tar.gz
dotty-0a5f8394a4a226bd3dcf9c966495e653a25ed7d2.tar.bz2
dotty-0a5f8394a4a226bd3dcf9c966495e653a25ed7d2.zip
Avoid infinite recursion when comparing recursive types.
The previous scheme goes into an infinite recursion if the recursive type does not contain a reference to itself. Also, make typeParams more defensive The problematic case is something like { z => CC { type hk$0 = z.hk$0; type(param) hk$0 } Here $hk0 becomes a type parameter through CC and the type lambda. It's true that such types are eliminated later on. But we want to avoid mispredictions at all points.
Diffstat (limited to 'src/dotty/tools')
-rw-r--r--src/dotty/tools/dotc/core/TypeApplications.scala4
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala7
3 files changed, 5 insertions, 8 deletions
diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala
index 6fc1fb9dc..fc8876d09 100644
--- a/src/dotty/tools/dotc/core/TypeApplications.scala
+++ b/src/dotty/tools/dotc/core/TypeApplications.scala
@@ -364,9 +364,9 @@ class TypeApplications(val self: Type) extends AnyVal {
val sym = self.parent.classSymbol
if (sym.isLambdaTraitOBS) return sym.typeParams
}
- val precedingParams = self.parent.typeParams
+ val precedingParams = self.parent.typeParams.filterNot(_.memberName == self.refinedName)
if (Config.newHK && self.isTypeParam) precedingParams :+ self
- else precedingParams.filterNot(_.memberName == self.refinedName)
+ else precedingParams
case self: RecType =>
self.parent.typeParams
case self: SingletonType =>
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala
index db41d85aa..dfe94de44 100644
--- a/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -381,7 +381,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
compareRefined
case tp2: RecType =>
val tp1stable = ensureStableSingleton(tp1)
- isSubType(fixRecs(tp1stable, tp1stable.widenExpr), tp2.substRecThis(tp2, tp1stable))
+ isSubType(fixRecs(tp1stable, tp1stable.widenExpr), tp2.parent.substRecThis(tp2, tp1stable))
case OrType(tp21, tp22) =>
// Rewrite T1 <: (T211 & T212) | T22 to T1 <: (T211 | T22) and T1 <: (T212 | T22)
// and analogously for T1 <: T21 | (T221 & T222)
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 33a94f5c7..34be65591 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -1674,11 +1674,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def adaptType(tp: Type): Tree = {
val tree1 =
- if (pt != AnyTypeConstructorProto && tp.typeParamSymbols.nonEmpty) {
- println(i"lam abs $tp with tparams ${tp.typeParamSymbols}%, %")
- tree.withType(tree.tpe.EtaExpand(tp.typeParamSymbols))
- }
- else tree
+ if ((pt eq AnyTypeConstructorProto) || tp.typeParamSymbols.isEmpty) tree
+ else tree.withType(tree.tpe.EtaExpand(tp.typeParamSymbols))
if ((ctx.mode is Mode.Pattern) || tree1.tpe <:< pt) tree1
else err.typeMismatch(tree1, pt)
}