summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2014-01-30 13:29:14 -0800
committerAdriaan Moors <adriaan.moors@typesafe.com>2014-01-30 13:29:14 -0800
commit50f38393af6d5aee3739cc73fdd5c7d22361390a (patch)
tree795166dc94035a5d9bfa608a5d3cd2c9a10cd7d2
parent0e578e693196f93b1ba4f972a2c96d468bef464a (diff)
parent327eea839e97e1d7cac92aa9cd61e3338d12cb12 (diff)
downloadscala-50f38393af6d5aee3739cc73fdd5c7d22361390a.tar.gz
scala-50f38393af6d5aee3739cc73fdd5c7d22361390a.tar.bz2
scala-50f38393af6d5aee3739cc73fdd5c7d22361390a.zip
Merge pull request #3416 from retronym/topic/any-val-implicit
Prohibit views targeting AnyVal
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala21
-rw-r--r--test/files/neg/no-implicit-to-anyref-any-val.check34
-rw-r--r--test/files/neg/no-implicit-to-anyref-any-val.scala (renamed from test/files/neg/no-implicit-to-anyref.scala)4
-rw-r--r--test/files/neg/no-implicit-to-anyref.check22
-rw-r--r--test/files/pos/implicit-anyval-2.10.flags1
-rw-r--r--test/files/pos/implicit-anyval-2.10.scala3
6 files changed, 54 insertions, 31 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 91321d4700..847211945c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -137,10 +137,6 @@ trait Implicits {
private val improvesCache = perRunCaches.newMap[(ImplicitInfo, ImplicitInfo), Boolean]()
private val implicitSearchId = { var id = 1 ; () => try id finally id += 1 }
- private def isInvalidConversionTarget(tpe: Type): Boolean = tpe match {
- case Function1(_, out) => AnyRefClass.tpe <:< out
- case _ => false
- }
private def isInvalidConversionSource(tpe: Type): Boolean = tpe match {
case Function1(in, _) => in <:< NullClass.tpe
case _ => false
@@ -629,7 +625,8 @@ trait Implicits {
// for instance, if we have `class C[T]` and `implicit def conv[T: Numeric](c: C[T]) = ???`
// then Scaladoc will give us something of type `C[T]`, and it would like to know
// that `conv` is potentially available under such and such conditions
- case tree if isImplicitMethodType(tree.tpe) && !isScalaDoc => applyImplicitArgs(tree)
+ case tree if isImplicitMethodType(tree.tpe) && !isScalaDoc =>
+ applyImplicitArgs(tree)
case tree => tree
}
case _ => fallback
@@ -1361,11 +1358,17 @@ trait Implicits {
if (context.ambiguousErrors)
context.issueAmbiguousError(AmbiguousImplicitTypeError(tree, msg))
}
- if (isInvalidConversionTarget(pt)) {
- maybeInvalidConversionError("the result type of an implicit conversion must be more specific than AnyRef")
- result = SearchFailure
+ pt match {
+ case Function1(_, out) =>
+ def prohibit(sym: Symbol) = if (sym.tpe <:< out) {
+ maybeInvalidConversionError(s"the result type of an implicit conversion must be more specific than ${sym.name}")
+ result = SearchFailure
+ }
+ prohibit(AnyRefClass)
+ if (settings.isScala211) prohibit(AnyValClass)
+ case _ => false
}
- else if (settings.isScala211 && isInvalidConversionSource(pt)) {
+ if (settings.isScala211 && isInvalidConversionSource(pt)) {
maybeInvalidConversionError("an expression of type Null is ineligible for implicit conversion")
result = SearchFailure
}
diff --git a/test/files/neg/no-implicit-to-anyref-any-val.check b/test/files/neg/no-implicit-to-anyref-any-val.check
new file mode 100644
index 0000000000..5953e1bd6d
--- /dev/null
+++ b/test/files/neg/no-implicit-to-anyref-any-val.check
@@ -0,0 +1,34 @@
+no-implicit-to-anyref-any-val.scala:11: error: the result type of an implicit conversion must be more specific than AnyRef
+ 1: AnyRef
+ ^
+no-implicit-to-anyref-any-val.scala:17: error: type mismatch;
+ found : Any
+ required: AnyRef
+ (null: Any): AnyRef
+ ^
+no-implicit-to-anyref-any-val.scala:21: error: type mismatch;
+ found : AnyVal
+ required: AnyRef
+ (0: AnyVal): AnyRef
+ ^
+no-implicit-to-anyref-any-val.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
+ ^
+no-implicit-to-anyref-any-val.scala:30: error: the result type of an implicit conversion must be more specific than AnyVal
+ "": AnyVal
+ ^
+no-implicit-to-anyref-any-val.scala:32: error: type mismatch;
+ found : Object
+ required: AnyVal
+Note that implicit conversions are not applicable because they are ambiguous:
+ both method ArrowAssoc in object Predef of type [A](self: A)ArrowAssoc[A]
+ and method Ensuring in object Predef of type [A](self: A)Ensuring[A]
+ are possible conversion functions from Object to AnyVal
+ new Object() : AnyVal
+ ^
+6 errors found
diff --git a/test/files/neg/no-implicit-to-anyref.scala b/test/files/neg/no-implicit-to-anyref-any-val.scala
index 3e3d373e38..f5daf541af 100644
--- a/test/files/neg/no-implicit-to-anyref.scala
+++ b/test/files/neg/no-implicit-to-anyref-any-val.scala
@@ -26,4 +26,8 @@ object Test {
locally {
new AV(0): AnyRef
}
+
+ "": AnyVal
+
+ new Object() : AnyVal
}
diff --git a/test/files/neg/no-implicit-to-anyref.check b/test/files/neg/no-implicit-to-anyref.check
deleted file mode 100644
index fe417ad8b0..0000000000
--- a/test/files/neg/no-implicit-to-anyref.check
+++ /dev/null
@@ -1,22 +0,0 @@
-no-implicit-to-anyref.scala:11: error: the result type of an implicit conversion must be more specific than AnyRef
- 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/pos/implicit-anyval-2.10.flags b/test/files/pos/implicit-anyval-2.10.flags
new file mode 100644
index 0000000000..94c8056747
--- /dev/null
+++ b/test/files/pos/implicit-anyval-2.10.flags
@@ -0,0 +1 @@
+-Xsource:2.10
diff --git a/test/files/pos/implicit-anyval-2.10.scala b/test/files/pos/implicit-anyval-2.10.scala
new file mode 100644
index 0000000000..3082af73b8
--- /dev/null
+++ b/test/files/pos/implicit-anyval-2.10.scala
@@ -0,0 +1,3 @@
+object Test {
+ "": AnyVal // newly prohibited in 2.11, allowed under -Xsourse:2.10
+} \ No newline at end of file