summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominik Gruntz <dominik.gruntz@fhnw.ch>2012-07-11 20:10:30 +0200
committerDominik Gruntz <dominik.gruntz@fhnw.ch>2012-07-11 20:10:30 +0200
commit4aeaf9015befc4f16a962896daa7deda99e11605 (patch)
tree8fd80cf5cc67bda7962aa7998e5bcf408dc73a44
parentbad93927836f302be3b973335a63bb5e69b2237c (diff)
downloadscala-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.scala16
-rw-r--r--test/files/run/reflect-resolveoverload-invalid.scala2
-rw-r--r--test/files/run/reflect-resolveoverload2.scala31
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]))
}