summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala4
-rw-r--r--test/files/neg/t5892.check17
-rw-r--r--test/files/neg/t5892.scala25
-rw-r--r--test/files/pos/t5892.scala5
5 files changed, 55 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index bcf529ecd2..805f60ba87 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -636,6 +636,12 @@ trait Contexts { self: Analyzer =>
collect(imp.tree.selectors)
}
+ /* SI-5892 / SI-4270: `implicitss` can return results which are not accessible at the
+ * point where implicit search is triggered. Example: implicits in (annotations of)
+ * class type parameters (SI-5892). The `context.owner` is the class symbol, therefore
+ * `implicitss` will return implicit conversions defined inside the class. These are
+ * filtered out later by `eligibleInfos` (SI-4270 / 9129cfe9), as they don't type-check.
+ */
def implicitss: List[List[ImplicitInfo]] = {
if (implicitsRunId != currentRunId) {
implicitsRunId = currentRunId
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 9580cd5676..fa34bce82c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -1212,8 +1212,8 @@ trait Namers extends MethodSynthesis {
if (!annotated.isInitialized) tree match {
case defn: MemberDef =>
val ainfos = defn.mods.annotations filterNot (_ eq null) map { ann =>
- // need to be lazy, #1782
- AnnotationInfo lazily (typer typedAnnotation ann)
+ // need to be lazy, #1782. beforeTyper to allow inferView in annotation args, SI-5892.
+ AnnotationInfo lazily beforeTyper(typer typedAnnotation ann)
}
if (ainfos.nonEmpty) {
annotated setAnnotations ainfos
diff --git a/test/files/neg/t5892.check b/test/files/neg/t5892.check
new file mode 100644
index 0000000000..839bf9de23
--- /dev/null
+++ b/test/files/neg/t5892.check
@@ -0,0 +1,17 @@
+t5892.scala:5: error: type mismatch;
+ found : Boolean(false)
+ required: String
+class C[@annot(false) X] {
+ ^
+t5892.scala:9: error: not found: value b2s
+class D[@annot(b2s(false)) X] {
+ ^
+t5892.scala:13: error: type mismatch;
+ found : Boolean(false)
+ required: String
+@annot(false) class E {
+ ^
+t5892.scala:17: error: not found: value b2s
+@annot(b2s(false)) class F {
+ ^
+four errors found
diff --git a/test/files/neg/t5892.scala b/test/files/neg/t5892.scala
new file mode 100644
index 0000000000..5e3b2f313e
--- /dev/null
+++ b/test/files/neg/t5892.scala
@@ -0,0 +1,25 @@
+import language.implicitConversions
+
+class annot(a: String) extends annotation.StaticAnnotation
+
+class C[@annot(false) X] {
+ implicit def b2s(b: Boolean): String = ""
+}
+
+class D[@annot(b2s(false)) X] {
+ implicit def b2s(b: Boolean): String = ""
+}
+
+@annot(false) class E {
+ implicit def b2s(b: Boolean): String = ""
+}
+
+@annot(b2s(false)) class F {
+ implicit def b2s(b: Boolean): String = ""
+}
+
+object T {
+ implicit def b2s(b: Boolean): String = ""
+ @annot(false) val x = 0
+ @annot(b2s(false)) val y = 0
+}
diff --git a/test/files/pos/t5892.scala b/test/files/pos/t5892.scala
new file mode 100644
index 0000000000..241e59860a
--- /dev/null
+++ b/test/files/pos/t5892.scala
@@ -0,0 +1,5 @@
+class foo(a: String) extends annotation.StaticAnnotation
+object o {
+ implicit def i2s(i: Int) = ""
+ @foo(1: String) def blerg { }
+}