summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bincompat-backward.whitelist.conf8
-rw-r--r--bincompat-forward.whitelist.conf8
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala5
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala3
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala12
-rw-r--r--test/files/neg/t6138.check7
-rw-r--r--test/files/neg/t6138.scala5
7 files changed, 39 insertions, 9 deletions
diff --git a/bincompat-backward.whitelist.conf b/bincompat-backward.whitelist.conf
index 904e9477a2..2ef4ae1cc1 100644
--- a/bincompat-backward.whitelist.conf
+++ b/bincompat-backward.whitelist.conf
@@ -219,6 +219,14 @@ filter {
{
matchName="scala.concurrent.forkjoin.ForkJoinPool.helpJoinOnce"
problemName=IncompatibleResultTypeProblem
+ },
+ {
+ matchName="scala.reflect.internal.Definitions#DefinitionsClass.getClassMethods"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.internal.Definitions#DefinitionsClass.primitiveGetClassMethods"
+ problemName=MissingMethodProblem
}
]
}
diff --git a/bincompat-forward.whitelist.conf b/bincompat-forward.whitelist.conf
index 83864f48ee..284e0809a8 100644
--- a/bincompat-forward.whitelist.conf
+++ b/bincompat-forward.whitelist.conf
@@ -471,6 +471,14 @@ filter {
{
matchName="scala.concurrent.impl.Promise$CompletionLatch"
problemName=MissingClassProblem
+ },
+ {
+ matchName="scala.reflect.internal.Definitions#DefinitionsClass.getClassMethods"
+ problemName=MissingMethodProblem
+ },
+ {
+ matchName="scala.reflect.internal.Definitions#DefinitionsClass.primitiveGetClassMethods"
+ problemName=MissingMethodProblem
}
]
}
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index ead6ef288c..76249974ac 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -341,11 +341,6 @@ abstract class Erasure extends AddInterfaces
}
}
- // Each primitive value class has its own getClass for ultra-precise class object typing.
- private lazy val primitiveGetClassMethods = Set[Symbol](Any_getClass, AnyVal_getClass) ++ (
- ScalaValueClasses map (_.tpe member nme.getClass_)
- )
-
// ## requires a little translation
private lazy val poundPoundMethods = Set[Symbol](Any_##, Object_##)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index c59ef4ebda..29cd3d4bfa 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -656,8 +656,7 @@ trait Typers extends Modes with Adaptations with Tags {
// To fully benefit from special casing the return type of
// getClass, we have to catch it immediately so expressions
// like x.getClass().newInstance() are typed with the type of x.
- else if ( tree.symbol.name == nme.getClass_
- && tree.tpe.params.isEmpty
+ else if ( isGetClass(tree.symbol)
// TODO: If the type of the qualifier is inaccessible, we can cause private types
// to escape scope here, e.g. pos/t1107. I'm not sure how to properly handle this
// so for now it requires the type symbol be public.
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index e5d9e54a16..629d82d254 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -110,8 +110,10 @@ trait Definitions extends api.StandardDefinitions {
/** Is symbol a numeric value class? */
def isNumericValueClass(sym: Symbol) = ScalaNumericValueClasses contains sym
- def isGetClass(sym: Symbol) =
- (sym.name == nme.getClass_) && flattensToEmpty(sym.paramss)
+ def isGetClass(sym: Symbol) = (
+ sym.name == nme.getClass_ // this condition is for performance only, this is called from `Typer#stabliize`.
+ && getClassMethods(sym)
+ )
lazy val UnitClass = valueClassSymbol(tpnme.Unit)
lazy val ByteClass = valueClassSymbol(tpnme.Byte)
@@ -805,6 +807,12 @@ trait Definitions extends api.StandardDefinitions {
lazy val Any_isInstanceOf = newT1NullaryMethod(AnyClass, nme.isInstanceOf_, FINAL)(_ => booltype)
lazy val Any_asInstanceOf = newT1NullaryMethod(AnyClass, nme.asInstanceOf_, FINAL)(_.typeConstructor)
+ lazy val primitiveGetClassMethods = Set[Symbol](Any_getClass, AnyVal_getClass) ++ (
+ ScalaValueClasses map (_.tpe member nme.getClass_)
+ )
+
+ lazy val getClassMethods: Set[Symbol] = primitiveGetClassMethods + Object_getClass
+
// A type function from T => Class[U], used to determine the return
// type of getClass calls. The returned type is:
//
diff --git a/test/files/neg/t6138.check b/test/files/neg/t6138.check
new file mode 100644
index 0000000000..8fd9978248
--- /dev/null
+++ b/test/files/neg/t6138.check
@@ -0,0 +1,7 @@
+t6138.scala:4: error: ambiguous reference to overloaded definition,
+both method getClass in object definitions of type (s: Int)Any
+and method getClass in object definitions of type (s: String)Any
+match argument types (Nothing)
+ getClass(???): String
+ ^
+one error found
diff --git a/test/files/neg/t6138.scala b/test/files/neg/t6138.scala
new file mode 100644
index 0000000000..2f45a46b1c
--- /dev/null
+++ b/test/files/neg/t6138.scala
@@ -0,0 +1,5 @@
+object definitions {
+ def getClass(s: String): Any = ???
+ def getClass(s: Int): Any = ???
+ getClass(???): String
+}