summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala22
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala10
-rw-r--r--test/files/run/names-defaults.scala7
5 files changed, 28 insertions, 24 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index eb3313a71c..44b70a602c 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -96,11 +96,16 @@ trait Symbols {
private var rawannots: List[AnnotationInfoBase] = Nil
+ /* Used in namer to check wether annotations were already assigned or not */
+ def rawAnnotations:List[AnnotationInfoBase] = rawannots
+
/** After the typer phase (before, look at the definition's Modifiers), contains
* the annotations attached to member a definition (class, method, type, field).
*/
def annotations: List[AnnotationInfo] = {
- val annots1 = rawannots map {
+ // .initialize: the type completer of the symbol parses the annotations,
+ // see "def typeSig" in Namers
+ val annots1 = initialize.rawannots map {
case LazyAnnotationInfo(annot) => annot()
case a @ AnnotationInfo(_, _, _) => a
} filter { a => !a.atp.isError }
@@ -114,7 +119,7 @@ trait Symbols {
}
def addAnnotation(annot: AnnotationInfo): this.type =
- setAnnotations(annot :: this.annotations)
+ setAnnotations(annot :: this.rawannots)
/** Does this symbol have an annotation of the given class? */
def hasAnnotation(cls: Symbol) = annotations exists { _.atp.typeSymbol == cls }
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 5f490592f5..20061515c8 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -1060,7 +1060,9 @@ trait Namers { self: Analyzer =>
// 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
- if (annotated.annotations.isEmpty) tree match {
+ // typeSig might be called multiple times, e.g. on a ValDef: val, getter, setter
+ // parse the annotations only once.
+ if (annotated.rawAnnotations.isEmpty) tree match {
case defn: MemberDef =>
val ainfos = defn.mods.annotations filter { _ != null } map { ann =>
// need to be lazy, #1782
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index 5ccc22f4dd..b104bed2c7 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -165,29 +165,19 @@ trait NamesDefaults { self: Analyzer =>
// constructor calls
case Select(New(TypeTree()), _) if isConstr =>
- val module = baseFun.symbol.owner.linkedModuleOfClass
- val defaultQual = if (module == NoSymbol) None
-
- else Some(gen.mkAttributedRef(module))
- blockWithoutQualifier(baseFun1, defaultQual)
+ blockWithoutQualifier(baseFun1, None)
case Select(New(Ident(_)), _) if isConstr =>
blockWithoutQualifier(baseFun1, None)
case Select(nev @ New(sel @ Select(qual, typeName)), constr) if isConstr =>
+ // #2057
val module = baseFun.symbol.owner.linkedModuleOfClass
val defaultQual = if (module == NoSymbol) None
- else Some(gen.mkAttributedRef(module))
- if (treeInfo.isPureExpr(qual)) {
- blockWithoutQualifier(baseFun1, defaultQual)
- } else {
- val fun: Symbol => Tree =
- sym => treeCopy.Select(baseFun1,
- treeCopy.New(nev,
- treeCopy.Select(sel, gen.mkAttributedRef(sym), typeName)),
- constr)
- blockWithQualifier(qual, fun, sym => defaultQual)
- }
+ else Some(gen.mkAttributedSelect(qual.duplicate, module))
+ // in `new q.C()', q is always stable
+ assert(treeInfo.isPureExpr(qual), qual)
+ blockWithoutQualifier(baseFun1, defaultQual)
// other method calls
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 2e8032d10a..2bd8ae2041 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1255,7 +1255,7 @@ trait Typers { self: Analyzer =>
error(getter.pos, getter+" is defined twice")
// todo: potentially dangerous not to duplicate the trees and clone the symbols / types.
- getter.setAnnotations(value.initialize.annotations)
+ getter.setAnnotations(value.annotations)
if (value.hasFlag(LAZY)) List(stat)
else {
@@ -2340,12 +2340,12 @@ trait Typers { self: Analyzer =>
if (typedFun.isErroneous) annotationError
else if (annType.typeSymbol isNonBottomSubClass ClassfileAnnotationClass) {
- // annotation to be saved as java annotation
+ // annotation to be saved as java classfile annotation
val isJava = typedFun.symbol.owner.hasFlag(JAVA)
if (!annType.typeSymbol.isNonBottomSubClass(annClass)) {
error(tpt.pos, "expected annotation of type "+ annClass.tpe +", found "+ annType)
} else if (argss.length > 1) {
- error(ann.pos, "multiple argument lists on java annotation")
+ error(ann.pos, "multiple argument lists on classfile annotation")
} else {
val args =
if (argss.head.length == 1 && !isNamed(argss.head.head))
@@ -2372,7 +2372,7 @@ trait Typers { self: Analyzer =>
(sym.name, annArg)
}
case arg =>
- error(arg.pos, "java annotation arguments have to be supplied as named arguments")
+ error(arg.pos, "classfile annotation arguments have to be supplied as named arguments")
(nme.ERROR, None)
}
@@ -2386,7 +2386,7 @@ trait Typers { self: Analyzer =>
else AnnotationInfo(annType, List(), nvPairs map {p => (p._1, p._2.get)})
}
} else if (requireJava) {
- error(ann.pos, "nested java annotations must be defined in java; found: "+ annType)
+ error(ann.pos, "nested classfile annotations must be defined in java; found: "+ annType)
} else {
val typedAnn = if (selfsym == NoSymbol) {
typed(ann, mode, annClass.tpe)
diff --git a/test/files/run/names-defaults.scala b/test/files/run/names-defaults.scala
index 482c4f2f7b..c016a98e1a 100644
--- a/test/files/run/names-defaults.scala
+++ b/test/files/run/names-defaults.scala
@@ -181,6 +181,13 @@ object Test extends Application {
println(b11.copy()())
+
+ // bug #2057
+ class O { class I(x: Int = 1) }
+ class U extends O { val f = new I() }
+
+
+
// DEFINITIONS
def test1(a: Int, b: String) = println(a +": "+ b)
def test2(u: Int, v: Int)(k: String, l: Int) = println(l +": "+ k +", "+ (u + v))