summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala56
-rw-r--r--test/files/neg/t3006.check6
-rwxr-xr-xtest/files/neg/t3006.scala10
3 files changed, 50 insertions, 22 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index bd0dc448fb..aff6aa86e6 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -1107,30 +1107,42 @@ trait Namers { self: Analyzer =>
caseClassCopyMeth(cdef) foreach (namer.enterSyntheticSym(_))
}
+
def typeSig(tree: Tree): Type = {
- val sym: Symbol = tree.symbol
- // For definitions, transform Annotation trees to AnnotationInfos, assign
- // them to the sym's annotations. Type annotations: see Typer.typedAnnotated
-
- // We have to parse definition annotatinos here (not in the typer when traversing
- // the MemberDef tree): the typer looks at annotations of certain symbols; if
- // they were added only in typer, depending on the compilation order, they would
- // be visible or not
- val annotated = if (sym.isModule) sym.moduleClass else sym
- // typeSig might be called multiple times, e.g. on a ValDef: val, getter, setter
- // parse the annotations only once.
- if (!annotated.isInitialized) tree match {
- case defn: MemberDef =>
- val ainfos = defn.mods.annotations filter { _ != null } map { ann =>
- // need to be lazy, #1782
- LazyAnnotationInfo(() => typer.typedAnnotation(ann))
- }
- if (!ainfos.isEmpty)
- annotated.setAnnotations(ainfos)
- if (annotated.isTypeSkolem)
- annotated.deSkolemize.setAnnotations(ainfos)
- case _ =>
+
+ /** For definitions, transform Annotation trees to AnnotationInfos, assign
+ * them to the sym's annotations. Type annotations: see Typer.typedAnnotated
+ * We have to parse definition annotatinos here (not in the typer when traversing
+ * the MemberDef tree): the typer looks at annotations of certain symbols; if
+ * they were added only in typer, depending on the compilation order, they would
+ * be visible or not
+ */
+ def annotate(annotated: Symbol) = {
+ // typeSig might be called multiple times, e.g. on a ValDef: val, getter, setter
+ // parse the annotations only once.
+ if (!annotated.isInitialized) tree match {
+ case defn: MemberDef =>
+ val ainfos = defn.mods.annotations filter { _ != null } map { ann =>
+ // need to be lazy, #1782
+ LazyAnnotationInfo(() => typer.typedAnnotation(ann))
+ }
+ if (!ainfos.isEmpty)
+ annotated.setAnnotations(ainfos)
+ if (annotated.isTypeSkolem)
+ annotated.deSkolemize.setAnnotations(ainfos)
+ case _ =>
+ }
}
+
+ val sym: Symbol = tree.symbol
+
+ // @Lukas: I am not sure this is the right way to do things.
+ // We used to only decorate the module class with annotations, which is
+ // clearly wrong. Now we decorate both the class and the object.
+ // But maybe some annotations are only meant for one of these but not for the other?
+ annotate(sym)
+ if (sym.isModule) annotate(sym.moduleClass)
+
val result =
try {
tree match {
diff --git a/test/files/neg/t3006.check b/test/files/neg/t3006.check
new file mode 100644
index 0000000000..9a90d32b28
--- /dev/null
+++ b/test/files/neg/t3006.check
@@ -0,0 +1,6 @@
+t3006.scala:8: error: type mismatch;
+ found : java.lang.String("H")
+ required: Int
+ println(A(3) + "H")
+ ^
+one error found
diff --git a/test/files/neg/t3006.scala b/test/files/neg/t3006.scala
new file mode 100755
index 0000000000..f476c1717d
--- /dev/null
+++ b/test/files/neg/t3006.scala
@@ -0,0 +1,10 @@
+object Test extends Application {
+ case class A(x: Int);
+
+ class Foo(a: A) { println("Foo created!"); def +(x: Int) = new A(this.a.x + x); }
+
+ implicit def aToFoo(x: A) = new Foo(x);
+
+ println(A(3) + "H")
+
+}