summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Suereth <Joshua.Suereth@gmail.com>2012-09-13 06:07:23 -0700
committerJosh Suereth <Joshua.Suereth@gmail.com>2012-09-13 06:07:23 -0700
commit33ba866fd22a4a5542ae5e4dae8de8bf8d8ab2aa (patch)
tree64351f36b81bb611cf7e6f8fb18fd9d7b75a5dfb
parent20f701bf504530cb12e9d24e2dd66fa42244664d (diff)
parent6fbb4ac42a3fa00689a6c3bbde2be273b7c36b2d (diff)
downloadscala-33ba866fd22a4a5542ae5e4dae8de8bf8d8ab2aa.tar.gz
scala-33ba866fd22a4a5542ae5e4dae8de8bf8d8ab2aa.tar.bz2
scala-33ba866fd22a4a5542ae5e4dae8de8bf8d8ab2aa.zip
Merge pull request #1294 from paulp/issue/6367
Fix for SI-6367, exponential time in inference.
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala30
-rw-r--r--test/files/pos/t6367.scala34
2 files changed, 51 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 =
diff --git a/test/files/pos/t6367.scala b/test/files/pos/t6367.scala
new file mode 100644
index 0000000000..1214be7418
--- /dev/null
+++ b/test/files/pos/t6367.scala
@@ -0,0 +1,34 @@
+package play.api.libs.json.util
+
+trait FunctionalCanBuild[M[_]]{
+ def apply[A,B](ma:M[A], mb:M[B]):M[A ~ B]
+}
+
+trait Variant[M[_]]
+
+trait Functor[M[_]] extends Variant[M]{
+ def fmap[A,B](m:M[A], f: A => B): M[B]
+}
+
+case class ~[A,B](_1:A,_2:B)
+
+class FunctionalBuilder[M[_]](canBuild:FunctionalCanBuild[M]){
+ class CanBuild20[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20](
+ m1:M[A1 ~ A2 ~ A3 ~ A4 ~ A5 ~ A6 ~ A7 ~ A8 ~ A9 ~ A10 ~ A11 ~ A12 ~ A13 ~ A14 ~ A15 ~ A16 ~ A17 ~ A18 ~ A19],
+ m2:M[A20]
+ ) {
+
+ def ~[A21](m3:M[A21]) = new CanBuild21(canBuild(m1,m2),m3)
+
+ def apply[B](f: (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20) => B)(implicit fu:Functor[M]): M[B] =
+ fu.fmap[A1 ~ A2 ~ A3 ~ A4 ~ A5 ~ A6 ~ A7 ~ A8 ~ A9 ~ A10 ~ A11 ~ A12 ~ A13 ~ A14 ~ A15 ~ A16 ~ A17 ~ A18 ~ A19 ~ A20, B](
+ canBuild(m1, m2),
+ { case a1 ~ a2 ~ a3 ~ a4 ~ a5 ~ a6 ~ a7 ~ a8 ~ a9 ~ a10 ~ a11 ~ a12 ~ a13 ~ a14 ~ a15 ~ a16 ~ a17 ~ a18 ~ a19 ~ a20 =>
+ f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) }
+ )
+ }
+
+ class CanBuild21[A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17, A18, A19, A20, A21](m1:M[A1 ~ A2 ~ A3 ~ A4 ~ A5 ~ A6 ~ A7 ~ A8 ~ A9 ~ A10 ~ A11 ~ A12 ~ A13 ~ A14 ~ A15 ~ A16 ~ A17 ~ A18 ~ A19 ~ A20], m2:M[A21]){
+ }
+
+}