diff options
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/scala/reflect/internal/Types.scala | 34 |
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 |