summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2012-09-11 23:40:11 +0200
committerJason Zaugg <jzaugg@gmail.com>2012-09-11 23:53:22 +0200
commitddb3b889b5fa55760167d9995d2f1549e2542b71 (patch)
tree6e32916bde7f4dccd87b974ae588d7e65acec7ca
parentea651e6fe187920d207aa5fe3c645d294e72e627 (diff)
downloadscala-ddb3b889b5fa55760167d9995d2f1549e2542b71.tar.gz
scala-ddb3b889b5fa55760167d9995d2f1549e2542b71.tar.bz2
scala-ddb3b889b5fa55760167d9995d2f1549e2542b71.zip
A little cleanup along the Any to AnyRef trail.
Followup to 35316be and d3f879a. - Remove obsolete comments and replace them with a test. - Don't emit error addendum unless we know we're dealing with a value class.
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala2
-rw-r--r--src/library/scala/runtime/StringAdd.scala5
-rw-r--r--src/library/scala/runtime/StringFormat.scala6
-rw-r--r--test/files/neg/no-implicit-to-anyref.check28
-rw-r--r--test/files/neg/no-implicit-to-anyref.scala29
5 files changed, 58 insertions, 12 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index b7195b0349..80bb487d2e 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -106,7 +106,7 @@ trait ContextErrors {
else
s"$name extends Any, not AnyRef"
)
- if (isPrimitiveValueType(found)) "" else "\n" +
+ if (isPrimitiveValueType(found) || isTrivialTopType(tp)) "" else "\n" +
s"""|Note that $what.
|Such types can participate in value classes, but instances
|cannot appear in singleton types or in reference comparisons.""".stripMargin
diff --git a/src/library/scala/runtime/StringAdd.scala b/src/library/scala/runtime/StringAdd.scala
index 4693b0bf44..f074b5407e 100644
--- a/src/library/scala/runtime/StringAdd.scala
+++ b/src/library/scala/runtime/StringAdd.scala
@@ -10,10 +10,5 @@ package scala.runtime
/** A wrapper class that adds string concatenation `+` to any value */
final class StringAdd(val self: Any) extends AnyVal {
- // Note: The implicit conversion from Any to StringAdd is one of two
- // implicit conversions from Any to AnyRef in Predef. It is important to have at least
- // two such conversions, so that silent conversions from value types to AnyRef
- // are avoided. If StringFormat should become a value class, another
- // implicit conversion from Any to AnyRef has to be introduced in Predef
def +(other: String) = String.valueOf(self) + other
}
diff --git a/src/library/scala/runtime/StringFormat.scala b/src/library/scala/runtime/StringFormat.scala
index 1f5feec9e1..7d34e82812 100644
--- a/src/library/scala/runtime/StringFormat.scala
+++ b/src/library/scala/runtime/StringFormat.scala
@@ -11,12 +11,6 @@ package scala.runtime
/** A wrapper class that adds a `formatted` operation to any value
*/
final class StringFormat(val self: Any) extends AnyVal {
- // Note: The implicit conversion from Any to StringFormat is one of two
- // implicit conversions from Any to AnyRef in Predef. It is important to have at least
- // two such conversions, so that silent conversions from value types to AnyRef
- // are avoided. If StringFormat should become a value class, another
- // implicit conversion from Any to AnyRef has to be introduced in Predef
-
/** Returns string formatted according to given `format` string.
* Format strings are as for `String.format`
* (@see java.lang.String.format).
diff --git a/test/files/neg/no-implicit-to-anyref.check b/test/files/neg/no-implicit-to-anyref.check
new file mode 100644
index 0000000000..d94b57a30a
--- /dev/null
+++ b/test/files/neg/no-implicit-to-anyref.check
@@ -0,0 +1,28 @@
+no-implicit-to-anyref.scala:11: error: type mismatch;
+ found : Int(1)
+ required: AnyRef
+Note: an implicit exists from scala.Int => java.lang.Integer, but
+methods inherited from Object are rendered ambiguous. This is to avoid
+a blanket implicit which would convert any scala.Int to any AnyRef.
+You may wish to use a type ascription: `x: java.lang.Integer`.
+ 1: AnyRef
+ ^
+no-implicit-to-anyref.scala:17: error: type mismatch;
+ found : Any
+ required: AnyRef
+ (null: Any): AnyRef
+ ^
+no-implicit-to-anyref.scala:21: error: type mismatch;
+ found : AnyVal
+ required: AnyRef
+ (0: AnyVal): AnyRef
+ ^
+no-implicit-to-anyref.scala:27: error: type mismatch;
+ found : Test.AV
+ required: AnyRef
+Note that AV extends Any, not AnyRef.
+Such types can participate in value classes, but instances
+cannot appear in singleton types or in reference comparisons.
+ new AV(0): AnyRef
+ ^
+four errors found
diff --git a/test/files/neg/no-implicit-to-anyref.scala b/test/files/neg/no-implicit-to-anyref.scala
new file mode 100644
index 0000000000..3e3d373e38
--- /dev/null
+++ b/test/files/neg/no-implicit-to-anyref.scala
@@ -0,0 +1,29 @@
+// Checks that the state of standard implicits in Predef._ and scala._
+// doesn't allow us to unambiguously and implicitly convert AnyVal
+// and subtypes to AnyRef.
+//
+// In the days before value classes, this was precariously held be
+// the competing implicits Any => StringAdd and Any => StringFormat.
+// Since then, these have both become value classes, but seeing as
+// this happened simultaneously, we're still okay.
+object Test {
+ locally {
+ 1: AnyRef
+ }
+
+ locally {
+ // before this test case was added and ContextErrors was tweaked, this
+ // emitted: "Note that Any extends Any, not AnyRef."
+ (null: Any): AnyRef
+ }
+
+ locally {
+ (0: AnyVal): AnyRef
+ }
+
+ class AV(val a: Int) extends AnyVal
+
+ locally {
+ new AV(0): AnyRef
+ }
+}