summaryrefslogtreecommitdiff
path: root/src/reflect
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-09-12 12:02:07 -0700
committerPaul Phillips <paulp@improving.org>2012-09-12 12:17:09 -0700
commit6fbb4ac42a3fa00689a6c3bbde2be273b7c36b2d (patch)
treee2e1482342e5f07f63bf7945c340ae82867ef07a /src/reflect
parent7e1f10d228c1f0c47db4f2136dda4b5690f43445 (diff)
downloadscala-6fbb4ac42a3fa00689a6c3bbde2be273b7c36b2d.tar.gz
scala-6fbb4ac42a3fa00689a6c3bbde2be273b7c36b2d.tar.bz2
scala-6fbb4ac42a3fa00689a6c3bbde2be273b7c36b2d.zip
Fix for SI-6367, exponential time in inference.
This pathology is not new - it can be witnessed in 2.9, where compiling the test case enclosed with this ticket with -Yinfer-debug will print a line with (pinky to lips) one million type parameters. 1048576 actually, aka 2^20. But in 2.9 we were somehow getting away with creating the list, presumably by not spending much time looking at it. Somewhere between there and M1, that changed. I cut it off at the knees - don't create a list of one million upper bound constraints when 1 will suffice. It would not be too surprising if this proves to be a boon for performance.
Diffstat (limited to 'src/reflect')
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala30
1 files changed, 17 insertions, 13 deletions
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index df44cf234e..29f7b53154 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -3935,13 +3935,15 @@ trait Types extends api.Types { self: SymbolTable =>
def avoidWiden: Boolean = avoidWidening
def addLoBound(tp: Type, isNumericBound: Boolean = false) {
- if (isNumericBound && isNumericValueType(tp)) {
- if (numlo == NoType || isNumericSubType(numlo, tp))
- numlo = tp
- else if (!isNumericSubType(tp, numlo))
- numlo = numericLoBound
+ if (!lobounds.contains(tp)) {
+ if (isNumericBound && isNumericValueType(tp)) {
+ if (numlo == NoType || isNumericSubType(numlo, tp))
+ numlo = tp
+ else if (!isNumericSubType(tp, numlo))
+ numlo = numericLoBound
+ }
+ else lobounds ::= tp
}
- else lobounds ::= tp
}
def checkWidening(tp: Type) {
@@ -3953,14 +3955,16 @@ trait Types extends api.Types { self: SymbolTable =>
}
def addHiBound(tp: Type, isNumericBound: Boolean = false) {
- checkWidening(tp)
- if (isNumericBound && isNumericValueType(tp)) {
- if (numhi == NoType || isNumericSubType(tp, numhi))
- numhi = tp
- else if (!isNumericSubType(numhi, tp))
- numhi = numericHiBound
+ if (!hibounds.contains(tp)) {
+ checkWidening(tp)
+ if (isNumericBound && isNumericValueType(tp)) {
+ if (numhi == NoType || isNumericSubType(tp, numhi))
+ numhi = tp
+ else if (!isNumericSubType(numhi, tp))
+ numhi = numericHiBound
+ }
+ else hibounds ::= tp
}
- else hibounds ::= tp
}
def isWithinBounds(tp: Type): Boolean =