summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2017-02-24 09:37:20 +1000
committerAdriaan Moors <adriaan@lightbend.com>2017-03-02 15:34:47 -0800
commit849d09b9e10d025df7f91494315f927f68bc9dd6 (patch)
tree9879307a770b049cde9c21db75e0ab0be053beb4
parent78d917393ea03ef94f892549f87cbc2cabba8ac6 (diff)
downloadscala-849d09b9e10d025df7f91494315f927f68bc9dd6.tar.gz
scala-849d09b9e10d025df7f91494315f927f68bc9dd6.tar.bz2
scala-849d09b9e10d025df7f91494315f927f68bc9dd6.zip
Test case for SI-10206
Implicit search implements a restriction that the target type for an implicit view should be more specific that AnyRef or AnyVal. scala> def foo(s: String): AnyVal = s <console>:12: error: the result type of an implicit conversion must be more specific than AnyVal def foo(s: String): AnyVal = s ^ Without this, an implicit value classes over `String` would be applied, which is unlikely to be what was intended. Implicit views are implemented as an implicit search for a function type with a structural type as its result. This structural type is created with: scala> val schema = analyzer.HasMethodMatching.apply(TermName("clone"), Nil, WildcardType) schema: $r.intp.global.analyzer.global.Type = ?{def clone(): ?} The quirk arises when, as above, we're seeking a member with the same name as a member of AnyRef. AnyRef is seen to be a subtype of the result type: scala> AnyRefClass.tpe <:< schema res23: Boolean = true Which leads to the implicit in the test case being disqualified. The typer opts to report the error about the inapplicability of the inherited clone method, so we don't even know why the implicit was discarded.
-rw-r--r--test/files/pos/t10206.scala15
1 files changed, 15 insertions, 0 deletions
diff --git a/test/files/pos/t10206.scala b/test/files/pos/t10206.scala
new file mode 100644
index 0000000000..3ddd1ea2fd
--- /dev/null
+++ b/test/files/pos/t10206.scala
@@ -0,0 +1,15 @@
+class Foo(val bar: String)
+
+object Foo {
+ implicit class Enrich(foo: Foo) {
+ def clone(x: Int, y: Int): Int = x + y
+ }
+}
+
+object Main extends App {
+ val foo = new Foo("hello")
+ println(foo.clone(1, 2)) // <- does not compile
+ // the implicit view was being disqualified because a new check in the compiler
+ // that implicit views must not target Any or AnyRef considered an implicit search
+ // for `foo.type => ?{def clone: ?}` to targeted AnyRef.
+}