Skip to content

Commit b671a13

Browse files
jchybtgodzik
authored andcommitted
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. [Cherry-picked 8f48a3b]
1 parent 56b2d42 commit b671a13

File tree

5 files changed

+31
-19
lines changed

5 files changed

+31
-19
lines changed

compiler/src/dotty/tools/dotc/CompilationUnit.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ object CompilationUnit {
134134
/** Create a compilation unit corresponding to an in-memory String.
135135
* Used for `compiletime.testing.typeChecks`.
136136
*/
137-
def apply(name: String, source: String)(using Context): CompilationUnit = {
137+
def apply(name: String, source: String): CompilationUnit = {
138138
val src = SourceFile.virtual(name = name, content = source, maybeIncomplete = false)
139139
new CompilationUnit(src)
140140
}

compiler/src/dotty/tools/dotc/inlines/Inlines.scala

+21-17
Original file line numberDiff line numberDiff line change
@@ -393,38 +393,42 @@ object Inlines:
393393
case ConstantType(Constant(code: String)) =>
394394
val unitName = "tasty-reflect"
395395
val source2 = SourceFile.virtual(unitName, code)
396+
def compilationUnits(untpdTree: untpd.Tree, tpdTree: Tree): List[CompilationUnit] =
397+
val compilationUnit = CompilationUnit(unitName, code)
398+
compilationUnit.tpdTree = tpdTree
399+
compilationUnit.untpdTree = untpdTree
400+
List(compilationUnit)
396401
// We need a dummy owner, as the actual one does not have a computed denotation yet,
397402
// but might be inspected in a transform phase, leading to cyclic errors
398403
val dummyOwner = newSymbol(ctx.owner, "$dummySymbol$".toTermName, Private, defn.AnyType, NoSymbol)
399404
val newContext =
400405
ctx.fresh.setNewTyperState().setTyper(new Typer(ctx.nestingLevel + 1)).setSource(source2)
401406

402407
inContext(newContext) {
403-
val tree2 = new Parser(source2).block()
404-
if ctx.reporter.allErrors.nonEmpty then
408+
def noErrors = ctx.reporter.allErrors.isEmpty
409+
val untpdTree = new Parser(source2).block()
410+
if !noErrors then
405411
ctx.reporter.allErrors.map((ErrorKind.Parser, _))
406412
else
407-
val tree3 = ctx.typer.typed(tree2)
413+
val tpdTree1 = ctx.typer.typed(untpdTree)
408414
ctx.base.postTyperPhase match
409-
case postTyper: PostTyper if ctx.reporter.allErrors.isEmpty =>
410-
val tree4 = atPhase(postTyper) { postTyper.newTransformer.transform(tree3) }
415+
case postTyper: PostTyper if noErrors =>
416+
val tpdTree2 =
417+
atPhase(postTyper) { postTyper.runOn(compilationUnits(untpdTree, tpdTree1)).head.tpdTree }
411418
ctx.base.setRootTreePhase match
412-
case setRootTree =>
413-
val tree5 =
414-
val compilationUnit = CompilationUnit(unitName, code)
415-
compilationUnit.tpdTree = tree4
416-
compilationUnit.untpdTree = tree2
417-
var units = List(compilationUnit)
418-
atPhase(setRootTree)(setRootTree.runOn(units).head.tpdTree)
419+
case setRootTree if noErrors => // might be noPhase, if -Yretain-trees is not used
420+
val tpdTree3 =
421+
atPhase(setRootTree)(setRootTree.runOn(compilationUnits(untpdTree, tpdTree2)).head.tpdTree)
419422
ctx.base.inliningPhase match
420-
case inlining: Inlining if ctx.reporter.allErrors.isEmpty =>
421-
val tree6 = atPhase(inlining) { inlining.newTransformer.transform(tree5) }
422-
if ctx.reporter.allErrors.isEmpty && reconstructedTransformPhases.nonEmpty then
423-
var transformTree = tree6
423+
case inlining: Inlining if noErrors =>
424+
val tpdTree4 = atPhase(inlining) { inlining.newTransformer.transform(tpdTree3) }
425+
if noErrors && reconstructedTransformPhases.nonEmpty then
426+
var transformTree = tpdTree4
424427
for phase <- reconstructedTransformPhases do
425-
if ctx.reporter.allErrors.isEmpty then
428+
if noErrors then
426429
transformTree = atPhase(phase.end + 1)(phase.transformUnit(transformTree))
427430
case _ =>
431+
case _ =>
428432
case _ =>
429433
ctx.reporter.allErrors.map((ErrorKind.Typer, _))
430434
}

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

tests/run/i22968.check

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

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)