summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/reflect/reify/Errors.scala5
-rw-r--r--src/compiler/scala/reflect/reify/phases/Reshape.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala23
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala6
-rw-r--r--test/files/neg/t7235.check4
-rw-r--r--test/files/neg/t7235.scala14
-rw-r--r--test/files/neg/t7238.check6
-rw-r--r--test/files/neg/t7238.scala7
-rw-r--r--test/files/pos/t7226.scala26
-rw-r--r--test/files/pos/t7234.scala15
-rw-r--r--test/files/pos/t7234b.scala20
-rw-r--r--test/files/presentation/hyperlinks.check137
-rw-r--r--test/files/presentation/hyperlinks/src/SuperTypes.scala32
-rw-r--r--test/files/run/t5710-1.check1
-rw-r--r--test/files/run/t5710-1.scala15
-rw-r--r--test/files/run/t5710-2.check1
-rw-r--r--test/files/run/t5710-2.scala15
-rw-r--r--test/files/run/t7235.check4
-rw-r--r--test/files/run/t7235.scala14
20 files changed, 336 insertions, 12 deletions
diff --git a/src/compiler/scala/reflect/reify/Errors.scala b/src/compiler/scala/reflect/reify/Errors.scala
index 3a68794c97..860dfd72b2 100644
--- a/src/compiler/scala/reflect/reify/Errors.scala
+++ b/src/compiler/scala/reflect/reify/Errors.scala
@@ -21,6 +21,11 @@ trait Errors {
throw new ReificationException(defaultErrorPosition, msg)
}
+ def CannotReifyCompoundTypeTreeWithNonEmptyBody(ctt: CompoundTypeTree) = {
+ val msg = "implementation restriction: cannot reify refinement type trees with non-empty bodies"
+ throw new ReificationException(ctt.pos, msg)
+ }
+
def CannotReifyWeakType(details: Any) = {
val msg = "cannot create a TypeTag" + details + ": use WeakTypeTag instead"
throw new ReificationException(defaultErrorPosition, msg)
diff --git a/src/compiler/scala/reflect/reify/phases/Reshape.scala b/src/compiler/scala/reflect/reify/phases/Reshape.scala
index 50ee379c2e..bb5cb53d7d 100644
--- a/src/compiler/scala/reflect/reify/phases/Reshape.scala
+++ b/src/compiler/scala/reflect/reify/phases/Reshape.scala
@@ -180,6 +180,7 @@ trait Reshape {
private def toPreTyperCompoundTypeTree(ctt: CompoundTypeTree): Tree = {
val CompoundTypeTree(tmpl @ Template(parents, self, stats)) = ctt
+ if (stats.nonEmpty) CannotReifyCompoundTypeTreeWithNonEmptyBody(ctt)
assert(self eq emptyValDef, self)
val att = tmpl.attachments.get[CompoundTypeTreeOriginalAttachment]
val CompoundTypeTreeOriginalAttachment(parents1, stats1) = att.getOrElse(CompoundTypeTreeOriginalAttachment(parents, stats))
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index fa141e95e1..ce8e0ed37b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -270,22 +270,25 @@ trait NamesDefaults { self: Analyzer =>
*/
def argValDefs(args: List[Tree], paramTypes: List[Type], blockTyper: Typer): List[Option[ValDef]] = {
val context = blockTyper.context
- val symPs = map2(args, paramTypes)((arg, tpe) => arg match {
+ val symPs = map2(args, paramTypes)((arg, paramTpe) => arg match {
case Ident(nme.SELECTOR_DUMMY) =>
None // don't create a local ValDef if the argument is <unapply-selector>
case _ =>
- val byName = isByNameParamType(tpe)
- val repeated = isScalaRepeatedParamType(tpe)
+ val byName = isByNameParamType(paramTpe)
+ val repeated = isScalaRepeatedParamType(paramTpe)
val argTpe = (
if (repeated) arg match {
case Typed(expr, Ident(tpnme.WILDCARD_STAR)) => expr.tpe
case _ => seqType(arg.tpe)
}
- else arg.tpe
- ).widen // have to widen or types inferred from literal defaults will be singletons
+ else
+ // Note stabilizing can lead to a non-conformant argument when existentials are involved, e.g. neg/t3507-old.scala, hence the filter.
+ gen.stableTypeFor(arg).filter(_ <:< paramTpe).getOrElse(arg.tpe)
+ // We have to deconst or types inferred from literal arguments will be Constant(_), e.g. pos/z1730.scala.
+ ).deconst
val s = context.owner.newValue(unit.freshTermName("x$"), arg.pos, newFlags = ARTIFACT) setInfo (
- if (byName) functionType(Nil, argTpe) else argTpe
- )
+ if (byName) functionType(Nil, argTpe) else argTpe
+ )
Some((context.scope.enter(s), byName, repeated))
})
map2(symPs, args) {
@@ -326,11 +329,10 @@ trait NamesDefaults { self: Analyzer =>
// type the application without names; put the arguments in definition-site order
val typedApp = doTypedApply(tree, funOnly, reorderArgs(namelessArgs, argPos), mode, pt)
- if (typedApp.isErrorTyped) tree
- else typedApp match {
+ typedApp match {
// Extract the typed arguments, restore the call-site evaluation order (using
// ValDef's in the block), change the arguments to these local values.
- case Apply(expr, typedArgs) =>
+ case Apply(expr, typedArgs) if !(typedApp :: typedArgs).exists(_.isErrorTyped) => // bail out with erroneous args, see SI-7238
// typedArgs: definition-site order
val formals = formalTypes(expr.tpe.paramTypes, typedArgs.length, removeByName = false, removeRepeated = false)
// valDefs: call-site order
@@ -358,6 +360,7 @@ trait NamesDefaults { self: Analyzer =>
context.namedApplyBlockInfo =
Some((block, NamedApplyInfo(qual, targs, vargss :+ refArgs, blockTyper)))
block
+ case _ => tree
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index eaf57cd39c..92f53f4956 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1535,7 +1535,7 @@ trait Typers extends Adaptations with Tags {
atPos(supertpt.pos.focus)(supercall)
} match {
case EmptyTree => MissingTypeArgumentsParentTpeError(supertpt)
- case tpt => supertpt = TypeTree(tpt.tpe) setPos supertpt.pos.focus
+ case tpt => supertpt = TypeTree(tpt.tpe) setPos supertpt.pos // SI-7224: don't .focus positions of the TypeTree of a parent that exists in source
}
}
// this is the place where we tell the typer what argss should be used for the super call
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index a6c5367425..e1433d1893 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -2958,6 +2958,12 @@ trait Types
origin: Type,
var constr: TypeConstraint
) extends Type {
+
+ // We don't want case class equality/hashing as TypeVar-s are mutable,
+ // and TypeRefs based on them get wrongly `uniqued` otherwise. See SI-7226.
+ override def hashCode(): Int = System.identityHashCode(this)
+ override def equals(other: Any): Boolean = this eq other.asInstanceOf[AnyRef]
+
def untouchable = false // by other typevars
override def params: List[Symbol] = Nil
override def typeArgs: List[Type] = Nil
diff --git a/test/files/neg/t7235.check b/test/files/neg/t7235.check
new file mode 100644
index 0000000000..357a3dfd83
--- /dev/null
+++ b/test/files/neg/t7235.check
@@ -0,0 +1,4 @@
+t7235.scala:9: error: implementation restriction: cannot reify refinement type trees with non-empty bodies
+ val Block(List(ValDef(_, _, tpt: CompoundTypeTree, _)), _) = reify{ val x: C { def x: Int } = ??? }.tree
+ ^
+one error found
diff --git a/test/files/neg/t7235.scala b/test/files/neg/t7235.scala
new file mode 100644
index 0000000000..cfebad3fae
--- /dev/null
+++ b/test/files/neg/t7235.scala
@@ -0,0 +1,14 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{universe => ru}
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.ToolBox
+
+class C
+
+object Test extends App {
+ val Block(List(ValDef(_, _, tpt: CompoundTypeTree, _)), _) = reify{ val x: C { def x: Int } = ??? }.tree
+ println(tpt)
+ println(tpt.templ.parents)
+ println(tpt.templ.self)
+ println(tpt.templ.body)
+}
diff --git a/test/files/neg/t7238.check b/test/files/neg/t7238.check
new file mode 100644
index 0000000000..b87f83ff65
--- /dev/null
+++ b/test/files/neg/t7238.check
@@ -0,0 +1,6 @@
+t7238.scala:6: error: type mismatch;
+ found : Seq[Any]
+ required: Seq[String]
+ c.c()(Seq[Any](): _*)
+ ^
+one error found
diff --git a/test/files/neg/t7238.scala b/test/files/neg/t7238.scala
new file mode 100644
index 0000000000..d42dc8d385
--- /dev/null
+++ b/test/files/neg/t7238.scala
@@ -0,0 +1,7 @@
+trait Main {
+ trait C {
+ def c(x: Any = 0)(bs: String*)
+ }
+ def c: C
+ c.c()(Seq[Any](): _*)
+}
diff --git a/test/files/pos/t7226.scala b/test/files/pos/t7226.scala
new file mode 100644
index 0000000000..06f0c95dc4
--- /dev/null
+++ b/test/files/pos/t7226.scala
@@ -0,0 +1,26 @@
+trait HK {
+ type Rep[X]
+
+ // okay
+ def unzip2[A, B](ps: Rep[List[(A, B)]])
+ unzip2(null.asInstanceOf[Rep[List[(Int, String)]]])
+
+ // okay
+ def unzipHK[A, B, C[_]](ps: Rep[C[(A, B)]])
+ unzipHK(null.asInstanceOf[Rep[List[(Int, String)]]])
+
+ def unzipHKRet0[A, C[_]](ps: C[A]): C[Int]
+ def ls: List[String]
+ unzipHKRet0(ls)
+
+ // fail
+ def unzipHKRet[A, C[_]](ps: Rep[C[A]]): Rep[C[Int]]
+ def rls: Rep[List[String]]
+ unzipHKRet(rls)
+}
+
+trait HK1 {
+ type Rep[A]
+ def unzip1[A, B, C[_]](ps: Rep[C[(A, B)]]): (Rep[C[A]], Rep[C[B]])
+ def doUnzip1[A, B](ps: Rep[List[(A, B)]]) = unzip1(ps)
+}
diff --git a/test/files/pos/t7234.scala b/test/files/pos/t7234.scala
new file mode 100644
index 0000000000..59a233d835
--- /dev/null
+++ b/test/files/pos/t7234.scala
@@ -0,0 +1,15 @@
+trait Main {
+ trait A {
+ type B
+ }
+ trait C {
+ def c(a: A, x: Int = 0)(b: a.B)
+ }
+ def c: C
+ def d(a: A, x: Int = 0)(b: a.B)
+
+ def ok1(a: A)(b: a.B) = c.c(a, 42)(b)
+ def ok2(a: A)(b: a.B) = d(a)(b)
+
+ def fail(a: A)(b: a.B) = c.c(a)(b)
+}
diff --git a/test/files/pos/t7234b.scala b/test/files/pos/t7234b.scala
new file mode 100644
index 0000000000..fee98e87a8
--- /dev/null
+++ b/test/files/pos/t7234b.scala
@@ -0,0 +1,20 @@
+trait Main {
+ trait A {
+ type B
+ def b: B
+ }
+ trait C {
+ def c(a: A, x: Int = 0)(b: => a.B, bs: a.B*)
+ def d(a: A = null, x: Int = 0)(b1: => a.B = a.b, b2: a.B = a.b)
+ }
+ def c: C
+ def ok(a: A)(b: a.B) = c.c(a, 42)(b)
+ def fail(a: A)(b: a.B) = c.c(a)(b)
+ def fail2(a: A)(b: a.B) = c.c(a)(b, b)
+ def fail3(a: A)(b: a.B) = c.c(a)(b, Seq[a.B](b): _*)
+
+ def fail4(a: A)(b: a.B) = c.d(a)()
+ def fail5(a: A)(b: a.B) = c.d(a)(b1 = a.b)
+ def fail6(a: A)(b: a.B) = c.d(a)(b2 = a.b)
+ def fail7(a: A)(b: a.B) = c.d()()
+}
diff --git a/test/files/presentation/hyperlinks.check b/test/files/presentation/hyperlinks.check
index 85d295dd7d..1051b67e85 100644
--- a/test/files/presentation/hyperlinks.check
+++ b/test/files/presentation/hyperlinks.check
@@ -1,4 +1,4 @@
-reload: NameDefaultTests.scala, PatMatTests.scala
+reload: NameDefaultTests.scala, PatMatTests.scala, SuperTypes.scala
askHyperlinkPos for `someOtherInt` at (14,24) NameDefaultTests.scala
================================================================================
@@ -44,3 +44,138 @@ askHyperlinkPos for `y` at (25,21) PatMatTests.scala
================================================================================
[response] found askHyperlinkPos for `y` at (23,13) PatMatTests.scala
================================================================================
+
+askHyperlinkPos for `BadPos` at (10,26) SuperTypes.scala
+================================================================================
+[response] found askHyperlinkPos for `BadPos` at (2,7) SuperTypes.scala
+================================================================================
+
+askHyperlinkPos for `BadPos` at (11,26) SuperTypes.scala
+================================================================================
+[response] found askHyperlinkPos for `BadPos` at (2,7) SuperTypes.scala
+================================================================================
+
+askHyperlinkPos for `Trait` at (12,25) SuperTypes.scala
+================================================================================
+[response] found askHyperlinkPos for `Trait` at (6,7) SuperTypes.scala
+================================================================================
+
+askHyperlinkPos for `SubTrait` at (13,28) SuperTypes.scala
+================================================================================
+[response] found askHyperlinkPos for `SubTrait` at (7,7) SuperTypes.scala
+================================================================================
+
+askHyperlinkPos for `Trait` at (14,25) SuperTypes.scala
+================================================================================
+[response] found askHyperlinkPos for `Trait` at (6,7) SuperTypes.scala
+================================================================================
+
+askHyperlinkPos for `LateralTrait` at (14,48) SuperTypes.scala
+================================================================================
+[response] found askHyperlinkPos for `LateralTrait` at (8,7) SuperTypes.scala
+================================================================================
+
+askHyperlinkPos for `Base` at (15,24) SuperTypes.scala
+================================================================================
+[response] found askHyperlinkPos for `Base` at (4,7) SuperTypes.scala
+================================================================================
+
+askHyperlinkPos for `Trait` at (15,40) SuperTypes.scala
+================================================================================
+[response] found askHyperlinkPos for `Trait` at (6,7) SuperTypes.scala
+================================================================================
+
+askHyperlinkPos for `LateralTrait` at (15,63) SuperTypes.scala
+================================================================================
+[response] found askHyperlinkPos for `LateralTrait` at (8,7) SuperTypes.scala
+================================================================================
+
+askHyperlinkPos for `PBase` at (19,29) SuperTypes.scala
+================================================================================
+[response] found askHyperlinkPos for `PBase` at (17,7) SuperTypes.scala
+================================================================================
+
+askHyperlinkPos for `PTrait` at (20,33) SuperTypes.scala
+================================================================================
+[response] found askHyperlinkPos for `PTrait` at (19,7) SuperTypes.scala
+================================================================================
+
+askHyperlinkPos for `PBase` at (21,36) SuperTypes.scala
+================================================================================
+[response] found askHyperlinkPos for `PBase` at (17,7) SuperTypes.scala
+================================================================================
+
+askHyperlinkPos for `PTrait` at (23,27) SuperTypes.scala
+================================================================================
+[response] found askHyperlinkPos for `PTrait` at (19,7) SuperTypes.scala
+================================================================================
+
+askHyperlinkPos for `PSubTrait` at (24,30) SuperTypes.scala
+================================================================================
+[response] found askHyperlinkPos for `PSubTrait` at (20,7) SuperTypes.scala
+================================================================================
+
+askHyperlinkPos for `PTrait` at (25,27) SuperTypes.scala
+================================================================================
+[response] found askHyperlinkPos for `PTrait` at (19,7) SuperTypes.scala
+================================================================================
+
+askHyperlinkPos for `PLateralTrait` at (25,56) SuperTypes.scala
+================================================================================
+[response] found askHyperlinkPos for `PLateralTrait` at (21,7) SuperTypes.scala
+================================================================================
+
+askHyperlinkPos for `PBase` at (26,26) SuperTypes.scala
+================================================================================
+[response] found askHyperlinkPos for `PBase` at (17,7) SuperTypes.scala
+================================================================================
+
+askHyperlinkPos for `PTrait` at (26,48) SuperTypes.scala
+================================================================================
+[response] found askHyperlinkPos for `PTrait` at (19,7) SuperTypes.scala
+================================================================================
+
+askHyperlinkPos for `PLateralTrait` at (26,77) SuperTypes.scala
+================================================================================
+[response] found askHyperlinkPos for `PLateralTrait` at (21,7) SuperTypes.scala
+================================================================================
+
+askHyperlinkPos for `BadPos` at (28,23) SuperTypes.scala
+================================================================================
+[response] found askHyperlinkPos for `BadPos` at (2,7) SuperTypes.scala
+================================================================================
+
+askHyperlinkPos for `PTrait` at (29,23) SuperTypes.scala
+================================================================================
+[response] found askHyperlinkPos for `PTrait` at (19,7) SuperTypes.scala
+================================================================================
+
+askHyperlinkPos for `PSubTrait` at (30,26) SuperTypes.scala
+================================================================================
+[response] found askHyperlinkPos for `PSubTrait` at (20,7) SuperTypes.scala
+================================================================================
+
+askHyperlinkPos for `PTrait` at (31,23) SuperTypes.scala
+================================================================================
+[response] found askHyperlinkPos for `PTrait` at (19,7) SuperTypes.scala
+================================================================================
+
+askHyperlinkPos for `PLateralTrait` at (31,52) SuperTypes.scala
+================================================================================
+[response] found askHyperlinkPos for `PLateralTrait` at (21,7) SuperTypes.scala
+================================================================================
+
+askHyperlinkPos for `PBase` at (32,22) SuperTypes.scala
+================================================================================
+[response] found askHyperlinkPos for `PBase` at (17,7) SuperTypes.scala
+================================================================================
+
+askHyperlinkPos for `PTrait` at (32,44) SuperTypes.scala
+================================================================================
+[response] found askHyperlinkPos for `PTrait` at (19,7) SuperTypes.scala
+================================================================================
+
+askHyperlinkPos for `PLateralTrait` at (32,73) SuperTypes.scala
+================================================================================
+[response] found askHyperlinkPos for `PLateralTrait` at (21,7) SuperTypes.scala
+================================================================================
diff --git a/test/files/presentation/hyperlinks/src/SuperTypes.scala b/test/files/presentation/hyperlinks/src/SuperTypes.scala
new file mode 100644
index 0000000000..15d16069fd
--- /dev/null
+++ b/test/files/presentation/hyperlinks/src/SuperTypes.scala
@@ -0,0 +1,32 @@
+/** This tests that hyperlinking works for super types. See SI-7224 */
+class BadPos[A](a: A)
+
+class Base
+
+trait Trait extends Base
+trait SubTrait extends Trait
+trait LateralTrait extends Base
+
+object obj1 extends BadPos/*#*/(new Object)
+object obj2 extends BadPos/*#*/[AnyRef](new Object)
+object obj3 extends Trait/*#*/
+object obj4 extends SubTrait/*#*/
+object obj5 extends Trait/*#*/ with LateralTrait/*#*/
+object obj6 extends Base/*#*/ with Trait/*#*/ with LateralTrait/*#*/
+
+class PBase[A]
+
+trait PTrait[A] extends PBase/*#*/[A]
+trait PSubTrait[A] extends PTrait/*#*/[A]
+trait PLateralTrait[A] extends PBase/*#*/[A]
+
+object pobj2 extends PTrait/*#*/[Int]
+object pobj3 extends PSubTrait/*#*/[Int]
+object pobj4 extends PTrait/*#*/[Int] with PLateralTrait/*#*/[Int]
+object pobj5 extends PBase/*#*/[Int] with PTrait/*#*/[Int] with PLateralTrait/*#*/[Int]
+
+class c1 extends BadPos/*#*/(new Object)
+class c2 extends PTrait/*#*/[Int]
+class c3 extends PSubTrait/*#*/[Int]
+class c4 extends PTrait/*#*/[Int] with PLateralTrait/*#*/[Int]
+class c5 extends PBase/*#*/[Int] with PTrait/*#*/[Int] with PLateralTrait/*#*/[Int]
diff --git a/test/files/run/t5710-1.check b/test/files/run/t5710-1.check
new file mode 100644
index 0000000000..eac2025aeb
--- /dev/null
+++ b/test/files/run/t5710-1.check
@@ -0,0 +1 @@
+evaluated = (abc,abc)
diff --git a/test/files/run/t5710-1.scala b/test/files/run/t5710-1.scala
new file mode 100644
index 0000000000..12bd858e06
--- /dev/null
+++ b/test/files/run/t5710-1.scala
@@ -0,0 +1,15 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{universe => ru}
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.ToolBox
+
+object Test extends App {
+ val code = reify {
+ val (x, y) = ("abc": Any) match { case x => (x, x) }
+ (x, y)
+ };
+
+ val toolbox = cm.mkToolBox()
+ val evaluated = toolbox.eval(code.tree)
+ println("evaluated = " + evaluated)
+} \ No newline at end of file
diff --git a/test/files/run/t5710-2.check b/test/files/run/t5710-2.check
new file mode 100644
index 0000000000..eac2025aeb
--- /dev/null
+++ b/test/files/run/t5710-2.check
@@ -0,0 +1 @@
+evaluated = (abc,abc)
diff --git a/test/files/run/t5710-2.scala b/test/files/run/t5710-2.scala
new file mode 100644
index 0000000000..6d2129cca2
--- /dev/null
+++ b/test/files/run/t5710-2.scala
@@ -0,0 +1,15 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{universe => ru}
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.ToolBox
+
+object Test extends App {
+ val code = reify {
+ val (x, y) = "abc" match { case x => (x, x) }
+ (x, y)
+ };
+
+ val toolbox = cm.mkToolBox()
+ val evaluated = toolbox.eval(code.tree)
+ println("evaluated = " + evaluated)
+} \ No newline at end of file
diff --git a/test/files/run/t7235.check b/test/files/run/t7235.check
new file mode 100644
index 0000000000..9cb9c55a0c
--- /dev/null
+++ b/test/files/run/t7235.check
@@ -0,0 +1,4 @@
+C
+List(C)
+private val _ = _
+List()
diff --git a/test/files/run/t7235.scala b/test/files/run/t7235.scala
new file mode 100644
index 0000000000..6039189716
--- /dev/null
+++ b/test/files/run/t7235.scala
@@ -0,0 +1,14 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{universe => ru}
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.ToolBox
+
+class C
+
+object Test extends App {
+ val Block(List(ValDef(_, _, tpt: CompoundTypeTree, _)), _) = reify{ val x: C{} = ??? }.tree
+ println(tpt)
+ println(tpt.templ.parents)
+ println(tpt.templ.self)
+ println(tpt.templ.body)
+}