Skip to content

Commit 70946d7

Browse files
committed
Better tests and bugfix for named args
The original problem was that in an expression f(x = bar(y = z)) only the outer named arg was eliminated by FirstTransform. The first error was that the postcondition in FirstTransform did not get to the named arg, because it got called from the overrdden typed method in TreeChecker, yet function arguments were evaluated with typedUnadapted. action: change Retyper and TreeChecker to override typedUndapped instead of typed. This flushed out the second error: transformOther in FirstTransform needs to recursively transform the argument of a NamedArg, because the framework itself does not handle NamedArg nodes. Now, all tests pass except that TreeChecker itself fails -Ycheck:gettersSetters due to a problem with handling by-name function types. This should be fixed in a separate PR.
1 parent f459bf0 commit 70946d7

File tree

5 files changed

+24
-13
lines changed

5 files changed

+24
-13
lines changed

src/dotty/tools/dotc/Compiler.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ class Compiler {
5353
new Literalize,
5454
new GettersSetters),
5555
List(new Erasure),
56-
List(new CapturedVars, new Constructors),
56+
List(new CapturedVars,
57+
new Constructors),
5758
List(new LambdaLift)
5859
)
5960

src/dotty/tools/dotc/transform/FirstTransform.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ class FirstTransform extends MiniPhaseTransform with IdentityDenotTransformer {
123123

124124
override def transformOther(tree: Tree)(implicit ctx: Context, info: TransformerInfo) = tree match {
125125
case tree: Import => EmptyTree
126-
case tree: NamedArg => tree.arg
126+
case tree: NamedArg => transform(tree.arg)
127127
case AppliedTypeTree(tycon, args) =>
128128
val tparams = tycon.tpe.typeSymbol.typeParams
129129
Checking.checkBounds(

src/dotty/tools/dotc/transform/TreeChecker.scala

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,13 @@ class TreeChecker {
5454
val checkingCtx = ctx.fresh
5555
.setTyperState(ctx.typerState.withReporter(new ThrowingReporter(ctx.typerState.reporter)))
5656
val checker = new Checker(previousPhases(phasesToRun.toList)(ctx))
57-
checker.typedExpr(ctx.compilationUnit.tpdTree)(checkingCtx)
57+
try checker.typedExpr(ctx.compilationUnit.tpdTree)(checkingCtx)
58+
catch {
59+
case ex: Throwable =>
60+
implicit val ctx: Context = checkingCtx
61+
println(i"*** error while checking after phase ${checkingCtx.phase.prev} ***")
62+
throw ex
63+
}
5864
}
5965

6066
class Checker(phasesToCheck: Seq[Phase]) extends ReTyper {
@@ -84,17 +90,17 @@ class TreeChecker {
8490
if (tree.symbol.maybeOwner.isTerm)
8591
assert(definedSyms contains tree.symbol, i"undefined symbol ${tree.symbol}")
8692

87-
override def typed(tree: untpd.Tree, pt: Type)(implicit ctx: Context) = {
93+
override def typedUnadapted(tree: untpd.Tree, pt: Type)(implicit ctx: Context): tpd.Tree = {
8894
val res = tree match {
8995
case _: untpd.UnApply =>
9096
// can't recheck patterns
9197
tree.asInstanceOf[tpd.Tree]
9298
case _: untpd.TypedSplice | _: untpd.Thicket | _: EmptyValDef[_] =>
93-
super.typed(tree)
99+
super.typedUnadapted(tree)
94100
case _ if tree.isType =>
95101
promote(tree)
96102
case _ =>
97-
val tree1 = super.typed(tree, pt)
103+
val tree1 = super.typedUnadapted(tree, pt)
98104
def isSubType(tp1: Type, tp2: Type) =
99105
(tp1 eq tp2) || // accept NoType / NoType
100106
(tp1 <:< tp2)
@@ -106,9 +112,10 @@ class TreeChecker {
106112
|After checking: ${tree1.show}
107113
|Why different :
108114
""".stripMargin + core.TypeComparer.explained((tp1 <:< tp2)(_))
109-
assert(isSubType(tree1.tpe, tree.typeOpt), divergenceMsg(tree1.tpe, tree.typeOpt))
115+
if (tree.hasType) // it might not be typed because Typer sometimes constructs new untyped trees and resubmits them to typedUnadapted
116+
assert(isSubType(tree1.tpe, tree.typeOpt), divergenceMsg(tree1.tpe, tree.typeOpt))
110117
tree1
111-
}
118+
}
112119
phasesToCheck.foreach(_.checkPostCondition(res))
113120
res
114121
}
@@ -183,10 +190,13 @@ class TreeChecker {
183190
override def adapt(tree: Tree, pt: Type, original: untpd.Tree = untpd.EmptyTree)(implicit ctx: Context) = {
184191
def isPrimaryConstructorReturn =
185192
ctx.owner.isPrimaryConstructor && pt.isRef(ctx.owner.owner) && tree.tpe.isRef(defn.UnitClass)
186-
if (ctx.mode.isExpr && !isPrimaryConstructorReturn && !pt.isInstanceOf[FunProto])
193+
if (ctx.mode.isExpr &&
194+
!tree.isEmpty &&
195+
!isPrimaryConstructorReturn &&
196+
!pt.isInstanceOf[FunProto])
187197
assert(tree.tpe <:< pt,
188198
s"error at ${sourcePos(tree.pos)}\n" +
189-
err.typeMismatchStr(tree.tpe, pt))
199+
err.typeMismatchStr(tree.tpe, pt) + "tree = " + tree)
190200
tree
191201
}
192202
}

src/dotty/tools/dotc/typer/ReTyper.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ class ReTyper extends Typer {
8787
super.handleUnexpectedFunType(tree, fun)
8888
}
8989

90-
override def typed(tree: untpd.Tree, pt: Type)(implicit ctx: Context) =
91-
try super.typed(tree, pt)
90+
override def typedUnadapted(tree: untpd.Tree, pt: Type)(implicit ctx: Context) =
91+
try super.typedUnadapted(tree, pt)
9292
catch {
9393
case ex: Throwable =>
9494
println(i"exception while typing $tree of class ${tree.getClass} # ${tree.uniqueId}")

test/dotc/tests.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ class tests extends CompilerTest {
106106
@Test def dotc_core = compileDir(dotcDir + "tools/dotc/core", twice)(allowDeepSubtypes)
107107
@Test def dotc_core_pickling = compileDir(dotcDir + "tools/dotc/core/pickling", twice)(allowDeepSubtypes)
108108

109-
//@Test def dotc_transform = compileDir(dotcDir + "tools/dotc/transform", twice)
109+
@Test def dotc_transform = compileDir(dotcDir + "tools/dotc/transform", twice)(defaultOptions ++ List("-Ycheck:pat,era,lam"))
110110
//disabled, awaiting fix for call-by-name function types.
111111

112112
@Test def dotc_parsing = compileDir(dotcDir + "tools/dotc/parsing", twice)

0 commit comments

Comments
 (0)