diff options
author | Dominik Gruntz <dominik.gruntz@fhnw.ch> | 2012-07-11 20:10:30 +0200 |
---|---|---|
committer | Dominik Gruntz <dominik.gruntz@fhnw.ch> | 2012-07-11 20:10:30 +0200 |
commit | 4aeaf9015befc4f16a962896daa7deda99e11605 (patch) | |
tree | 8fd80cf5cc67bda7962aa7998e5bcf408dc73a44 | |
parent | bad93927836f302be3b973335a63bb5e69b2237c (diff) | |
download | scala-4aeaf9015befc4f16a962896daa7deda99e11605.tar.gz scala-4aeaf9015befc4f16a962896daa7deda99e11605.tar.bz2 scala-4aeaf9015befc4f16a962896daa7deda99e11605.zip |
SI-6061 adds weakly conformance for number types to resolveOverloaded
This fix changes resolveOverloaded in scala.reflect.internal
so that numeric widening on the actual argument types is also
considered for primitive number types. Needs changes in functions
applicable and mostSpecific.
-rw-r--r-- | src/reflect/scala/reflect/internal/Symbols.scala | 16 | ||||
-rw-r--r-- | test/files/run/reflect-resolveoverload-invalid.scala | 2 | ||||
-rw-r--r-- | test/files/run/reflect-resolveoverload2.scala | 31 |
3 files changed, 35 insertions, 14 deletions
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 77c27126c5..47e84b4918 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -93,6 +93,16 @@ trait Symbols extends api.Symbols { self: SymbolTable => // Begin Correlation Helpers + def weaklyConforms(a: Type, f: Type): Boolean = (a =:= f) || { + if(a =:= typeOf[Byte]) weaklyConforms(typeOf[Short], f) + else if(a =:= typeOf[Short]) weaklyConforms(typeOf[Int], f) + else if(a =:= typeOf[Char]) weaklyConforms(typeOf[Int], f) + else if(a =:= typeOf[Int]) weaklyConforms(typeOf[Long], f) + else if(a =:= typeOf[Long]) weaklyConforms(typeOf[Float], f) + else if(a =:= typeOf[Float]) weaklyConforms(typeOf[Double], f) + else false + } + def isCompatible(tp: Type, pt: Type): Boolean = { def isCompatibleByName(tp: Type, pt: Type): Boolean = pt match { case TypeRef(_, ByNameParamClass, List(res)) if !definitions.isByNameParamType(tp) => @@ -100,13 +110,13 @@ trait Symbols extends api.Symbols { self: SymbolTable => case _ => false } - (tp <:< pt) || isCompatibleByName(tp, pt) + (tp <:< pt) || weaklyConforms(tp, pt) || isCompatibleByName(tp, pt) } def signatureAsSpecific(method1: MethodSymbol, method2: MethodSymbol): Boolean = { (substituteTypeParams(method1), substituteTypeParams(method2)) match { case (NullaryMethodType(r1), NullaryMethodType(r2)) => - r1 <:< r2 + r1 <:< r2 || weaklyConforms(r1, r2) case (NullaryMethodType(_), MethodType(_, _)) => true case (MethodType(_, _), NullaryMethodType(_)) => @@ -298,7 +308,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => else { val a = argTypes val p = extend(paramTypes, argTypes.length) - (a corresponds p)(_ <:< _) + (a corresponds p)((a, f) => a <:< f || weaklyConforms(a, f)) } } } diff --git a/test/files/run/reflect-resolveoverload-invalid.scala b/test/files/run/reflect-resolveoverload-invalid.scala index def28ccbb4..8c5dc9f94b 100644 --- a/test/files/run/reflect-resolveoverload-invalid.scala +++ b/test/files/run/reflect-resolveoverload-invalid.scala @@ -27,7 +27,7 @@ object Test extends App { val d = t member u.newTermName("d") asTermSymbol val e = t member u.newTermName("e") asTermSymbol - val n1 = a.resolveOverloaded(posVargs = List(u.typeOf[Char])) + val n1 = a.resolveOverloaded(posVargs = List(u.typeOf[Long])) val n2 = b.resolveOverloaded(posVargs = List(u.typeOf[A])) val n3 = c.resolveOverloaded(posVargs = List(u.typeOf[B], u.typeOf[B])) val n4 = d.resolveOverloaded(targs = List(u.typeOf[Int])) diff --git a/test/files/run/reflect-resolveoverload2.scala b/test/files/run/reflect-resolveoverload2.scala index b5f719814b..a800a3e92c 100644 --- a/test/files/run/reflect-resolveoverload2.scala +++ b/test/files/run/reflect-resolveoverload2.scala @@ -2,16 +2,20 @@ class A class B extends A class C { - def a(x: Int) = 1 - def a(x: String) = 2 - //def b(x: => Int)(s: String) = 1 - //def b(x: => String)(a: Array[_]) = 2 - def c(x: A) = 1 - def c(x: B) = 2 - //def d(x: => A)(s: String) = 1 - //def d(x: => B)(a: Array[_]) = 2 - def e(x: A) = 1 - def e(x: B = new B) = 2 + def a(x: Int) = 1 + def a(x: String) = 2 + //def b(x: => Int)(s: String) = 1 + //def b(x: => String)(a: Array[_]) = 2 + def c(x: A) = 1 + def c(x: B) = 2 + //def d(x: => A)(s: String) = 1 + //def d(x: => B)(a: Array[_]) = 2 + def e(x: A) = 1 + def e(x: B = new B) = 2 + def f(x: Int) = 1 + def f(x: String) = 2 + def f(x: Long) = 3 + def f(x: Double) = 4 } object Test extends App { @@ -29,6 +33,8 @@ object Test extends App { } assert(c.a(1) == invoke("a", 1, u.typeOf[Int])) assert(c.a("a") == invoke("a", "a", u.typeOf[String])) + assert(c.a('a') == invoke("a", 'a', u.typeOf[Char])) + assert(c.a(3: Byte) == invoke("a", 3: Byte, u.typeOf[Byte])) //assert(c.b(1)(null) == invoke("b", 1, u.typeOf[Int])) //assert(c.b("a")(null) == invoke("b", "a", u.typeOf[String])) assert(c.c(new A) == invoke("c", new A, u.typeOf[A])) @@ -37,4 +43,9 @@ object Test extends App { //assert(c.d(new B)(null) == invoke("d", new B, u.typeOf[B])) assert(c.e(new A) == invoke("e", new A, u.typeOf[A])) assert(c.e(new B) == invoke("e", new B, u.typeOf[B])) + assert(c.f(1: Short) == invoke("f", 1: Short, u.typeOf[Short])) + assert(c.f(2) == invoke("f", 2, u.typeOf[Int])) + assert(c.f(3L) == invoke("f", 3L, u.typeOf[Long])) + assert(c.f(4f) == invoke("f", 4f, u.typeOf[Float])) + assert(c.f(5d) == invoke("f", 5d, u.typeOf[Double])) } |