aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-12-08 18:13:12 +0100
committerMartin Odersky <odersky@gmail.com>2015-12-14 14:30:08 +0100
commit6c9168467d9278e13c06fc7e56ae7bf331ae0198 (patch)
tree6c9e9e84b527a5104e7e7bd53460f54e38136531
parent4900abc7edcd209608cf7539a968cb375bdcb9c1 (diff)
downloaddotty-6c9168467d9278e13c06fc7e56ae7bf331ae0198.tar.gz
dotty-6c9168467d9278e13c06fc7e56ae7bf331ae0198.tar.bz2
dotty-6c9168467d9278e13c06fc7e56ae7bf331ae0198.zip
Fix tricky bug coming up when compiling TraversableViewLike.
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala38
-rw-r--r--tests/pos/paramcycle.scala18
2 files changed, 52 insertions, 4 deletions
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index ca37614bf..7f85badf5 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -789,9 +789,36 @@ class Namer { typer: Typer =>
/** The type signature of a DefDef with given symbol */
def defDefSig(ddef: DefDef, sym: Symbol)(implicit ctx: Context) = {
val DefDef(name, tparams, vparamss, _, _) = ddef
- completeParams(tparams)
- vparamss foreach completeParams
val isConstructor = name == nme.CONSTRUCTOR
+
+ // The following 3 lines replace what was previously just completeParams(tparams).
+ // But that can cause bad bounds being computed, as witnessed by
+ // tests/pos/paramcycle.scala. The problematic sequence is this:
+ // 0. Class constructor gets completed.
+ // 1. Type parameter CP of constructor gets completed
+ // 2. As a first step CP's bounds are set to Nothing..Any.
+ // 3. CP's real type bound demands the completion of corresponding type parameter DP
+ // of enclosing class.
+ // 4. Type parameter DP has a rhs a DerivedFromParam tree, as installed by
+ // desugar.classDef
+ // 5. The completion of DP then copies the current bounds of CP, which are still Nothing..Any.
+ // 6. The completion of CP finishes installing the real type bounds.
+ // Consequence: CP ends up with the wrong bounds!
+ // To avoid this we always complete type parameters of a class before the type parameters
+ // of the class constructor, but after having indexed the constructor parameters (because
+ // indexing is needed to provide a symbol to copy for DP's completion.
+ // With the patch, we get instead the following sequence:
+ // 0. Class constructor gets completed.
+ // 1. Class constructor parameter CP is indexed.
+ // 2. Class parameter DP starts completion.
+ // 3. Info of CP is computed (to be copied to DP).
+ // 4. CP is completed.
+ // 5. Info of CP is copied to DP and DP is completed.
+ index(tparams)
+ if (isConstructor) sym.owner.typeParams.foreach(_.ensureCompleted())
+ for (tparam <- tparams) typedAheadExpr(tparam)
+
+ vparamss foreach completeParams
def typeParams = tparams map symbolOfTree
val paramSymss = ctx.normalizeIfConstructor(vparamss.nestedMap(symbolOfTree), isConstructor)
def wrapMethType(restpe: Type): Type = {
@@ -834,8 +861,11 @@ class Namer { typer: Typer =>
case bounds: TypeBounds => bounds
case alias => TypeAlias(alias, if (sym is Local) sym.variance else 0)
}
- sym.info = NoCompleter
- sym.info = checkNonCyclic(sym, unsafeInfo, reportErrors = true)
+ if (isDerived) sym.info = unsafeInfo
+ else {
+ sym.info = NoCompleter
+ sym.info = checkNonCyclic(sym, unsafeInfo, reportErrors = true)
+ }
etaExpandArgs.apply(sym.info)
}
diff --git a/tests/pos/paramcycle.scala b/tests/pos/paramcycle.scala
new file mode 100644
index 000000000..d894fdf12
--- /dev/null
+++ b/tests/pos/paramcycle.scala
@@ -0,0 +1,18 @@
+import scala.collection._
+import scala.collection.generic._
+
+trait ViewMkString[+A]
+
+trait TraversableViewLike[+A,
+ +Coll,
+ +This <: TraversableView[A, Coll] with TraversableViewLike[A, Coll, This]]
+ extends Traversable[A] with TraversableLike[A, This] with ViewMkString[A] { self =>
+
+ def f[B](pf: PartialFunction[A, B]) =
+ filter(pf.isDefinedAt).map(pf)
+
+}
+
+trait TraversableView[+A, +Coll] extends TraversableViewLike[A, Coll, TraversableView[A, Coll]] { }
+
+