diff options
author | Paul Phillips <paulp@improving.org> | 2012-09-12 12:02:07 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-09-12 12:17:09 -0700 |
commit | 6fbb4ac42a3fa00689a6c3bbde2be273b7c36b2d (patch) | |
tree | e2e1482342e5f07f63bf7945c340ae82867ef07a /src | |
parent | 7e1f10d228c1f0c47db4f2136dda4b5690f43445 (diff) | |
download | scala-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')
-rw-r--r-- | src/reflect/scala/reflect/internal/Types.scala | 30 |
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 = |