summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-01-04 16:03:56 -0800
committerPaul Phillips <paulp@improving.org>2012-01-04 22:51:07 -0800
commit14ca7ef432d57a6188f184b700ca37e42b9ba17d (patch)
treefb88caf51411fe8860590f5436c8f4b2e0d76cdd /src/compiler
parent6975b4888da9b56e2c06d45da8f483f2e33a102b (diff)
downloadscala-14ca7ef432d57a6188f184b700ca37e42b9ba17d.tar.gz
scala-14ca7ef432d57a6188f184b700ca37e42b9ba17d.tar.bz2
scala-14ca7ef432d57a6188f184b700ca37e42b9ba17d.zip
Fix bugs with lubs.
Was not substituting before using fallback lub. I don't think it was hurting anything because the substitution is wrong anyway, since it gives up on f-bounds. (This is directly responsible for the malformed lubs.) But if it must fail, it shouldn't be letting A and Repr escape into the error message: scala> List(List(), Stream()) <console>:8: error: type mismatch; found : List[Nothing] required: scala.collection.immutable.LinearSeq[Nothing] with ..... scala.collection.LinearSeqOptimized[A,Repr]]]]] List(List(), Stream()) ^ Rather, like this: found : List[Nothing] required: scala.collection.immutable.LinearSeq[Nothing] with ..... scala.collection.LinearSeqOptimized[Nothing,scala.collection.immutable.Stream[Nothing]]]]]] Also, AbstractSeq and other not-public classes were appeaing in the errors, alerting me to the fact that it would happily infer a lub containing a type which cannot be referenced. scala> List(List(), Vector()) res1: List[scala.collection.immutable.Seq[Nothing] with scala.collection.AbstractSeq[Nothing] ... So I excluded non-public types in lubList: scala> List(List(), Vector()) res0: List[scala.collection.immutable.Seq[Nothing]] = List(List(), Vector()) Finally, I added logging for recursive bounds. % scala -Ydebug scala> List(List(), Stream()) Encountered 2 recursive bounds while lubbing 2 types. type A in trait LinearSeqOptimized appears in the bounds of type Repr type Repr >: scala.this.Nothing <: collection.this.LinearSeqOptimized[A,Repr] type Repr in trait LinearSeqOptimized appears in its own bounds type Repr >: scala.this.Nothing <: collection.this.LinearSeqOptimized[A,Repr] Review by @moors.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala34
1 files changed, 32 insertions, 2 deletions
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index a644baf9f9..c1d3f85bc9 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -5455,6 +5455,23 @@ A type's typeSymbol should never be inspected directly.
val formatted = tableDef.table(transposed)
println("** Depth is " + depth + "\n" + formatted)
}
+
+ /** From a list of types, find any which take type parameters
+ * where the type parameter bounds contain references to other
+ * any types in the list (including itself.)
+ *
+ * @return List of symbol pairs holding the recursive type
+ * parameter and the parameter which references it.
+ */
+ def findRecursiveBounds(ts: List[Type]): List[(Symbol, Symbol)] = {
+ if (ts.isEmpty) Nil
+ else {
+ val sym = ts.head.typeSymbol
+ require(ts.tail forall (_.typeSymbol == sym), ts)
+ for (p <- sym.typeParams ; in <- sym.typeParams ; if in.info.bounds contains p) yield
+ p -> in
+ }
+ }
/** Given a matrix `tsBts` whose columns are basetype sequences (and the symbols `tsParams` that should be interpreted as type parameters in this matrix),
* compute its least sorted upwards closed upper bound relative to the following ordering <= between lists of types:
@@ -5501,6 +5518,19 @@ A type's typeSymbol should never be inspected directly.
// merging, strip targs that refer to bound tparams (when we're computing the lub of type
// constructors.) Also filter out all types that are a subtype of some other type.
if (isUniformFrontier) {
+ if (settings.debug.value || printLubs) {
+ val fbounds = findRecursiveBounds(ts0)
+ if (fbounds.nonEmpty) {
+ println("Encountered " + fbounds.size + " recursive bounds while lubbing " + ts0.size + " types.")
+ for ((p0, p1) <- fbounds) {
+ val desc = if (p0 == p1) "its own bounds" else "the bounds of " + p1
+
+ println(" " + p0.fullLocationString + " appears in " + desc)
+ println(" " + p1 + " " + p1.info.bounds)
+ }
+ println("")
+ }
+ }
val tails = tsBts map (_.tail)
mergePrefixAndArgs(elimSub(ts0 map elimHigherOrderTypeParam, depth), 1, depth) match {
case Some(tp) => tp :: loop(tails)
@@ -5526,7 +5556,7 @@ A type's typeSymbol should never be inspected directly.
}
}
- val initialBTSes = ts map (_.baseTypeSeq.toList)
+ val initialBTSes = ts map (_.baseTypeSeq.toList filter (_.typeSymbol.isPublic))
if (printLubs)
printLubMatrix(ts zip initialBTSes toMap, depth)
@@ -5977,7 +6007,7 @@ A type's typeSymbol should never be inspected directly.
// conforming to bounds.
val bounds0 = sym.typeParams map (_.info.bounds.hi) filterNot (_.typeSymbol == AnyClass)
if (bounds0.isEmpty) AnyClass.tpe
- else intersectionType(bounds0)
+ else intersectionType(bounds0 map (b => b.asSeenFrom(tps.head, sym)))
}
else if (tparam.variance == -variance) NothingClass.tpe
else NoType