Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

[nomaster] Revert "introduces global.pendingSuperCall"

This reverts commit 0ebf72b.

Conflicts:
	src/compiler/scala/tools/nsc/typechecker/Typers.scala
	src/reflect/scala/reflect/internal/Trees.scala
  • Loading branch information...
commit 570f4a46f663a8f55ce045bfde2d834bd4902f9c 1 parent c720531
@xeno-by xeno-by authored
View
4 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(_, _) =>
View
3  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)
View
2  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.isDummy) ()
+ 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))
View
23 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 }
@@ -124,12 +117,12 @@ 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 = Apply(superRef, Nil) // 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
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`?
@@ -337,8 +330,6 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
else
super.transform {
tree match {
- case tree if tree.isDummy =>
- tree
case tpt: TypeTree =>
if (tpt.original != null)
transform(tpt.original)
@@ -352,6 +343,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))
View
12 src/compiler/scala/tools/nsc/typechecker/StdAttachments.scala
@@ -21,14 +21,12 @@ trait StdAttachments {
*/
case class SuperCallArgsAttachment(argss: List[List[Tree]])
- /** Convenience method for `SuperCallArgsAttachment`.
+ /** Extractor for `SuperCallArgsAttachment`.
* Compared with `MacroRuntimeAttachment` this attachment has different a usage pattern,
* so it really benefits from a dedicated extractor.
*/
- def superCallArgs(tree: Tree): Option[List[List[Tree]]] =
- tree.attachments.get[SuperCallArgsAttachment] collect { case SuperCallArgsAttachment(argss) => argss }
-
- /** Determines whether the given tree has an associated SuperCallArgsAttachment.
- */
- def hasSuperArgs(tree: Tree): Boolean = superCallArgs(tree).nonEmpty
+ object CarriesSuperCallArgs {
+ def unapply(tree: Tree): Option[List[List[Tree]]] =
+ tree.attachments.get[SuperCallArgsAttachment] collect { case SuperCallArgsAttachment(argss) => argss }
+ }
}
View
73 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.isDummy) {
- tree.tpe = null
- if (tree.hasSymbol) tree.symbol = NoSymbol
- }
+ if (tree != EmptyTree) tree.tpe = null
+ if (tree.hasSymbol) tree.symbol = NoSymbol
super.traverse(tree)
}
}
@@ -1584,7 +1582,7 @@ trait Typers extends Modes with Adaptations with Tags {
var supertpt = typedTypeConstructor(decodedtpt)
val supertparams = if (supertpt.hasSymbol) supertpt.symbol.typeParams else Nil
if (supertparams.nonEmpty) {
- typedPrimaryConstrBody(templ) {
+ typedPrimaryConstrBody(templ) { superRef =>
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
@@ -1603,8 +1601,8 @@ trait Typers extends Modes with Adaptations with Tags {
}
/** 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.
+ * Before commencing the typecheck applies `superCallTransform` to a super call (if the latter exists).
+ * The transform can return `EmptyTree`, in which case the super call is replaced with a literal unit.
*
* ***Return value and side effects***
*
@@ -1629,14 +1627,34 @@ trait Typers extends Modes with Adaptations with Tags {
* Block(List(
* ValDef(NoMods, x, TypeTree(), 2)
* ValDef(NoMods, y, TypeTree(), 4)
- * global.pendingSuperCall,
+ * Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR)), List()),
* 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`.
+ * Note the Select(Super(_, _), nme.CONSTRUCTOR) part. This is the representation of
+ * a fill-me-in-later supercall dummy. The argss are Nil, 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`.
+ *
+ * The entire Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR)), List()) is a dummy,
+ * and it's the one and only possible representation that can be emitted by parser.
+ *
+ * Despite of being unwieldy, this tree is quite convenient because:
+ * * It works as is for the case when no processing is required (empty ctor args for the superclass)
+ * * Stripping off the Apply produces a core that only needs rewrapping with applications of actual argss.
+ *
+ * For some time I was thinking of using just Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR)),
+ * but that one required wrapping even if the superclass doesn't take any argss.
+ *
+ * Another option would be to introduce a singleton tree akin to `emptyValDef` and use it as a dummy.
+ * Unfortunately this won't work out of the box, because the Super part is supposed to get attributed
+ * during `typedPrimaryConstrBody`.
+ *
+ * We could introduce another attachment for that or change SuperCallArgsAttachment
+ * to accommodate for the attributed Super, and then using the attached info to adjust the primary constructor
+ * during typedTemplate. However, given the scope of necessary changes (beyond a few lines) and the fact that,
+ * according to Martin, the whole thing is to be rewritten soon, I'd say we don't do the follow-up refactoring.
*/
- private def typedPrimaryConstrBody(templ: Template)(actualSuperCall: => Tree): Tree =
+ private def typedPrimaryConstrBody(templ: Template)(superCallTransform: Tree => Tree): Tree =
treeInfo.firstConstructor(templ.body) match {
case ctor @ DefDef(_, _, _, vparamss, _, cbody @ Block(cstats, cunit)) =>
val (preSuperStats, superCall) = {
@@ -1644,7 +1662,7 @@ trait Typers extends Modes with Adaptations with Tags {
(stats map (_.duplicate), if (rest.isEmpty) EmptyTree else rest.head.duplicate)
}
val superCall1 = (superCall match {
- case global.pendingSuperCall => actualSuperCall
+ case Apply(superRef @ Select(Super(_, _), nme.CONSTRUCTOR), Nil) => superCallTransform(superRef)
case EmptyTree => EmptyTree
}) orElse cunit
val cbody1 = treeCopy.Block(cbody, preSuperStats, superCall1)
@@ -1724,7 +1742,7 @@ trait Typers extends Modes with Adaptations with Tags {
// 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)
+ typedPrimaryConstrBody(templ)(superRef => EmptyTree)
supertpts mapConserve (tpt => checkNoEscaping.privates(context.owner, tpt))
} catch {
@@ -2007,8 +2025,6 @@ trait Typers extends Modes with Adaptations with Tags {
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")
@@ -2020,16 +2036,23 @@ trait Typers extends Modes with Adaptations with Tags {
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 = superCallArgs(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
+ parents1.head match {
+ case CarriesSuperCallArgs(argss) =>
+ if (clazz.isTrait) {
+ ConstrArgsInParentOfTraitError(parents1.head, clazz)
+ body
+ } else {
+ val pos = wrappingPos(parents1.head.pos, argss.flatten)
+ val primaryCtor = treeInfo.firstConstructor(templ.body)
+ val primaryCtor1 = (deriveDefDef(primaryCtor) {
+ case block @ Block(earlyVals :+ Apply(superRef, Nil), unit) =>
+ val superCall = atPos(pos)((superRef /: argss)(Apply.apply))
+ Block(earlyVals :+ superCall, unit) setPos pos
+ }) setPos pos
+ body map { case `primaryCtor` => primaryCtor1; case stat => stat }
+ }
+ case _ => body
}
- body mapConserve { case `primaryCtor` => primaryCtor1; case stat => stat }
}
val body1 = typedStats(body, templ.symbol)
View
9 src/reflect/scala/reflect/api/Trees.scala
@@ -2405,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.
View
2  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) =>
View
2  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.isDummy) ()
+ 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?
View
4 src/reflect/scala/reflect/internal/Printers.scala
@@ -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
View
1  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"
View
26 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 isDummy = false
/** 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,24 +961,12 @@ trait Trees extends api.Trees { self: SymbolTable =>
def ValDef(sym: Symbol): ValDef = ValDef(sym, EmptyTree)
- trait DummyTree extends Tree {
+ object emptyValDef extends ValDef(Modifiers(PRIVATE), nme.WILDCARD, TypeTree(NoType), EmptyTree) {
override def isEmpty = true
- override def isDummy = true
-
- private def unsupported(what: String, args: Any*) =
- throw new UnsupportedOperationException(s"$what($args) inapplicable for "+self.toString)
-
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 DummyTree { val asList = List(this) }
- object emptyValDef extends ValDef(Modifiers(PRIVATE), nme.WILDCARD, TypeTree(NoType), EmptyTree) with DummyTree
- object pendingSuperCall extends Apply(Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR), List()) with DummyTree
-
def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef =
atPos(sym.pos) {
assert(sym != NoSymbol)
View
2  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
^
View
2  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
^
View
5 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
View
6 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
View
4 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>
View
12 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;
View
6 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:
Please sign in to comment.
Something went wrong with that request. Please try again.