summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2013-02-07 14:18:37 -0800
committerAdriaan Moors <adriaan.moors@typesafe.com>2013-02-07 14:18:37 -0800
commit33608ffb282e3b844b28143d9f3588e57c20c7aa (patch)
treedeff36c8e4253461a56d86d1ca5f93a02c657f40
parentdb02585dafdc509de289177826df2eed8eb38326 (diff)
parent1f838edb02f6e5ced6641504a96cca3ec4c1fa7a (diff)
downloadscala-33608ffb282e3b844b28143d9f3588e57c20c7aa.tar.gz
scala-33608ffb282e3b844b28143d9f3588e57c20c7aa.tar.bz2
scala-33608ffb282e3b844b28143d9f3588e57c20c7aa.zip
Merge pull request #2068 from scalamacros/ticket/7064
[nomaster] SI-7064 Reflection: forward compat for 2.10.1
-rw-r--r--src/compiler/scala/reflect/reify/codegen/GenTrees.scala4
-rw-r--r--src/compiler/scala/reflect/reify/codegen/GenUtils.scala3
-rw-r--r--src/compiler/scala/tools/nsc/ast/Positions.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala29
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala66
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala22
-rw-r--r--src/compiler/scala/tools/nsc/interactive/RangePositions.scala6
-rw-r--r--src/compiler/scala/tools/nsc/javac/JavaParsers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala13
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala24
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala377
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Unapplies.scala2
-rw-r--r--src/compiler/scala/tools/reflect/ToolBoxFactory.scala1
-rw-r--r--src/reflect/scala/reflect/api/BuildUtils.scala2
-rw-r--r--src/reflect/scala/reflect/api/Trees.scala27
-rw-r--r--src/reflect/scala/reflect/internal/BuildUtils.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Importers.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Positions.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Printers.scala6
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala1
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala7
-rw-r--r--src/reflect/scala/reflect/internal/Trees.scala32
-rw-r--r--src/reflect/scala/reflect/macros/Attachments.scala2
-rw-r--r--test/files/neg/anyval-anyref-parent.check2
-rw-r--r--test/files/neg/cyclics-import.check11
-rw-r--r--test/files/neg/names-defaults-neg.check2
-rw-r--r--test/files/neg/protected-constructors.check5
-rw-r--r--test/files/neg/t2148.check2
-rw-r--r--test/files/neg/t409.check4
-rw-r--r--test/files/neg/t5529.check5
-rw-r--r--test/files/neg/t5696.check2
-rw-r--r--test/files/neg/t667.check4
-rw-r--r--test/files/neg/t877.check4
-rw-r--r--test/files/run/analyzerPlugins.check35
-rw-r--r--test/files/run/t5064.check6
-rw-r--r--test/files/run/t5603.check4
-rw-r--r--test/files/run/t6288.check12
-rw-r--r--test/files/run/t6288b-jump-position.check6
-rw-r--r--test/files/run/t7064-old-style-supercalls.check1
-rw-r--r--test/files/run/t7064-old-style-supercalls.scala48
44 files changed, 333 insertions, 470 deletions
diff --git a/src/compiler/scala/reflect/reify/codegen/GenTrees.scala b/src/compiler/scala/reflect/reify/codegen/GenTrees.scala
index 31974b5b76..949f7f1799 100644
--- a/src/compiler/scala/reflect/reify/codegen/GenTrees.scala
+++ b/src/compiler/scala/reflect/reify/codegen/GenTrees.scala
@@ -45,9 +45,7 @@ trait GenTrees {
case global.EmptyTree =>
reifyMirrorObject(EmptyTree)
case global.emptyValDef =>
- mirrorSelect(nme.emptyValDef)
- case global.pendingSuperCall =>
- mirrorSelect(nme.pendingSuperCall)
+ mirrorBuildSelect(nme.emptyValDef)
case FreeDef(_, _, _, _, _) =>
reifyNestedFreeDef(tree)
case FreeRef(_, _) =>
diff --git a/src/compiler/scala/reflect/reify/codegen/GenUtils.scala b/src/compiler/scala/reflect/reify/codegen/GenUtils.scala
index 21db93d8f5..49877b4286 100644
--- a/src/compiler/scala/reflect/reify/codegen/GenUtils.scala
+++ b/src/compiler/scala/reflect/reify/codegen/GenUtils.scala
@@ -34,6 +34,9 @@ trait GenUtils {
def mirrorSelect(name: String): Tree =
termPath(nme.UNIVERSE_PREFIX + name)
+ def mirrorBuildSelect(name: String): Tree =
+ termPath(nme.UNIVERSE_BUILD_PREFIX + name)
+
def mirrorMirrorSelect(name: String): Tree =
termPath(nme.MIRROR_PREFIX + name)
diff --git a/src/compiler/scala/tools/nsc/ast/Positions.scala b/src/compiler/scala/tools/nsc/ast/Positions.scala
index 49569f5e05..d8fb632f73 100644
--- a/src/compiler/scala/tools/nsc/ast/Positions.scala
+++ b/src/compiler/scala/tools/nsc/ast/Positions.scala
@@ -20,7 +20,7 @@ trait Positions extends scala.reflect.internal.Positions {
// When we prune due to encountering a position, traverse the
// pruned children so we can warn about those lacking positions.
t.children foreach { c =>
- if (!c.canHaveAttrs) ()
+ if ((c eq EmptyTree) || (c eq emptyValDef)) ()
else if (c.pos == NoPosition) {
reporter.warning(t.pos, " Positioned tree has unpositioned child in phase " + globalPhase)
inform("parent: " + treeSymStatus(t))
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index 96146b7343..99b82d9746 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -58,7 +58,7 @@ abstract class TreeGen extends scala.reflect.internal.TreeGen with TreeDSL {
def mkUnchecked(expr: Tree): Tree = atPos(expr.pos) {
// This can't be "Annotated(New(UncheckedClass), expr)" because annotations
// are very picky about things and it crashes the compiler with "unexpected new".
- Annotated(New(scalaDot(UncheckedClass.name), Nil), expr)
+ Annotated(New(scalaDot(UncheckedClass.name), ListOfNil), expr)
}
// if it's a Match, mark the selector unchecked; otherwise nothing.
def mkUncheckedMatch(tree: Tree) = tree match {
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index def1198dae..2ad762fd55 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -65,13 +65,6 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
// --- factory methods ----------------------------------------------------------
- /** Factory method for a primary constructor super call `super.<init>(args_1)...(args_n)`
- */
- def PrimarySuperCall(argss: List[List[Tree]]): Tree = argss match {
- case Nil => Apply(gen.mkSuperSelect, Nil)
- case xs :: rest => rest.foldLeft(Apply(gen.mkSuperSelect, xs): Tree)(Apply.apply)
- }
-
/** Generates a template with constructor corresponding to
*
* constrmods (vparams1_) ... (vparams_n) preSuper { presupers }
@@ -89,7 +82,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
* body
* }
*/
- def Template(parents: List[Tree], self: ValDef, constrMods: Modifiers, vparamss: List[List[ValDef]], body: List[Tree], superPos: Position): Template = {
+ def Template(parents: List[Tree], self: ValDef, constrMods: Modifiers, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree], superPos: Position): Template = {
/* Add constructor to template */
// create parameters for <init> as synthetic trees.
@@ -124,16 +117,9 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
if (vparamss1.isEmpty || !vparamss1.head.isEmpty && vparamss1.head.head.mods.isImplicit)
vparamss1 = List() :: vparamss1;
val superRef: Tree = atPos(superPos)(gen.mkSuperSelect)
- val superCall = pendingSuperCall // we can't know in advance which of the parents will end up as a superclass
- // this requires knowing which of the parents is a type macro and which is not
- // and that's something that cannot be found out before typer
- // (the type macros aren't in the trunk yet, but there is a plan for them to land there soon)
- // this means that we don't know what will be the arguments of the super call
- // therefore here we emit a dummy which gets populated when the template is named and typechecked
+ val superCall = (superRef /: argss) (Apply.apply)
List(
- // TODO: previously this was `wrappingPos(superPos, lvdefs ::: argss.flatten)`
- // is it going to be a problem that we can no longer include the `argss`?
- atPos(wrappingPos(superPos, lvdefs)) (
+ atPos(wrappingPos(superPos, lvdefs ::: argss.flatten)) (
DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), Literal(Constant())))))
}
}
@@ -151,10 +137,11 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
* @param constrMods the modifiers for the class constructor, i.e. as in `class C private (...)`
* @param vparamss the value parameters -- if they have symbols they
* should be owned by `sym`
+ * @param argss the supercall arguments
* @param body the template statements without primary constructor
* and value parameter fields.
*/
- def ClassDef(sym: Symbol, constrMods: Modifiers, vparamss: List[List[ValDef]], body: List[Tree], superPos: Position): ClassDef = {
+ def ClassDef(sym: Symbol, constrMods: Modifiers, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree], superPos: Position): ClassDef = {
// "if they have symbols they should be owned by `sym`"
assert(
mforall(vparamss)(p => (p.symbol eq NoSymbol) || (p.symbol.owner == sym)),
@@ -164,7 +151,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
ClassDef(sym,
Template(sym.info.parents map TypeTree,
if (sym.thisSym == sym || phase.erasedTypes) emptyValDef else ValDef(sym.thisSym),
- constrMods, vparamss, body, superPos))
+ constrMods, vparamss, argss, body, superPos))
}
// --- subcomponents --------------------------------------------------
@@ -337,8 +324,6 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
else
super.transform {
tree match {
- case tree if !tree.canHaveAttrs =>
- tree
case tpt: TypeTree =>
if (tpt.original != null)
transform(tpt.original)
@@ -352,6 +337,8 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
transform(fn)
case This(_) if tree.symbol != null && tree.symbol.isPackageClass =>
tree
+ case EmptyTree =>
+ tree
case _ =>
val dupl = tree.duplicate
if (tree.hasSymbol && (!localOnly || (locals contains tree.symbol)) && !(keepLabels && tree.symbol.isLabel))
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index c508e14343..6f79f639b9 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -1559,9 +1559,9 @@ self =>
val nstart = in.skipToken()
val npos = r2p(nstart, nstart, in.lastOffset)
val tstart = in.offset
- val (parents, self, stats) = template()
+ val (parents, argss, self, stats) = template(isTrait = false)
val cpos = r2p(tstart, tstart, in.lastOffset max tstart)
- makeNew(parents, self, stats, npos, cpos)
+ makeNew(parents, self, stats, argss, npos, cpos)
case _ =>
syntaxErrorOrIncomplete("illegal start of simple expression", true)
errorTermTree
@@ -2103,7 +2103,7 @@ self =>
def annotationExpr(): Tree = atPos(in.offset) {
val t = exprSimpleType()
if (in.token == LPAREN) New(t, multipleArgumentExprs())
- else New(t, Nil)
+ else New(t, ListOfNil)
}
/* -------- PARAMETERS ------------------------------------------- */
@@ -2739,17 +2739,20 @@ self =>
* TraitParents ::= AnnotType {with AnnotType}
* }}}
*/
- def templateParents(): List[Tree] = {
- val parents = new ListBuffer[Tree]
- def readAppliedParent() = {
- val start = in.offset
- val parent = startAnnotType()
- val argss = if (in.token == LPAREN) multipleArgumentExprs() else Nil
- parents += atPos(start)((parent /: argss)(Apply.apply))
+ def templateParents(isTrait: Boolean): (List[Tree], List[List[Tree]]) = {
+ val parents = new ListBuffer[Tree] += startAnnotType()
+ val argss = (
+ // TODO: the insertion of ListOfNil here is where "new Foo" becomes
+ // indistinguishable from "new Foo()".
+ if (in.token == LPAREN && !isTrait) multipleArgumentExprs()
+ else ListOfNil
+ )
+
+ while (in.token == WITH) {
+ in.nextToken()
+ parents += startAnnotType()
}
- readAppliedParent()
- while (in.token == WITH) { in.nextToken(); readAppliedParent() }
- parents.toList
+ (parents.toList, argss)
}
/** {{{
@@ -2759,12 +2762,12 @@ self =>
* EarlyDef ::= Annotations Modifiers PatDef
* }}}
*/
- def template(): (List[Tree], ValDef, List[Tree]) = {
+ def template(isTrait: Boolean): (List[Tree], List[List[Tree]], ValDef, List[Tree]) = {
newLineOptWhenFollowedBy(LBRACE)
if (in.token == LBRACE) {
// @S: pre template body cannot stub like post body can!
val (self, body) = templateBody(isPre = true)
- if (in.token == WITH && (self eq emptyValDef)) {
+ if (in.token == WITH && self.isEmpty) {
val earlyDefs: List[Tree] = body flatMap {
case vdef @ ValDef(mods, _, _, _) if !mods.isDeferred =>
List(copyValDef(vdef)(mods = mods | Flags.PRESUPER))
@@ -2776,16 +2779,16 @@ self =>
case _ => List()
}
in.nextToken()
- val parents = templateParents()
- val (self1, body1) = templateBodyOpt(parenMeansSyntaxError = false)
- (parents, self1, earlyDefs ::: body1)
+ val (parents, argss) = templateParents(isTrait = isTrait)
+ val (self1, body1) = templateBodyOpt(traitParentSeen = isTrait)
+ (parents, argss, self1, earlyDefs ::: body1)
} else {
- (List(), self, body)
+ (List(), ListOfNil, self, body)
}
} else {
- val parents = templateParents()
- val (self, body) = templateBodyOpt(parenMeansSyntaxError = false)
- (parents, self, body)
+ val (parents, argss) = templateParents(isTrait = isTrait)
+ val (self, body) = templateBodyOpt(traitParentSeen = isTrait)
+ (parents, argss, self, body)
}
}
@@ -2799,15 +2802,15 @@ self =>
* }}}
*/
def templateOpt(mods: Modifiers, name: Name, constrMods: Modifiers, vparamss: List[List[ValDef]], tstart: Int): Template = {
- val (parents0, self, body) = (
+ val (parents0, argss, self, body) = (
if (in.token == EXTENDS || in.token == SUBTYPE && mods.isTrait) {
in.nextToken()
- template()
+ template(isTrait = mods.isTrait)
}
else {
newLineOptWhenFollowedBy(LBRACE)
- val (self, body) = templateBodyOpt(parenMeansSyntaxError = mods.isTrait || name.isTermName)
- (List(), self, body)
+ val (self, body) = templateBodyOpt(traitParentSeen = false)
+ (List(), ListOfNil, self, body)
}
)
def anyrefParents() = {
@@ -2829,7 +2832,7 @@ self =>
if (inScalaRootPackage && ScalaValueClassNames.contains(name))
Template(parents0, self, anyvalConstructor :: body)
else
- Template(anyrefParents, self, constrMods, vparamss, body, o2p(tstart))
+ Template(anyrefParents, self, constrMods, vparamss, argss, body, o2p(tstart))
}
}
@@ -2844,15 +2847,14 @@ self =>
case (self, Nil) => (self, EmptyTree.asList)
case result => result
}
- def templateBodyOpt(parenMeansSyntaxError: Boolean): (ValDef, List[Tree]) = {
+ def templateBodyOpt(traitParentSeen: Boolean): (ValDef, List[Tree]) = {
newLineOptWhenFollowedBy(LBRACE)
if (in.token == LBRACE) {
templateBody(isPre = false)
} else {
- if (in.token == LPAREN) {
- if (parenMeansSyntaxError) syntaxError(s"traits or objects may not have parameters", true)
- else abort("unexpected opening parenthesis")
- }
+ if (in.token == LPAREN)
+ syntaxError((if (traitParentSeen) "parents of traits" else "traits or objects")+
+ " may not have parameters", true)
(emptyValDef, List())
}
}
diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
index ac8ab493e0..7969bb9c20 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
@@ -205,26 +205,20 @@ abstract class TreeBuilder {
*/
def makeAnonymousNew(stats: List[Tree]): Tree = {
val stats1 = if (stats.isEmpty) List(Literal(Constant(()))) else stats
- makeNew(Nil, emptyValDef, stats1, NoPosition, NoPosition)
+ makeNew(Nil, emptyValDef, stats1, ListOfNil, NoPosition, NoPosition)
}
/** Create positioned tree representing an object creation <new parents { stats }
* @param npos the position of the new
* @param cpos the position of the anonymous class starting with parents
*/
- def makeNew(parents: List[Tree], self: ValDef, stats: List[Tree],
+ def makeNew(parents: List[Tree], self: ValDef, stats: List[Tree], argss: List[List[Tree]],
npos: Position, cpos: Position): Tree =
if (parents.isEmpty)
- makeNew(List(scalaAnyRefConstr), self, stats, npos, cpos)
- else if (parents.tail.isEmpty && stats.isEmpty) {
- // `Parsers.template` no longer differentiates tpts and their argss
- // e.g. `C()` will be represented as a single tree Apply(Ident(C), Nil)
- // instead of parents = Ident(C), argss = Nil as before
- // this change works great for things that are actually templates
- // but in this degenerate case we need to perform postprocessing
- val app = treeInfo.dissectApplied(parents.head)
- atPos(npos union cpos) { New(app.callee, app.argss) }
- } else {
+ makeNew(List(scalaAnyRefConstr), self, stats, argss, npos, cpos)
+ else if (parents.tail.isEmpty && stats.isEmpty)
+ atPos(npos union cpos) { New(parents.head, argss) }
+ else {
val x = tpnme.ANON_CLASS_NAME
atPos(npos union cpos) {
Block(
@@ -232,12 +226,12 @@ abstract class TreeBuilder {
atPos(cpos) {
ClassDef(
Modifiers(FINAL), x, Nil,
- Template(parents, self, NoMods, ListOfNil, stats, cpos.focus))
+ Template(parents, self, NoMods, ListOfNil, argss, stats, cpos.focus))
}),
atPos(npos) {
New(
Ident(x) setPos npos.focus,
- Nil)
+ ListOfNil)
}
)
}
diff --git a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
index 64117bd8ee..b95f1fa7ca 100644
--- a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
+++ b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
@@ -144,7 +144,7 @@ self: scala.tools.nsc.Global =>
*/
private def setChildrenPos(pos: Position, trees: List[Tree]): Unit = try {
for (tree <- trees) {
- if (!tree.isEmpty && tree.canHaveAttrs && tree.pos == NoPosition) {
+ if (!tree.isEmpty && tree.pos == NoPosition) {
val children = tree.children
if (children.isEmpty) {
tree setPos pos.focus
@@ -165,7 +165,7 @@ self: scala.tools.nsc.Global =>
*/
override def atPos[T <: Tree](pos: Position)(tree: T): T = {
if (pos.isOpaqueRange) {
- if (!tree.isEmpty && tree.canHaveAttrs && tree.pos == NoPosition) {
+ if (!tree.isEmpty && tree.pos == NoPosition) {
tree.setPos(pos)
val children = tree.children
if (children.nonEmpty) {
@@ -203,7 +203,7 @@ self: scala.tools.nsc.Global =>
def validate(tree: Tree, encltree: Tree): Unit = {
- if (!tree.isEmpty && tree.canHaveAttrs) {
+ if (!tree.isEmpty) {
if (settings.Yposdebug.value && (settings.verbose.value || settings.Yrangepos.value))
println("[%10s] %s".format("validate", treeStatus(tree, encltree)))
diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
index 050f7a8f95..43a8402fc7 100644
--- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
@@ -551,7 +551,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
if (parentToken == AT && in.token == DEFAULT) {
val annot =
atPos(pos) {
- New(Select(scalaDot(nme.runtime), tpnme.AnnotationDefaultATTR), Nil)
+ New(Select(scalaDot(nme.runtime), tpnme.AnnotationDefaultATTR), ListOfNil)
}
mods1 = mods1 withAnnotations List(annot)
skipTo(SEMI)
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index ec0797acb5..4891ef2fd1 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -511,6 +511,7 @@ abstract class Constructors extends Transform with ast.TreeDSL {
sym = closureClass,
constrMods = Modifiers(0),
vparamss = List(List(outerFieldDef)),
+ argss = ListOfNil,
body = List(applyMethodDef),
superPos = impl.pos)
}
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index 965063a724..e9f403aea0 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -277,7 +277,7 @@ abstract class UnCurry extends InfoTransform
localTyper.typedPos(fun.pos) {
Block(
- List(ClassDef(anonClass, NoMods, ListOfNil, List(applyMethodDef), fun.pos)),
+ List(ClassDef(anonClass, NoMods, ListOfNil, ListOfNil, List(applyMethodDef), fun.pos)),
Typed(New(anonClass.tpe), TypeTree(fun.tpe)))
}
@@ -403,7 +403,7 @@ abstract class UnCurry extends InfoTransform
localTyper.typedPos(fun.pos) {
Block(
- List(ClassDef(anonClass, NoMods, ListOfNil, List(applyOrElseMethodDef, isDefinedAtMethodDef), fun.pos)),
+ List(ClassDef(anonClass, NoMods, ListOfNil, ListOfNil, List(applyOrElseMethodDef, isDefinedAtMethodDef), fun.pos)),
Typed(New(anonClass.tpe), TypeTree(fun.tpe)))
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index fbf23968f0..4bf7f78167 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -184,18 +184,14 @@ trait ContextErrors {
}
def ParentTypesError(templ: Template, ex: TypeError) = {
- templ.tpe = null
- issueNormalTypeError(templ, ex.getMessage())
- setError(templ)
+ templ.tpe = null
+ issueNormalTypeError(templ, ex.getMessage())
}
// additional parentTypes errors
- def ConstrArgsInParentWhichIsTraitError(arg: Tree, parent: Symbol) =
+ def ConstrArgsInTraitParentTpeError(arg: Tree, parent: Symbol) =
issueNormalTypeError(arg, parent + " is a trait; does not take constructor arguments")
- def ConstrArgsInParentOfTraitError(arg: Tree, parent: Symbol) =
- issueNormalTypeError(arg, "parents of traits may not have parameters")
-
def MissingTypeArgumentsParentTpeError(supertpt: Tree) =
issueNormalTypeError(supertpt, "missing type arguments")
@@ -1048,6 +1044,9 @@ trait ContextErrors {
def MaxParametersCaseClassError(tree: Tree) =
issueNormalTypeError(tree, "Implementation restriction: case classes cannot have more than " + definitions.MaxFunctionArity + " parameters.")
+ def InheritsItselfError(tree: Tree) =
+ issueNormalTypeError(tree, tree.tpe.typeSymbol+" inherits itself")
+
def MissingParameterOrValTypeError(vparam: Tree) =
issueNormalTypeError(vparam, "missing parameter type")
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index c728185d4e..ab338447c9 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -857,8 +857,13 @@ trait Namers extends MethodSynthesis {
private def templateSig(templ: Template): Type = {
val clazz = context.owner
def checkParent(tpt: Tree): Type = {
- if (tpt.tpe.isError) AnyRefClass.tpe
- else tpt.tpe
+ val tp = tpt.tpe
+ val inheritsSelf = tp.typeSymbol == owner
+ if (inheritsSelf)
+ InheritsItselfError(tpt)
+
+ if (inheritsSelf || tp.isError) AnyRefClass.tpe
+ else tp
}
val parents = typer.parentTypes(templ) map checkParent
diff --git a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
index 20db479463..64c5b41638 100644
--- a/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
@@ -4,31 +4,7 @@ package typechecker
trait StdAttachments {
self: Analyzer =>
- import global._
-
- /** Carries information necessary to expand the host tree.
- * At times we need to store this info, because macro expansion can be delayed until its targs are inferred.
- * After a macro application has been successfully expanded, this attachment is destroyed.
- */
type UnaffiliatedMacroContext = scala.reflect.macros.runtime.Context
type MacroContext = UnaffiliatedMacroContext { val universe: self.global.type }
case class MacroRuntimeAttachment(delayed: Boolean, typerContext: Context, macroContext: Option[MacroContext])
-
- /** After being synthesized by the parser, primary constructors aren't fully baked yet.
- * A call to super in such constructors is just a fill-me-in-later dummy resolved later
- * by `parentTypes`. This attachment coordinates `parentTypes` and `typedTemplate` and
- * allows them to complete the synthesis.
- */
- case class SuperArgsAttachment(argss: List[List[Tree]])
-
- /** Convenience method for `SuperArgsAttachment`.
- * Compared with `MacroRuntimeAttachment` this attachment has different a usage pattern,
- * so it really benefits from a dedicated extractor.
- */
- def superArgs(tree: Tree): Option[List[List[Tree]]] =
- tree.attachments.get[SuperArgsAttachment] collect { case SuperArgsAttachment(argss) => argss }
-
- /** Determines whether the given tree has an associated SuperArgsAttachment.
- */
- def hasSuperArgs(tree: Tree): Boolean = superArgs(tree).nonEmpty
} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 026c130a87..f518712701 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -53,10 +53,8 @@ trait Typers extends Modes with Adaptations with Tags {
object UnTyper extends Traverser {
override def traverse(tree: Tree) = {
- if (tree.canHaveAttrs) {
- tree.tpe = null
- if (tree.hasSymbol) tree.symbol = NoSymbol
- }
+ if (tree != EmptyTree) tree.tpe = null
+ if (tree.hasSymbol) tree.symbol = NoSymbol
super.traverse(tree)
}
}
@@ -1401,6 +1399,13 @@ trait Typers extends Modes with Adaptations with Tags {
if (member(qual, name) != NoSymbol) qual
else adaptToMember(qual, HasMember(name))
+ private def typePrimaryConstrBody(clazz : Symbol, cbody: Tree, tparams: List[Symbol], enclTparams: List[Symbol], vparamss: List[List[ValDef]]): Tree = {
+ // XXX: see about using the class's symbol....
+ enclTparams foreach (sym => context.scope.enter(sym))
+ namer.enterValueParams(vparamss)
+ typed(cbody)
+ }
+
private def validateNoCaseAncestor(clazz: Symbol) = {
if (!phase.erasedTypes) {
for (ancestor <- clazz.ancestors find (_.isCase)) {
@@ -1502,243 +1507,126 @@ trait Typers extends Modes with Adaptations with Tags {
unit.error(tparam.pos, "type parameter of value class may not be specialized")
}
- /** Typechecks a parent type reference.
- *
- * This typecheck is harder than it might look, because it should honor early
- * definitions and also perform type argument inference with the help of super call
- * arguments provided in `encodedtpt`.
- *
- * The method is called in batches (batch = 1 time per each parent type referenced),
- * two batches per definition: once from namer, when entering a ClassDef or a ModuleDef
- * and once from typer, when typechecking the definition.
- *
- * ***Arguments***
- *
- * `encodedtpt` represents the parent type reference wrapped in an `Apply` node
- * which indicates value arguments (i.e. type macro arguments or super constructor call arguments)
- * If no value arguments are provided by the user, the `Apply` node is still
- * there, but its `args` will be set to `Nil`.
- * This argument is synthesized by `tools.nsc.ast.Parsers.templateParents`.
- *
- * `templ` is an enclosing template, which contains a primary constructor synthesized by the parser.
- * Such a constructor is a DefDef which contains early initializers and maybe a super constructor call
- * (I wrote "maybe" because trait constructors don't call super constructors).
- * This argument is synthesized by `tools.nsc.ast.Trees.Template`.
- *
- * `inMixinPosition` indicates whether the reference is not the first in the
- * list of parents (and therefore cannot be a class) or the opposite.
- *
- * ***Return value and side effects***
- *
- * Returns a `TypeTree` representing a resolved parent type.
- * If the typechecked parent reference implies non-nullary and non-empty argument list,
- * this argument list is attached to the returned value in SuperArgsAttachment.
- * The attachment is necessary for the subsequent typecheck to fixup a super constructor call
- * in the body of the primary constructor (see `typedTemplate` for details).
- *
- * This method might invoke `typedPrimaryConstrBody`, hence it might cause the side effects
- * described in the docs of that method. It might also attribute the Super(_, _) reference
- * (if present) inside the primary constructor of `templ`.
- *
- * ***Example***
- *
- * For the following definition:
- *
- * class D extends {
- * val x = 2
- * val y = 4
- * } with B(x)(3) with C(y) with T
- *
- * this method will be called six times:
- *
- * (3 times from the namer)
- * typedParentType(Apply(Apply(Ident(B), List(Ident(x))), List(3)), templ, inMixinPosition = false)
- * typedParentType(Apply(Ident(C), List(Ident(y))), templ, inMixinPosition = true)
- * typedParentType(Apply(Ident(T), List()), templ, inMixinPosition = true)
- *
- * (3 times from the typer)
- * <the same three calls>
- */
- private def typedParentType(encodedtpt: Tree, templ: Template, inMixinPosition: Boolean): Tree = {
- val app = treeInfo.dissectApplied(encodedtpt)
- val (treeInfo.Applied(core, targs, argss), decodedtpt) = (app, app.callee)
- val argssAreTrivial = argss == Nil || argss == ListOfNil
-
- // we cannot avoid cyclic references with `initialize` here, because when type macros arrive,
- // we'll have to check the probe for isTypeMacro anyways.
- // therefore I think it's reasonable to trade a more specific "inherits itself" error
- // for a generic, yet understandable "cyclic reference" error
- var probe = typedTypeConstructor(core.duplicate).tpe.typeSymbol
- if (probe == null) probe = NoSymbol
- probe.initialize
-
- if (probe.isTrait || inMixinPosition) {
- if (!argssAreTrivial) {
- if (probe.isTrait) ConstrArgsInParentWhichIsTraitError(encodedtpt, probe)
- else () // a class in a mixin position - this warrants an error in `validateParentClasses`
- // therefore here we do nothing, e.g. don't check that the # of ctor arguments
- // matches the # of ctor parameters or stuff like that
- }
- typedType(decodedtpt)
- } else {
- var supertpt = typedTypeConstructor(decodedtpt)
- val supertparams = if (supertpt.hasSymbol) supertpt.symbol.typeParams else Nil
- if (supertparams.nonEmpty) {
- typedPrimaryConstrBody(templ) {
- val supertpe = PolyType(supertparams, appliedType(supertpt.tpe, supertparams map (_.tpeHK)))
- val supercall = New(supertpe, mmap(argss)(_.duplicate))
- val treeInfo.Applied(Select(ctor, nme.CONSTRUCTOR), _, _) = supercall
- ctor setType supertpe // this is an essential hack, otherwise it will occasionally fail to typecheck
- atPos(supertpt.pos.focus)(supercall)
- } match {
- case EmptyTree => MissingTypeArgumentsParentTpeError(supertpt)
- case tpt => supertpt = TypeTree(tpt.tpe) setPos supertpt.pos.focus
+ def parentTypes(templ: Template): List[Tree] =
+ if (templ.parents.isEmpty) List(atPos(templ.pos)(TypeTree(AnyRefClass.tpe)))
+ else try {
+ val clazz = context.owner
+ // Normalize supertype and mixins so that supertype is always a class, not a trait.
+ var supertpt = typedTypeConstructor(templ.parents.head)
+ val firstParent = supertpt.tpe.typeSymbol
+ var mixins = templ.parents.tail map typedType
+ // If first parent is a trait, make it first mixin and add its superclass as first parent
+ while ((supertpt.tpe.typeSymbol ne null) && supertpt.tpe.typeSymbol.initialize.isTrait) {
+ val supertpt1 = typedType(supertpt)
+ if (!supertpt1.isErrorTyped) {
+ mixins = supertpt1 :: mixins
+ supertpt = TypeTree(supertpt1.tpe.firstParent) setPos supertpt.pos.focus
}
}
- // this is the place where we tell the typer what argss should be used for the super call
- // if argss are nullary or empty, then (see the docs for `typedPrimaryConstrBody`)
- // the super call dummy is already good enough, so we don't need to do anything
- if (argssAreTrivial) supertpt else supertpt updateAttachment SuperArgsAttachment(argss)
- }
- }
-
- /** Typechecks the mishmash of trees that happen to be stuffed into the primary constructor of a given template.
- * Before commencing the typecheck, replaces the `pendingSuperCall` dummy with the result of `actualSuperCall`.
- * `actualSuperCall` can return `EmptyTree`, in which case the dummy is replaced with a literal unit.
- *
- * ***Return value and side effects***
- *
- * If a super call is present in the primary constructor and is not erased by the transform, returns it typechecked.
- * Otherwise (e.g. if the primary constructor is missing or the super call isn't there) returns `EmptyTree`.
- *
- * As a side effect, this method attributes the underlying fields of early vals.
- * Early vals aren't typechecked anywhere else, so it's essential to call `typedPrimaryConstrBody`
- * at least once per definition. It'd be great to disentangle this logic at some point.
- *
- * ***Example***
- *
- * For the following definition:
- *
- * class D extends {
- * val x = 2
- * val y = 4
- * } with B(x)(3) with C(y) with T
- *
- * the primary constructor of `templ` will be:
- *
- * Block(List(
- * ValDef(NoMods, x, TypeTree(), 2)
- * ValDef(NoMods, y, TypeTree(), 4)
- * global.pendingSuperCall,
- * Literal(Constant(())))
- *
- * Note the `pendingSuperCall` part. This is the representation of a fill-me-in-later supercall dummy,
- * which encodes the fact that supercall argss are unknown during parsing and need to be transplanted
- * from one of the parent types. Read more about why the argss are unknown in `tools.nsc.ast.Trees.Template`.
- */
- private def typedPrimaryConstrBody(templ: Template)(actualSuperCall: => Tree): Tree =
- treeInfo.firstConstructor(templ.body) match {
- case ctor @ DefDef(_, _, _, vparamss, _, cbody @ Block(cstats, cunit)) =>
- val (preSuperStats, superCall) = {
- val (stats, rest) = cstats span (x => !treeInfo.isSuperConstrCall(x))
- (stats map (_.duplicate), if (rest.isEmpty) EmptyTree else rest.head.duplicate)
- }
- val superCall1 = (superCall match {
- case global.pendingSuperCall => actualSuperCall
- case EmptyTree => EmptyTree
- }) orElse cunit
- val cbody1 = treeCopy.Block(cbody, preSuperStats, superCall1)
-
- val clazz = context.owner
- assert(clazz != NoSymbol, templ)
- val cscope = context.outer.makeNewScope(ctor, context.outer.owner)
- val cbody2 = { // called both during completion AND typing.
- val typer1 = newTyper(cscope)
- // XXX: see about using the class's symbol....
- clazz.unsafeTypeParams foreach (sym => typer1.context.scope.enter(sym))
- typer1.namer.enterValueParams(vparamss map (_.map(_.duplicate)))
- typer1.typed(cbody1)
- }
+ if (supertpt.tpe.typeSymbol == AnyClass && firstParent.isTrait)
+ supertpt.tpe = AnyRefClass.tpe
+
+ // Determine
+ // - supertparams: Missing type parameters from supertype
+ // - supertpe: Given supertype, polymorphic in supertparams
+ val supertparams = if (supertpt.hasSymbol) supertpt.symbol.typeParams else List()
+ var supertpe = supertpt.tpe
+ if (!supertparams.isEmpty)
+ supertpe = PolyType(supertparams, appliedType(supertpe, supertparams map (_.tpeHK)))
+
+ // A method to replace a super reference by a New in a supercall
+ def transformSuperCall(scall: Tree): Tree = (scall: @unchecked) match {
+ case Apply(fn, args) =>
+ treeCopy.Apply(scall, transformSuperCall(fn), args map (_.duplicate))
+ case Select(Super(_, _), nme.CONSTRUCTOR) =>
+ treeCopy.Select(
+ scall,
+ atPos(supertpt.pos.focus)(New(TypeTree(supertpe)) setType supertpe),
+ nme.CONSTRUCTOR)
+ }
- val preSuperVals = treeInfo.preSuperFields(templ.body)
- if (preSuperVals.isEmpty && preSuperStats.nonEmpty)
- debugwarn("Wanted to zip empty presuper val list with " + preSuperStats)
- else
- map2(preSuperStats, preSuperVals)((ldef, gdef) => gdef.tpt.tpe = ldef.symbol.tpe)
+ treeInfo.firstConstructor(templ.body) match {
+ case constr @ DefDef(_, _, _, vparamss, _, cbody @ Block(cstats, cunit)) =>
+ // Convert constructor body to block in environment and typecheck it
+ val (preSuperStats, superCall) = {
+ val (stats, rest) = cstats span (x => !treeInfo.isSuperConstrCall(x))
+ (stats map (_.duplicate), if (rest.isEmpty) EmptyTree else rest.head.duplicate)
+ }
+ val cstats1 = if (superCall == EmptyTree) preSuperStats else preSuperStats :+ superCall
+ val cbody1 = treeCopy.Block(cbody, preSuperStats, superCall match {
+ case Apply(_, _) if supertparams.nonEmpty => transformSuperCall(superCall)
+ case _ => cunit.duplicate
+ })
+ val outercontext = context.outer
+
+ assert(clazz != NoSymbol, templ)
+ val cscope = outercontext.makeNewScope(constr, outercontext.owner)
+ val cbody2 = newTyper(cscope) // called both during completion AND typing.
+ .typePrimaryConstrBody(clazz,
+ cbody1, supertparams, clazz.unsafeTypeParams, vparamss map (_.map(_.duplicate)))
+
+ superCall match {
+ case Apply(_, _) =>
+ val treeInfo.Applied(_, _, argss) = superCall
+ val sarg = argss.flatten.headOption.getOrElse(EmptyTree)
+ if (sarg != EmptyTree && supertpe.typeSymbol != firstParent)
+ ConstrArgsInTraitParentTpeError(sarg, firstParent)
+ if (!supertparams.isEmpty)
+ supertpt = TypeTree(cbody2.tpe) setPos supertpt.pos.focus
+ case _ =>
+ if (!supertparams.isEmpty)
+ MissingTypeArgumentsParentTpeError(supertpt)
+ }
- if (superCall1 == cunit) EmptyTree else cbody2
- case _ =>
- EmptyTree
- }
+ val preSuperVals = treeInfo.preSuperFields(templ.body)
+ if (preSuperVals.isEmpty && preSuperStats.nonEmpty)
+ debugwarn("Wanted to zip empty presuper val list with " + preSuperStats)
+ else
+ map2(preSuperStats, preSuperVals)((ldef, gdef) => gdef.tpt.tpe = ldef.symbol.tpe)
- /** Makes sure that the first type tree in the list of parent types is always a class.
- * If the first parent is a trait, prepend its supertype to the list until it's a class.
- */
- private def normalizeFirstParent(parents: List[Tree]): List[Tree] = parents match {
- case first :: rest if treeInfo.isTraitRef(first) =>
- def explode(supertpt: Tree, acc: List[Tree]): List[Tree] = {
- if (treeInfo.isTraitRef(supertpt)) {
- val supertpt1 = typedType(supertpt)
- if (!supertpt1.isErrorTyped) {
- val supersupertpt = TypeTree(supertpt1.tpe.firstParent) setPos supertpt.pos.focus
- return explode(supersupertpt, supertpt1 :: acc)
- }
- }
- if (supertpt.tpe.typeSymbol == AnyClass) supertpt.tpe = AnyRefClass.tpe
- supertpt :: acc
+ case _ =>
+ if (!supertparams.isEmpty)
+ MissingTypeArgumentsParentTpeError(supertpt)
}
- explode(first, Nil) ++ rest
- case _ => parents
- }
+/* experimental: early types as type arguments
+ val hasEarlyTypes = templ.body exists (treeInfo.isEarlyTypeDef)
+ val earlyMap = new EarlyMap(clazz)
+ List.mapConserve(supertpt :: mixins){ tpt =>
+ val tpt1 = checkNoEscaping.privates(clazz, tpt)
+ if (hasEarlyTypes) tpt1 else tpt1 setType earlyMap(tpt1.tpe)
+ }
+*/
- /** Certain parents are added in the parser before it is known whether
- * that class also declared them as parents. For instance, this is an
- * error unless we take corrective action here:
- *
- * case class Foo() extends Serializable
- *
- * So we strip the duplicates before typer.
- */
- private def fixDuplicateSyntheticParents(parents: List[Tree]): List[Tree] = parents match {
- case Nil => Nil
- case x :: xs =>
- val sym = x.symbol
- x :: fixDuplicateSyntheticParents(
- if (isPossibleSyntheticParent(sym)) xs filterNot (_.symbol == sym)
- else xs
- )
- }
+ //Console.println("parents("+clazz") = "+supertpt :: mixins);//DEBUG
- def parentTypes(templ: Template): List[Tree] = templ.parents match {
- case Nil => List(atPos(templ.pos)(TypeTree(AnyRefClass.tpe)))
- case first :: rest =>
- try {
- val supertpts = fixDuplicateSyntheticParents(normalizeFirstParent(
- typedParentType(first, templ, inMixinPosition = false) +:
- (rest map (typedParentType(_, templ, inMixinPosition = true)))))
-
- // if that is required to infer the targs of a super call
- // typedParentType calls typedPrimaryConstrBody to do the inferring typecheck
- // as a side effect, that typecheck also assigns types to the fields underlying early vals
- // however if inference is not required, the typecheck doesn't happen
- // and therefore early fields have their type trees not assigned
- // here we detect this situation and take preventive measures
- if (treeInfo.hasUntypedPreSuperFields(templ.body))
- typedPrimaryConstrBody(templ)(EmptyTree)
-
- supertpts mapConserve (tpt => checkNoEscaping.privates(context.owner, tpt))
- } catch {
- case ex: TypeError =>
- // fallback in case of cyclic errors
- // @H none of the tests enter here but I couldn't rule it out
- // upd. @E when a definitions inherits itself, we end up here
- // because `typedParentType` triggers `initialize` for parent types symbols
- log("Type error calculating parents in template " + templ)
- log("Error: " + ex)
- ParentTypesError(templ, ex)
- List(TypeTree(AnyRefClass.tpe))
+ // Certain parents are added in the parser before it is known whether
+ // that class also declared them as parents. For instance, this is an
+ // error unless we take corrective action here:
+ //
+ // case class Foo() extends Serializable
+ //
+ // So we strip the duplicates before typer.
+ def fixDuplicates(remaining: List[Tree]): List[Tree] = remaining match {
+ case Nil => Nil
+ case x :: xs =>
+ val sym = x.symbol
+ x :: fixDuplicates(
+ if (isPossibleSyntheticParent(sym)) xs filterNot (_.symbol == sym)
+ else xs
+ )
}
- }
+
+ fixDuplicates(supertpt :: mixins) mapConserve (tpt => checkNoEscaping.privates(clazz, tpt))
+ }
+ catch {
+ case ex: TypeError =>
+ // fallback in case of cyclic errors
+ // @H none of the tests enter here but I couldn't rule it out
+ log("Type error calculating parents in template " + templ)
+ log("Error: " + ex)
+ ParentTypesError(templ, ex)
+ List(TypeTree(AnyRefClass.tpe))
+ }
/** <p>Check that</p>
* <ul>
@@ -2003,12 +1891,9 @@ trait Typers extends Modes with Adaptations with Tags {
// the following is necessary for templates generated later
assert(clazz.info.decls != EmptyScope, clazz)
enterSyms(context.outer.make(templ, clazz, clazz.info.decls), templ.body)
- if (!templ.isErrorTyped) // if `parentTypes` has invalidated the template, don't validate it anymore
- validateParentClasses(parents1, selfType)
+ validateParentClasses(parents1, selfType)
if (clazz.isCase)
validateNoCaseAncestor(clazz)
- if (clazz.isTrait && hasSuperArgs(parents1.head))
- ConstrArgsInParentOfTraitError(parents1.head, clazz)
if ((clazz isSubClass ClassfileAnnotationClass) && !clazz.owner.isPackageClass)
unit.error(clazz.pos, "inner classes cannot be classfile annotations")
@@ -2016,21 +1901,9 @@ trait Typers extends Modes with Adaptations with Tags {
if (!phase.erasedTypes && !clazz.info.resultType.isError) // @S: prevent crash for duplicated type members
checkFinitary(clazz.info.resultType.asInstanceOf[ClassInfoType])
- val body = {
- val body =
- if (isPastTyper || reporter.hasErrors) templ.body
- else templ.body flatMap rewrappingWrapperTrees(namer.addDerivedTrees(Typer.this, _))
- val primaryCtor = treeInfo.firstConstructor(body)
- val primaryCtor1 = primaryCtor match {
- case DefDef(_, _, _, _, _, Block(earlyVals :+ global.pendingSuperCall, unit)) =>
- val argss = superArgs(parents1.head) getOrElse Nil
- val pos = wrappingPos(parents1.head.pos, argss.flatten)
- val superCall = atPos(pos)(PrimarySuperCall(argss))
- deriveDefDef(primaryCtor)(block => Block(earlyVals :+ superCall, unit) setPos pos) setPos pos
- case _ => primaryCtor
- }
- body mapConserve { case `primaryCtor` => primaryCtor1; case stat => stat }
- }
+ val body =
+ if (isPastTyper || reporter.hasErrors) templ.body
+ else templ.body flatMap rewrappingWrapperTrees(namer.addDerivedTrees(Typer.this, _))
val body1 = typedStats(body, templ.symbol)
@@ -2820,7 +2693,7 @@ trait Typers extends Modes with Adaptations with Tags {
members foreach (m => anonClass.info.decls enter m.symbol)
val typedBlock = typedPos(tree.pos, mode, pt) {
- Block(ClassDef(anonClass, NoMods, ListOfNil, members, tree.pos.focus), atPos(tree.pos.focus)(New(anonClass.tpe)))
+ Block(ClassDef(anonClass, NoMods, ListOfNil, ListOfNil, members, tree.pos.focus), atPos(tree.pos.focus)(New(anonClass.tpe)))
}
if (typedBlock.isErrorTyped) typedBlock
diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
index 577aa087ea..69074e4c0c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
@@ -127,7 +127,7 @@ trait Unapplies extends ast.TreeDSL
ModuleDef(
Modifiers(cdef.mods.flags & AccessFlags | SYNTHETIC, cdef.mods.privateWithin),
cdef.name.toTermName,
- Template(parents, emptyValDef, NoMods, Nil, body, cdef.impl.pos.focus))
+ Template(parents, emptyValDef, NoMods, Nil, ListOfNil, body, cdef.impl.pos.focus))
}
private val caseMods = Modifiers(SYNTHETIC | CASE)
diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
index 0125f1b189..95135b84e0 100644
--- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
+++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
@@ -230,6 +230,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
emptyValDef,
NoMods,
List(),
+ List(List()),
List(methdef),
NoPosition))
trace("wrapped: ")(showAttributed(moduledef, true, true, settings.Yshowsymkinds.value))
diff --git a/src/reflect/scala/reflect/api/BuildUtils.scala b/src/reflect/scala/reflect/api/BuildUtils.scala
index 8f256aa1f5..0c8e81a220 100644
--- a/src/reflect/scala/reflect/api/BuildUtils.scala
+++ b/src/reflect/scala/reflect/api/BuildUtils.scala
@@ -59,6 +59,8 @@ private[reflect] trait BuildUtils { self: Universe =>
def flagsFromBits(bits: Long): FlagSet
+ def emptyValDef: ValDef
+
def This(sym: Symbol): Tree
def Select(qualifier: Tree, sym: Symbol): Select
diff --git a/src/reflect/scala/reflect/api/Trees.scala b/src/reflect/scala/reflect/api/Trees.scala
index cfa6315797..0937a93738 100644
--- a/src/reflect/scala/reflect/api/Trees.scala
+++ b/src/reflect/scala/reflect/api/Trees.scala
@@ -75,26 +75,11 @@ trait Trees { self: Universe =>
def isDef: Boolean
/** Is this tree one of the empty trees?
- *
* Empty trees are: the `EmptyTree` null object, `TypeTree` instances that don't carry a type
* and the special `emptyValDef` singleton.
- *
- * In the compiler the `isEmpty` check and the derived `orElse` method are mostly used
- * as a check for a tree being a null object (`EmptyTree` for term trees and empty TypeTree for type trees).
- *
- * Unfortunately `emptyValDef` is also considered to be `isEmpty`, but this is deemed to be
- * a conceptual mistake pending a fix in https://issues.scala-lang.org/browse/SI-6762.
- *
- * @see `canHaveAttrs`
*/
def isEmpty: Boolean
- /** Can this tree carry attributes (i.e. symbols, types or positions)?
- * Typically the answer is yes, except for the `EmptyTree` null object and
- * two special singletons: `emptyValDef` and `pendingSuperCall`.
- */
- def canHaveAttrs: Boolean
-
/** The canonical way to test if a Tree represents a term.
*/
def isTerm: Boolean
@@ -2420,15 +2405,6 @@ trait Trees { self: Universe =>
*/
val emptyValDef: ValDef
- /** An empty superclass constructor call corresponding to:
- * super.<init>()
- * This is used as a placeholder in the primary constructor body in class templates
- * to denote the insertion point of a call to superclass constructor after the typechecker
- * figures out the superclass of a given template.
- * @group Trees
- */
- val pendingSuperCall: Apply
-
// ---------------------- factories ----------------------------------------------
/** A factory method for `ClassDef` nodes.
@@ -2931,8 +2907,7 @@ trait Trees { self: Universe =>
trees mapConserve (tree => transform(tree).asInstanceOf[TypeDef])
/** Transforms a `ValDef`. */
def transformValDef(tree: ValDef): ValDef =
- if (tree eq emptyValDef) tree
- else transform(tree).asInstanceOf[ValDef]
+ if (tree.isEmpty) tree else transform(tree).asInstanceOf[ValDef]
/** Transforms a list of `ValDef` nodes. */
def transformValDefs(trees: List[ValDef]): List[ValDef] =
trees mapConserve (transformValDef(_))
diff --git a/src/reflect/scala/reflect/internal/BuildUtils.scala b/src/reflect/scala/reflect/internal/BuildUtils.scala
index b1b0c5b60b..9f41f0336e 100644
--- a/src/reflect/scala/reflect/internal/BuildUtils.scala
+++ b/src/reflect/scala/reflect/internal/BuildUtils.scala
@@ -47,6 +47,8 @@ trait BuildUtils { self: SymbolTable =>
def flagsFromBits(bits: Long): FlagSet = bits
+ def emptyValDef: ValDef = self.emptyValDef
+
def This(sym: Symbol): Tree = self.This(sym)
def Select(qualifier: Tree, sym: Symbol): Select = self.Select(qualifier, sym)
diff --git a/src/reflect/scala/reflect/internal/Importers.scala b/src/reflect/scala/reflect/internal/Importers.scala
index 2f2b02975c..43902c1930 100644
--- a/src/reflect/scala/reflect/internal/Importers.scala
+++ b/src/reflect/scala/reflect/internal/Importers.scala
@@ -334,8 +334,6 @@ trait Importers extends api.Importers { self: SymbolTable =>
new ModuleDef(importModifiers(mods), importName(name).toTermName, importTemplate(impl))
case from.emptyValDef =>
emptyValDef
- case from.pendingSuperCall =>
- pendingSuperCall
case from.ValDef(mods, name, tpt, rhs) =>
new ValDef(importModifiers(mods), importName(name).toTermName, importTree(tpt), importTree(rhs))
case from.DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
diff --git a/src/reflect/scala/reflect/internal/Positions.scala b/src/reflect/scala/reflect/internal/Positions.scala
index f8c670827a..faa161d6b1 100644
--- a/src/reflect/scala/reflect/internal/Positions.scala
+++ b/src/reflect/scala/reflect/internal/Positions.scala
@@ -38,7 +38,7 @@ trait Positions extends api.Positions { self: SymbolTable =>
protected class DefaultPosAssigner extends PosAssigner {
var pos: Position = _
override def traverse(t: Tree) {
- if (!t.canHaveAttrs) ()
+ if (t eq EmptyTree) ()
else if (t.pos == NoPosition) {
t.setPos(pos)
super.traverse(t) // TODO: bug? shouldn't the traverse be outside of the if?
diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala
index a8085a4c58..80d247c0ea 100644
--- a/src/reflect/scala/reflect/internal/Printers.scala
+++ b/src/reflect/scala/reflect/internal/Printers.scala
@@ -435,7 +435,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
case tree =>
xprintTree(this, tree)
}
- if (printTypes && tree.isTerm && tree.canHaveAttrs) {
+ if (printTypes && tree.isTerm && !tree.isEmpty) {
print("{", if (tree.tpe eq null) "<null>" else tree.tpe.toString, "}")
}
}
@@ -542,10 +542,8 @@ trait Printers extends api.Printers { self: SymbolTable =>
print(")")
case EmptyTree =>
print("EmptyTree")
- case self.emptyValDef =>
+ case emptyValDef: AnyRef if emptyValDef eq self.emptyValDef =>
print("emptyValDef")
- case self.pendingSuperCall =>
- print("pendingSuperCall")
case tree: Tree =>
val hasSymbol = tree.hasSymbol && tree.symbol != NoSymbol
val isError = hasSymbol && tree.symbol.name.toString == nme.ERROR.toString
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index c870d8972d..5e7f5777b2 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -730,7 +730,6 @@ trait StdNames {
val null_ : NameType = "null"
val ofDim: NameType = "ofDim"
val origin: NameType = "origin"
- val pendingSuperCall: NameType = "pendingSuperCall"
val prefix : NameType = "prefix"
val productArity: NameType = "productArity"
val productElement: NameType = "productElement"
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index 98c1afb323..2cc848d458 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -342,9 +342,6 @@ abstract class TreeInfo {
def preSuperFields(stats: List[Tree]): List[ValDef] =
stats collect { case vd: ValDef if isEarlyValDef(vd) => vd }
- def hasUntypedPreSuperFields(stats: List[Tree]): Boolean =
- preSuperFields(stats) exists (_.tpt.isEmpty)
-
def isEarlyDef(tree: Tree) = tree match {
case TypeDef(mods, _, _, _) => mods hasFlag PRESUPER
case ValDef(mods, _, _, _) => mods hasFlag PRESUPER
@@ -509,10 +506,6 @@ abstract class TreeInfo {
def isSynthCaseSymbol(sym: Symbol) = sym hasAllFlags SYNTH_CASE_FLAGS
def hasSynthCaseSymbol(t: Tree) = t.symbol != null && isSynthCaseSymbol(t.symbol)
- def isTraitRef(tree: Tree): Boolean = {
- val sym = if (tree.tpe != null) tree.tpe.typeSymbol else null
- ((sym ne null) && sym.initialize.isTrait)
- }
/** Applications in Scala can have one of the following shapes:
*
diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala
index a528a9ced8..5522c47cfa 100644
--- a/src/reflect/scala/reflect/internal/Trees.scala
+++ b/src/reflect/scala/reflect/internal/Trees.scala
@@ -36,7 +36,6 @@ trait Trees extends api.Trees { self: SymbolTable =>
def isDef = false
def isEmpty = false
- def canHaveAttrs = true
/** The canonical way to test if a Tree represents a term.
*/
@@ -229,6 +228,14 @@ trait Trees extends api.Trees { self: SymbolTable =>
override def isDef = true
}
+ case object EmptyTree extends TermTree {
+ val asList = List(this)
+ super.tpe_=(NoType)
+ override def tpe_=(t: Type) =
+ if (t != NoType) throw new UnsupportedOperationException("tpe_=("+t+") inapplicable for <empty>")
+ override def isEmpty = true
+ }
+
abstract class MemberDef extends DefTree with MemberDefApi {
def mods: Modifiers
def keyword: String = this match {
@@ -592,7 +599,6 @@ trait Trees extends api.Trees { self: SymbolTable =>
case _: ApplyToImplicitArgs => new ApplyToImplicitArgs(fun, args)
case _: ApplyImplicitView => new ApplyImplicitView(fun, args)
// TODO: ApplyConstructor ???
- case self.pendingSuperCall => self.pendingSuperCall
case _ => new Apply(fun, args)
}).copyAttrs(tree)
def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]) =
@@ -955,23 +961,12 @@ trait Trees extends api.Trees { self: SymbolTable =>
def ValDef(sym: Symbol): ValDef = ValDef(sym, EmptyTree)
- trait CannotHaveAttrs extends Tree {
- override def canHaveAttrs = false
-
- private def unsupported(what: String, args: Any*) =
- throw new UnsupportedOperationException(s"$what($args) inapplicable for "+self.toString)
-
+ object emptyValDef extends ValDef(Modifiers(PRIVATE), nme.WILDCARD, TypeTree(NoType), EmptyTree) {
+ override def isEmpty = true
super.setPos(NoPosition)
- override def setPos(pos: Position) = unsupported("setPos", pos)
-
- super.setType(NoType)
- override def tpe_=(t: Type) = if (t != NoType) unsupported("tpe_=", t)
+ override def setPos(pos: Position) = { assert(false); this }
}
- case object EmptyTree extends TermTree with CannotHaveAttrs { override def isEmpty = true; val asList = List(this) }
- object emptyValDef extends ValDef(Modifiers(PRIVATE), nme.WILDCARD, TypeTree(NoType), EmptyTree) with CannotHaveAttrs
- object pendingSuperCall extends Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List()) with CannotHaveAttrs
-
def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef =
atPos(sym.pos) {
assert(sym != NoSymbol)
@@ -1039,9 +1034,6 @@ trait Trees extends api.Trees { self: SymbolTable =>
def New(tpe: Type, args: Tree*): Tree =
ApplyConstructor(TypeTree(tpe), args.toList)
- def New(tpe: Type, argss: List[List[Tree]]): Tree =
- New(TypeTree(tpe), argss)
-
def New(sym: Symbol, args: Tree*): Tree =
New(sym.tpe, args: _*)
@@ -1122,7 +1114,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
traverse(annot); traverse(arg)
case Template(parents, self, body) =>
traverseTrees(parents)
- if (self ne emptyValDef) traverse(self)
+ if (!self.isEmpty) traverse(self)
traverseStats(body, tree.symbol)
case Block(stats, expr) =>
traverseTrees(stats); traverse(expr)
diff --git a/src/reflect/scala/reflect/macros/Attachments.scala b/src/reflect/scala/reflect/macros/Attachments.scala
index eeb87fafcc..007df3b6e2 100644
--- a/src/reflect/scala/reflect/macros/Attachments.scala
+++ b/src/reflect/scala/reflect/macros/Attachments.scala
@@ -56,6 +56,8 @@ abstract class Attachments { self =>
// SI-7018: This used to be an inner class of `Attachments`, but that led to a memory leak in the
// IDE via $outer pointers.
+// Forward compatibility note: This class used to be Attachments$NonemptyAttachments.
+// However it's private, therefore it transcends the compatibility policy for 2.10.x.
private final class NonemptyAttachments[P >: Null](override val pos: P, override val all: Set[Any]) extends Attachments {
type Pos = P
def withPos(newPos: Pos) = new NonemptyAttachments(newPos, all)
diff --git a/test/files/neg/anyval-anyref-parent.check b/test/files/neg/anyval-anyref-parent.check
index 8c2aa36583..fe20e5de81 100644
--- a/test/files/neg/anyval-anyref-parent.check
+++ b/test/files/neg/anyval-anyref-parent.check
@@ -3,7 +3,7 @@ trait Foo2 extends AnyVal // fail
^
anyval-anyref-parent.scala:5: error: Any does not have a constructor
class Bar1 extends Any // fail
- ^
+ ^
anyval-anyref-parent.scala:6: error: value class needs to have exactly one public val parameter
class Bar2(x: Int) extends AnyVal // fail
^
diff --git a/test/files/neg/cyclics-import.check b/test/files/neg/cyclics-import.check
index be09fca374..ef355fab0a 100644
--- a/test/files/neg/cyclics-import.check
+++ b/test/files/neg/cyclics-import.check
@@ -3,4 +3,13 @@ Note: this is often due in part to a class depending on a definition nested with
If applicable, you may wish to try moving some members into another object.
import User.UserStatus._
^
-one error found
+cyclics-import.scala:12: error: not found: type Value
+ type UserStatus = Value
+ ^
+cyclics-import.scala:14: error: not found: value Value
+ val Active = Value("1")
+ ^
+cyclics-import.scala:15: error: not found: value Value
+ val Disabled = Value("2")
+ ^
+four errors found
diff --git a/test/files/neg/names-defaults-neg.check b/test/files/neg/names-defaults-neg.check
index f6bd703e1f..ea7c323b74 100644
--- a/test/files/neg/names-defaults-neg.check
+++ b/test/files/neg/names-defaults-neg.check
@@ -100,7 +100,7 @@ Error occurred in an application involving default arguments.
^
names-defaults-neg.scala:86: error: module extending its companion class cannot use default constructor arguments
object C extends C()
- ^
+ ^
names-defaults-neg.scala:90: error: deprecated parameter name x has to be distinct from any other parameter name (deprecated or not).
def deprNam1(x: Int, @deprecatedName('x) y: String) = 0
^
diff --git a/test/files/neg/protected-constructors.check b/test/files/neg/protected-constructors.check
index e295917050..f137158ed6 100644
--- a/test/files/neg/protected-constructors.check
+++ b/test/files/neg/protected-constructors.check
@@ -19,4 +19,7 @@ protected-constructors.scala:15: error: class Foo3 in object Ding cannot be acce
object Ding in package dingus where target is defined
class Bar3 extends Ding.Foo3("abc")
^
-four errors found
+protected-constructors.scala:15: error: too many arguments for constructor Object: ()Object
+ class Bar3 extends Ding.Foo3("abc")
+ ^
+5 errors found
diff --git a/test/files/neg/t2148.check b/test/files/neg/t2148.check
index 27b5dce507..5113b48e51 100644
--- a/test/files/neg/t2148.check
+++ b/test/files/neg/t2148.check
@@ -1,4 +1,4 @@
-t2148.scala:9: error: A is not a legal prefix for a constructor
+t2148.scala:9: error: type A is not a stable prefix
val b = new A with A#A1
^
one error found
diff --git a/test/files/neg/t409.check b/test/files/neg/t409.check
index 0edc0d03cd..433d64d25d 100644
--- a/test/files/neg/t409.check
+++ b/test/files/neg/t409.check
@@ -1,4 +1,4 @@
-t409.scala:6: error: class Case1 needs to be a trait to be mixed in
+t409.scala:6: error: traits or objects may not have parameters
class Toto extends Expr with Case1(12);
- ^
+ ^
one error found
diff --git a/test/files/neg/t5529.check b/test/files/neg/t5529.check
index da3f84e1ec..5d2175fa79 100644
--- a/test/files/neg/t5529.check
+++ b/test/files/neg/t5529.check
@@ -4,4 +4,7 @@ t5529.scala:12: error: File is already defined as class File
t5529.scala:10: error: class type required but test.Test.File found
sealed class Dir extends File { }
^
-two errors found
+t5529.scala:10: error: test.Test.File does not have a constructor
+ sealed class Dir extends File { }
+ ^
+three errors found
diff --git a/test/files/neg/t5696.check b/test/files/neg/t5696.check
index e0fb61b839..72b7781fc4 100644
--- a/test/files/neg/t5696.check
+++ b/test/files/neg/t5696.check
@@ -15,5 +15,5 @@ t5696.scala:38: error: too many argument lists for constructor invocation
^
t5696.scala:46: error: too many argument lists for constructor invocation
object x extends G(1)(2) {}
- ^
+ ^
6 errors found
diff --git a/test/files/neg/t667.check b/test/files/neg/t667.check
index e68c6dea00..d4367bc87b 100644
--- a/test/files/neg/t667.check
+++ b/test/files/neg/t667.check
@@ -1,4 +1,4 @@
-t667.scala:8: error: illegal cyclic reference involving class Ni
+t667.scala:8: error: class Ni inherits itself
class Ni extends super.Ni with Ni;
- ^
+ ^
one error found
diff --git a/test/files/neg/t877.check b/test/files/neg/t877.check
index c3d4ab6584..5f25bd439c 100644
--- a/test/files/neg/t877.check
+++ b/test/files/neg/t877.check
@@ -1,7 +1,7 @@
t877.scala:3: error: Invalid literal number
trait Foo extends A(22A, Bug!) {}
^
-t877.scala:3: error: ')' expected but eof found.
+t877.scala:3: error: parents of traits may not have parameters
trait Foo extends A(22A, Bug!) {}
- ^
+ ^
two errors found
diff --git a/test/files/run/analyzerPlugins.check b/test/files/run/analyzerPlugins.check
index 8856fef5b3..7d8d181306 100644
--- a/test/files/run/analyzerPlugins.check
+++ b/test/files/run/analyzerPlugins.check
@@ -22,12 +22,12 @@ pluginsPt(?, Trees$Annotated) [7]
pluginsPt(?, Trees$Apply) [8]
pluginsPt(?, Trees$ApplyImplicitView) [2]
pluginsPt(?, Trees$Assign) [7]
-pluginsPt(?, Trees$Block) [4]
+pluginsPt(?, Trees$Block) [7]
pluginsPt(?, Trees$ClassDef) [2]
pluginsPt(?, Trees$DefDef) [14]
-pluginsPt(?, Trees$Ident) [51]
+pluginsPt(?, Trees$Ident) [49]
pluginsPt(?, Trees$If) [2]
-pluginsPt(?, Trees$Literal) [16]
+pluginsPt(?, Trees$Literal) [20]
pluginsPt(?, Trees$New) [5]
pluginsPt(?, Trees$PackageDef) [1]
pluginsPt(?, Trees$Return) [1]
@@ -37,9 +37,9 @@ pluginsPt(?, Trees$This) [20]
pluginsPt(?, Trees$TypeApply) [3]
pluginsPt(?, Trees$TypeBoundsTree) [2]
pluginsPt(?, Trees$TypeDef) [1]
-pluginsPt(?, Trees$TypeTree) [38]
+pluginsPt(?, Trees$TypeTree) [37]
pluginsPt(?, Trees$Typed) [1]
-pluginsPt(?, Trees$ValDef) [21]
+pluginsPt(?, Trees$ValDef) [23]
pluginsPt(Any, Trees$Literal) [2]
pluginsPt(Any, Trees$Typed) [1]
pluginsPt(Array[Any], Trees$ArrayValue) [1]
@@ -53,7 +53,7 @@ pluginsPt(Int @testAnn, Trees$Literal) [1]
pluginsPt(Int, Trees$Apply) [1]
pluginsPt(Int, Trees$Ident) [2]
pluginsPt(Int, Trees$If) [1]
-pluginsPt(Int, Trees$Literal) [5]
+pluginsPt(Int, Trees$Literal) [6]
pluginsPt(Int, Trees$Select) [3]
pluginsPt(List, Trees$Apply) [1]
pluginsPt(List[Any], Trees$Select) [1]
@@ -82,8 +82,8 @@ pluginsTypeSig(value lub1, Trees$ValDef) [2]
pluginsTypeSig(value lub2, Trees$ValDef) [2]
pluginsTypeSig(value param, Trees$ValDef) [2]
pluginsTypeSig(value str, Trees$ValDef) [1]
-pluginsTypeSig(value x, Trees$ValDef) [4]
-pluginsTypeSig(value y, Trees$ValDef) [4]
+pluginsTypeSig(value x, Trees$ValDef) [5]
+pluginsTypeSig(value y, Trees$ValDef) [5]
pluginsTypeSig(variable count, Trees$ValDef) [3]
pluginsTypeSigAccessor(value annotField) [1]
pluginsTypeSigAccessor(value inferField) [1]
@@ -110,7 +110,7 @@ pluginsTyped(<notype>, Trees$ClassDef) [2]
pluginsTyped(<notype>, Trees$DefDef) [14]
pluginsTyped(<notype>, Trees$PackageDef) [1]
pluginsTyped(<notype>, Trees$TypeDef) [1]
-pluginsTyped(<notype>, Trees$ValDef) [21]
+pluginsTyped(<notype>, Trees$ValDef) [23]
pluginsTyped(<root>, Trees$Ident) [1]
pluginsTyped(=> Boolean @testAnn, Trees$Select) [1]
pluginsTyped(=> Double, Trees$Select) [4]
@@ -124,7 +124,7 @@ pluginsTyped(A, Trees$TypeTree) [4]
pluginsTyped(A.super.type, Trees$Super) [1]
pluginsTyped(A.this.type, Trees$This) [11]
pluginsTyped(Any, Trees$TypeTree) [1]
-pluginsTyped(AnyRef, Trees$Select) [4]
+pluginsTyped(AnyRef, Trees$Select) [2]
pluginsTyped(Array[Any], Trees$ArrayValue) [1]
pluginsTyped(Boolean @testAnn, Trees$Select) [1]
pluginsTyped(Boolean @testAnn, Trees$TypeTree) [4]
@@ -137,12 +137,12 @@ pluginsTyped(Int @testAnn, Trees$TypeTree) [2]
pluginsTyped(Int @testAnn, Trees$Typed) [2]
pluginsTyped(Int(0), Trees$Literal) [3]
pluginsTyped(Int(1) @testAnn, Trees$Typed) [1]
-pluginsTyped(Int(1), Trees$Literal) [8]
+pluginsTyped(Int(1), Trees$Literal) [9]
pluginsTyped(Int(2), Trees$Literal) [1]
pluginsTyped(Int, Trees$Apply) [1]
pluginsTyped(Int, Trees$Ident) [2]
pluginsTyped(Int, Trees$If) [2]
-pluginsTyped(Int, Trees$Select) [15]
+pluginsTyped(Int, Trees$Select) [17]
pluginsTyped(Int, Trees$TypeTree) [13]
pluginsTyped(List, Trees$Apply) [1]
pluginsTyped(List, Trees$Select) [1]
@@ -160,27 +160,26 @@ pluginsTyped(String("huhu"), Trees$Literal) [1]
pluginsTyped(String("str") @testAnn, Trees$Typed) [1]
pluginsTyped(String("str"), Trees$Literal) [1]
pluginsTyped(String("str"), Trees$Typed) [1]
-pluginsTyped(String("two"), Trees$Literal) [2]
+pluginsTyped(String("two"), Trees$Literal) [3]
pluginsTyped(String, Trees$Apply) [2]
pluginsTyped(String, Trees$Block) [2]
pluginsTyped(String, Trees$Ident) [1]
pluginsTyped(String, Trees$Select) [9]
-pluginsTyped(String, Trees$TypeTree) [7]
+pluginsTyped(String, Trees$TypeTree) [8]
pluginsTyped(Unit, Trees$Apply) [2]
pluginsTyped(Unit, Trees$Assign) [8]
-pluginsTyped(Unit, Trees$Block) [4]
+pluginsTyped(Unit, Trees$Block) [7]
pluginsTyped(Unit, Trees$If) [1]
-pluginsTyped(Unit, Trees$Literal) [5]
+pluginsTyped(Unit, Trees$Literal) [8]
pluginsTyped(Unit, Trees$TypeTree) [1]
pluginsTyped([A](xs: A*)List[A], Trees$Select) [1]
pluginsTyped([T <: Int]=> Int, Trees$Select) [1]
pluginsTyped([T0 >: ? <: ?]()T0, Trees$Select) [1]
pluginsTyped([T](xs: Array[T])scala.collection.mutable.WrappedArray[T], Trees$Select) [1]
-pluginsTyped(annotation.type, Trees$Select) [4]
+pluginsTyped(annotation.type, Trees$Select) [2]
pluginsTyped(math.type, Trees$Select) [9]
pluginsTyped(scala.annotation.Annotation, Trees$Apply) [1]
pluginsTyped(scala.annotation.TypeConstraint, Trees$Select) [4]
-pluginsTyped(scala.annotation.TypeConstraint, Trees$TypeTree) [2]
pluginsTyped(scala.collection.immutable.List.type, Trees$Select) [2]
pluginsTyped(scala.collection.immutable.StringOps, Trees$ApplyImplicitView) [2]
pluginsTyped(scala.collection.mutable.WrappedArray[Any], Trees$Apply) [1]
diff --git a/test/files/run/t5064.check b/test/files/run/t5064.check
index 61ccfd16e7..077006abd9 100644
--- a/test/files/run/t5064.check
+++ b/test/files/run/t5064.check
@@ -1,6 +1,6 @@
-[53] T5064.super.<init>()
-[53] T5064.super.<init>
-[53] this
+[12] T5064.super.<init>()
+[12] T5064.super.<init>
+[12] this
[16:23] immutable.this.List.apply(scala.this.Predef.wrapIntArray(Array[Int]{1}))
[16:20] immutable.this.List.apply
<16:20> immutable.this.List
diff --git a/test/files/run/t5603.check b/test/files/run/t5603.check
index 3b2eb55313..5127d3c1c7 100644
--- a/test/files/run/t5603.check
+++ b/test/files/run/t5603.check
@@ -12,7 +12,7 @@
[95:101]<paramaccessor> private[this] val i: [98:101]Int = _;
<119:139>def <init>([95]i: [98]Int) = <119:139>{
<119:139>val nameElse = <134:139>"Bob";
- [NoPosition][NoPosition][NoPosition]super.<init>();
+ [94][94][94]super.<init>();
[94]()
};
[168:184]val name = [179:184]"avc";
@@ -20,7 +20,7 @@
};
[215:241]object Test extends [227:241][235:238]App {
[227]def <init>() = [227]{
- [NoPosition][NoPosition][NoPosition]super.<init>();
+ [227][227][227]super.<init>();
[227]()
};
[NoPosition]<empty>
diff --git a/test/files/run/t6288.check b/test/files/run/t6288.check
index 4895c2c007..e6467edc95 100644
--- a/test/files/run/t6288.check
+++ b/test/files/run/t6288.check
@@ -1,8 +1,8 @@
[[syntax trees at end of patmat]] // newSource1
[7]package [7]<empty> {
[7]object Case3 extends [13][106]scala.AnyRef {
- [106]def <init>(): [13]Case3.type = [106]{
- [106][106][106]Case3.super.<init>();
+ [13]def <init>(): [13]Case3.type = [13]{
+ [13][13][13]Case3.super.<init>();
[13]()
};
[21]def unapply([29]z: [32]<type: [32]scala.Any>): [21]Option[Int] = [56][52][52]scala.Some.apply[[52]Int]([58]-1);
@@ -24,8 +24,8 @@
}
};
[113]object Case4 extends [119][217]scala.AnyRef {
- [217]def <init>(): [119]Case4.type = [217]{
- [217][217][217]Case4.super.<init>();
+ [119]def <init>(): [119]Case4.type = [119]{
+ [119][119][119]Case4.super.<init>();
[119]()
};
[127]def unapplySeq([138]z: [141]<type: [141]scala.Any>): [127]Option[List[Int]] = [167]scala.None;
@@ -50,8 +50,8 @@
}
};
[224]object Case5 extends [230][312]scala.AnyRef {
- [312]def <init>(): [230]Case5.type = [312]{
- [312][312][312]Case5.super.<init>();
+ [230]def <init>(): [230]Case5.type = [230]{
+ [230][230][230]Case5.super.<init>();
[230]()
};
[238]def unapply([246]z: [249]<type: [249]scala.Any>): [238]Boolean = [265]true;
diff --git a/test/files/run/t6288b-jump-position.check b/test/files/run/t6288b-jump-position.check
index ece88b18f0..83ba810958 100644
--- a/test/files/run/t6288b-jump-position.check
+++ b/test/files/run/t6288b-jump-position.check
@@ -65,9 +65,9 @@ object Case3 extends Object {
blocks: [1]
1:
- 12 THIS(Case3)
- 12 CALL_METHOD java.lang.Object.<init> (super())
- 12 RETURN(UNIT)
+ 1 THIS(Case3)
+ 1 CALL_METHOD java.lang.Object.<init> (super())
+ 1 RETURN(UNIT)
}
Exception handlers:
diff --git a/test/files/run/t7064-old-style-supercalls.check b/test/files/run/t7064-old-style-supercalls.check
new file mode 100644
index 0000000000..0cfbf08886
--- /dev/null
+++ b/test/files/run/t7064-old-style-supercalls.check
@@ -0,0 +1 @@
+2
diff --git a/test/files/run/t7064-old-style-supercalls.scala b/test/files/run/t7064-old-style-supercalls.scala
new file mode 100644
index 0000000000..cffa7b1888
--- /dev/null
+++ b/test/files/run/t7064-old-style-supercalls.scala
@@ -0,0 +1,48 @@
+import scala.reflect.runtime.universe._
+import Flag._
+import definitions._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.ToolBox
+import scala.tools.reflect.Eval
+
+object Test extends App {
+ val PARAMACCESSOR = (1L << 29).asInstanceOf[FlagSet]
+
+ // these trees can be acquired by running the following incantation:
+ // echo 'class C(val x: Int); class D extends C(2)' > foo.scala
+ // ./scalac -Xprint:parser -Yshow-trees-stringified -Yshow-trees-compact foo.scala
+
+ val c = ClassDef(
+ Modifiers(), newTypeName("C"), List(),
+ Template(
+ List(Select(Ident(ScalaPackage), newTypeName("AnyRef"))),
+ emptyValDef,
+ List(
+ ValDef(Modifiers(PARAMACCESSOR), newTermName("x"), Ident(newTypeName("Int")), EmptyTree),
+ DefDef(
+ Modifiers(),
+ nme.CONSTRUCTOR,
+ List(),
+ List(List(ValDef(Modifiers(PARAM | PARAMACCESSOR), newTermName("x"), Ident(newTypeName("Int")), EmptyTree))),
+ TypeTree(),
+ Block(
+ List(Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List())),
+ Literal(Constant(())))))))
+ val d = ClassDef(
+ Modifiers(), newTypeName("D"), List(),
+ Template(
+ List(Ident(newTypeName("C"))),
+ emptyValDef,
+ List(
+ DefDef(
+ Modifiers(),
+ nme.CONSTRUCTOR,
+ List(),
+ List(List()),
+ TypeTree(),
+ Block(
+ List(Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List(Literal(Constant(2))))),
+ Literal(Constant(())))))))
+ val result = Select(Apply(Select(New(Ident(newTypeName("D"))), nme.CONSTRUCTOR), List()), newTermName("x"))
+ println(cm.mkToolBox().eval(Block(List(c, d), result)))
+} \ No newline at end of file