Skip to content

Commit 8f48a3b

Browse files
committed
Fix issue with certain synthetics missing in compiletime.typechecks
Previously, instead of using the PostTyper phase directly, a typed tree Transformer was used. However, it did not transform the ClassInfo values using PostTyper.transformInfo, which lead to RefChecks not finding certain synthesized methods, throwing an incorrect error about a missing implementation. This is fixed by running the full suite of PostTyper transforms. A minor refactor is included, to limit the repeated CompilationUnit construction and error checking.
1 parent a5e029a commit 8f48a3b

File tree

5 files changed

+32
-20
lines changed

5 files changed

+32
-20
lines changed

Diff for: compiler/src/dotty/tools/dotc/CompilationUnit.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -158,10 +158,10 @@ object CompilationUnit {
158158
unit1
159159
}
160160

161-
/** Create a compilation unit corresponding to an in-memory String.
161+
/** Create a compilation unit corresponding to an in-memory String.
162162
* Used for `compiletime.testing.typeChecks`.
163163
*/
164-
def apply(name: String, source: String)(using Context): CompilationUnit = {
164+
def apply(name: String, source: String): CompilationUnit = {
165165
val src = SourceFile.virtual(name = name, content = source, maybeIncomplete = false)
166166
new CompilationUnit(src, null)
167167
}

Diff for: compiler/src/dotty/tools/dotc/inlines/Inlines.scala

+21-17
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,11 @@ object Inlines:
395395
case ConstantType(Constant(code: String)) =>
396396
val unitName = "tasty-reflect"
397397
val source2 = SourceFile.virtual(unitName, code)
398+
def compilationUnits(untpdTree: untpd.Tree, tpdTree: Tree): List[CompilationUnit] =
399+
val compilationUnit = CompilationUnit(unitName, code)
400+
compilationUnit.tpdTree = tpdTree
401+
compilationUnit.untpdTree = untpdTree
402+
List(compilationUnit)
398403
// We need a dummy owner, as the actual one does not have a computed denotation yet,
399404
// but might be inspected in a transform phase, leading to cyclic errors
400405
val dummyOwner = newSymbol(ctx.owner, "$dummySymbol$".toTermName, Private, defn.AnyType, NoSymbol)
@@ -407,31 +412,30 @@ object Inlines:
407412
.withOwner(dummyOwner)
408413

409414
inContext(newContext) {
410-
val tree2 = new Parser(source2).block()
411-
if ctx.reporter.allErrors.nonEmpty then
415+
def noErrors = ctx.reporter.allErrors.isEmpty
416+
val untpdTree = new Parser(source2).block()
417+
if !noErrors then
412418
ctx.reporter.allErrors.map((ErrorKind.Parser, _))
413419
else
414-
val tree3 = ctx.typer.typed(tree2)
420+
val tpdTree1 = ctx.typer.typed(untpdTree)
415421
ctx.base.postTyperPhase match
416-
case postTyper: PostTyper if ctx.reporter.allErrors.isEmpty =>
417-
val tree4 = atPhase(postTyper) { postTyper.newTransformer.transform(tree3) }
422+
case postTyper: PostTyper if noErrors =>
423+
val tpdTree2 =
424+
atPhase(postTyper) { postTyper.runOn(compilationUnits(untpdTree, tpdTree1)).head.tpdTree }
418425
ctx.base.setRootTreePhase match
419-
case setRootTree =>
420-
val tree5 =
421-
val compilationUnit = CompilationUnit(unitName, code)
422-
compilationUnit.tpdTree = tree4
423-
compilationUnit.untpdTree = tree2
424-
var units = List(compilationUnit)
425-
atPhase(setRootTree)(setRootTree.runOn(units).head.tpdTree)
426+
case setRootTree if noErrors => // might be noPhase, if -Yretain-trees is not used
427+
val tpdTree3 =
428+
atPhase(setRootTree)(setRootTree.runOn(compilationUnits(untpdTree, tpdTree2)).head.tpdTree)
426429
ctx.base.inliningPhase match
427-
case inlining: Inlining if ctx.reporter.allErrors.isEmpty =>
428-
val tree6 = atPhase(inlining) { inlining.newTransformer.transform(tree5) }
429-
if ctx.reporter.allErrors.isEmpty && reconstructedTransformPhases.nonEmpty then
430-
var transformTree = tree6
430+
case inlining: Inlining if noErrors =>
431+
val tpdTree4 = atPhase(inlining) { inlining.newTransformer.transform(tpdTree3) }
432+
if noErrors && reconstructedTransformPhases.nonEmpty then
433+
var transformTree = tpdTree4
431434
for phase <- reconstructedTransformPhases do
432-
if ctx.reporter.allErrors.isEmpty then
435+
if noErrors then
433436
transformTree = atPhase(phase.end + 1)(phase.transformUnit(transformTree))
434437
case _ =>
438+
case _ =>
435439
case _ =>
436440
ctx.reporter.allErrors.map((ErrorKind.Typer, _))
437441
}

Diff for: compiler/test/dotc/run-test-pickling.excludelist

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,4 @@ named-tuples-strawman-2.scala
4949
# typecheckErrors method unpickling
5050
typeCheckErrors.scala
5151
i18150.scala
52-
52+
i22968.scala

Diff for: tests/run/i22968.check

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
List()

Diff for: tests/run/i22968.scala

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import scala.compiletime.testing.typeCheckErrors
2+
3+
object Test {
4+
def main(args: Array[String]): Unit = {
5+
println(typeCheckErrors("enum Foo { case A }"))
6+
}
7+
}

0 commit comments

Comments
 (0)