summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2016-11-18 16:04:49 +1000
committerJason Zaugg <jzaugg@gmail.com>2016-11-18 18:17:30 +1000
commit944db65d63e12ae4e0135999cdc8b9f2695f4102 (patch)
tree0076ec04446f6eefc3c18dc0f079d6bd84761e68 /test
parent73678d4dafe250f0b38df2e953787af26b1a4ee3 (diff)
downloadscala-944db65d63e12ae4e0135999cdc8b9f2695f4102.tar.gz
scala-944db65d63e12ae4e0135999cdc8b9f2695f4102.tar.bz2
scala-944db65d63e12ae4e0135999cdc8b9f2695f4102.zip
SI-10066 Fix crash in erroneous code with implicits, dynamic
The compiler support in the typechecker for `scala.Dynamic` is very particular about the `Context` in which it is typechecked. It looks at the `tree` in the enclosing context to find the expression immediately enclosing the dynamic selection. See the logic in `dyna::mkInvoke` for the details. This commit substitutes the result of `resetAttrs` into the tree of the typer context before continuing with typechecking.
Diffstat (limited to 'test')
-rw-r--r--test/files/neg/t10066.check7
-rw-r--r--test/files/neg/t10066.scala38
-rw-r--r--test/files/pos/t10066.scala38
3 files changed, 83 insertions, 0 deletions
diff --git a/test/files/neg/t10066.check b/test/files/neg/t10066.check
new file mode 100644
index 0000000000..3555205d83
--- /dev/null
+++ b/test/files/neg/t10066.check
@@ -0,0 +1,7 @@
+t10066.scala:33: error: could not find implicit value for parameter extractor: dynamicrash.Extractor[String]
+ println(storage.foo[String])
+ ^
+t10066.scala:37: error: could not find implicit value for parameter extractor: dynamicrash.Extractor[A]
+ println(storage.foo)
+ ^
+two errors found
diff --git a/test/files/neg/t10066.scala b/test/files/neg/t10066.scala
new file mode 100644
index 0000000000..ef52f333dd
--- /dev/null
+++ b/test/files/neg/t10066.scala
@@ -0,0 +1,38 @@
+package dynamicrash
+
+import scala.language.dynamics
+
+class Config
+
+trait Extractor[A] {
+ def extract(config: Config, name: String): A
+}
+
+object Extractor {
+ // note missing "implicit"
+ val stringExtractor = new Extractor[String] {
+ override def extract(config: Config, name: String): String = ???
+ }
+}
+
+class Workspace extends Dynamic {
+ val config: Config = new Config
+
+ def selectDynamic[A](name: String)(implicit extractor: Extractor[A]): A =
+ extractor.extract(config, name)
+}
+
+object Main {
+ val storage = new Workspace
+
+ // this line works fine
+ // val a = storage.foo
+
+ // this line crashes the compiler ("head of empty list")
+ // in ContextErrors$InferencerContextErrors$InferErrorGen$.NotWithinBoundsErrorMessage
+ println(storage.foo[String])
+
+ // this line crashes the compiler in different way ("unknown type")
+ // in the backend, warning: an unexpected type representation reached the compiler backend while compiling Test.scala: <error>
+ println(storage.foo)
+}
diff --git a/test/files/pos/t10066.scala b/test/files/pos/t10066.scala
new file mode 100644
index 0000000000..bef85cb08c
--- /dev/null
+++ b/test/files/pos/t10066.scala
@@ -0,0 +1,38 @@
+package dynamicrash
+
+import scala.language.dynamics
+
+class Config
+
+trait Extractor[A] {
+ def extract(config: Config, name: String): A
+}
+
+object Extractor {
+ // this has "implicit", unlike the corresponding neg test
+ implicit val stringExtractor = new Extractor[String] {
+ override def extract(config: Config, name: String): String = ???
+ }
+}
+
+class Workspace extends Dynamic {
+ val config: Config = new Config
+
+ def selectDynamic[A](name: String)(implicit extractor: Extractor[A]): A =
+ extractor.extract(config, name)
+}
+
+object Main {
+ val storage = new Workspace
+
+ // this line works fine
+ // val a = storage.foo
+
+ // this line crashes the compiler ("head of empty list")
+ // in ContextErrors$InferencerContextErrors$InferErrorGen$.NotWithinBoundsErrorMessage
+ println(storage.foo[String])
+
+ // this line crashes the compiler in different way ("unknown type")
+ // in the backend, warning: an unexpected type representation reached the compiler backend while compiling Test.scala: <error>
+ println(storage.foo)
+}