summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2014-01-27 10:29:28 +0100
committerJason Zaugg <jzaugg@gmail.com>2014-01-27 10:44:48 +0100
commit327eea839e97e1d7cac92aa9cd61e3338d12cb12 (patch)
tree27c96fc40658a947216b61fab6b6da4956c6cdbd /src
parenta5b0fc49e517d1c63d22f9909ac9bed0552ed466 (diff)
downloadscala-327eea839e97e1d7cac92aa9cd61e3338d12cb12.tar.gz
scala-327eea839e97e1d7cac92aa9cd61e3338d12cb12.tar.bz2
scala-327eea839e97e1d7cac92aa9cd61e3338d12cb12.zip
Prohibit views targeting AnyVal
Library changes in Scala 2.10 mean that we are left with the unfortunate situation of admitting: scala> "": AnyVal res0: AnyVal = We already have explicit checks in place to prevent views targeting `AnyRef`. This commit balances this out by prohibiting `AnyVal`, as well. The enclosed test shows that this case is now prevented. If multiple implicits views are applicable, the ambiguity error is still raised; these check comes right at the end. Maybe that ought to be changed, but I don't think it matters too much. I've also disabled this prohibition under -Xsource:2.10.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala21
1 files changed, 12 insertions, 9 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 06a1e21e8b..9564d6a632 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
}