From 7144b4990f2c90002286ebf31a395c36024adcd2 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 8 Mar 2010 13:40:32 +0000 Subject: Closes #3115. Reviw by rytz --- .../scala/tools/nsc/typechecker/Namers.scala | 56 +++++++++++++--------- test/files/neg/t3006.check | 6 +++ test/files/neg/t3006.scala | 10 ++++ 3 files changed, 50 insertions(+), 22 deletions(-) create mode 100644 test/files/neg/t3006.check create mode 100755 test/files/neg/t3006.scala 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") + +} -- cgit v1.2.3