Skip to content

Commit 6d753ee

Browse files
committed
Test recheck in CompilationTests
1 parent 774d8e8 commit 6d753ee

File tree

11 files changed

+65
-4
lines changed

11 files changed

+65
-4
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ class Compiler {
9999
new TupleOptimizations, // Optimize generic operations on tuples
100100
new LetOverApply, // Lift blocks from receivers of applications
101101
new ArrayConstructors) :: // Intercept creation of (non-generic) arrays and intrinsify.
102+
List(new PreRecheck) ::
103+
List(new TestRecheck) ::
102104
List(new Erasure) :: // Rewrite types to JVM model, erasing all type parameters, abstract types and refinements.
103105
List(new ElimErasedValueType, // Expand erased value types to their underlying implmementation types
104106
new PureStats, // Remove pure stats from blocks

compiler/src/dotty/tools/dotc/config/ScalaSettings.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ private sealed trait YSettings:
238238
val YexplicitNulls: Setting[Boolean] = BooleanSetting("-Yexplicit-nulls", "Make reference types non-nullable. Nullable types can be expressed with unions: e.g. String|Null.")
239239
val YcheckInit: Setting[Boolean] = BooleanSetting("-Ysafe-init", "Ensure safe initialization of objects")
240240
val YrequireTargetName: Setting[Boolean] = BooleanSetting("-Yrequire-targetName", "Warn if an operator is defined without a @targetName annotation")
241+
val Yrecheck: Setting[Boolean] = BooleanSetting("-Yrecheck", "Run type rechecks (test only)")
241242

242243
/** Area-specific debug output */
243244
val YexplainLowlevel: Setting[Boolean] = BooleanSetting("-Yexplain-lowlevel", "When explaining type errors, show types at a lower level.")

compiler/src/dotty/tools/dotc/transform/Recheck.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ abstract class Recheck extends Phase, IdentityDenotTransformer:
2424

2525
def preRecheckPhase = this.prev.asInstanceOf[PreRecheck]
2626

27-
//override def isTyper = true
27+
override def isEnabled(using Context) = ctx.settings.Yrecheck.value
2828

2929
def run(using Context): Unit =
3030
val unit = ctx.compilationUnit
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Cannot compensate dealiasing due to false result dependency
2+
i6635a.scala
3+
4+
# Cannot handle closures with skolem types
5+
i6199b.scala
6+
i6199c.scala
7+
8+
# Skolemized type fails -Ycheck after recheck (NamedType caching problem?)
9+
i583.scala
10+

compiler/test/dotc/run-test-recheck.exludes

Whitespace-only changes.

compiler/test/dotty/tools/TestSources.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,21 @@ object TestSources {
1111

1212
def posFromTastyBlacklistFile: String = "compiler/test/dotc/pos-from-tasty.blacklist"
1313
def posTestPicklingBlacklistFile: String = "compiler/test/dotc/pos-test-pickling.blacklist"
14+
def posTestRecheckExcludesFile = "compiler/test/dotc/pos-test-recheck.exludes"
1415

1516
def posFromTastyBlacklisted: List[String] = loadList(posFromTastyBlacklistFile)
1617
def posTestPicklingBlacklisted: List[String] = loadList(posTestPicklingBlacklistFile)
18+
def posTestRecheckExcluded = loadList(posTestRecheckExcludesFile)
1719

1820
// run tests lists
1921

2022
def runFromTastyBlacklistFile: String = "compiler/test/dotc/run-from-tasty.blacklist"
2123
def runTestPicklingBlacklistFile: String = "compiler/test/dotc/run-test-pickling.blacklist"
24+
def runTestRecheckExcludesFile = "compiler/test/dotc/run-test-recheck.exludes"
2225

2326
def runFromTastyBlacklisted: List[String] = loadList(runFromTastyBlacklistFile)
2427
def runTestPicklingBlacklisted: List[String] = loadList(runTestPicklingBlacklistFile)
28+
def runTestRecheckExcluded = loadList(runTestRecheckExcludesFile)
2529

2630
// load lists
2731

compiler/test/dotty/tools/dotc/CompilationTests.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,15 @@ class CompilationTests {
218218
).checkCompile()
219219
}
220220

221+
@Test def recheck: Unit =
222+
given TestGroup = TestGroup("recheck")
223+
aggregateTests(
224+
compileFilesInDir("tests/new", recheckOptions),
225+
compileFilesInDir("tests/pos", recheckOptions, FileFilter.exclude(TestSources.posTestRecheckExcluded)),
226+
compileFilesInDir("tests/run", recheckOptions, FileFilter.exclude(TestSources.runTestRecheckExcluded))
227+
).checkCompile()
228+
229+
221230
/** The purpose of this test is three-fold, being able to compile dotty
222231
* bootstrapped, and making sure that TASTY can link against a compiled
223232
* version of Dotty, and compiling the compiler using the SemanticDB generation

compiler/test/dotty/tools/vulpix/TestConfiguration.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ object TestConfiguration {
7878
)
7979
val picklingWithCompilerOptions =
8080
picklingOptions.withClasspath(withCompilerClasspath).withRunClasspath(withCompilerClasspath)
81+
val recheckOptions = defaultOptions.and("-Yrecheck")
8182
val scala2CompatMode = defaultOptions.and("-source", "3.0-migration")
8283
val explicitUTF8 = defaultOptions and ("-encoding", "UTF8")
8384
val explicitUTF16 = defaultOptions and ("-encoding", "UTF16")

tests/neg/i6635a.scala

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
object Test {
2+
abstract class ExprBase { s =>
3+
type A
4+
}
5+
6+
abstract class Lit extends ExprBase { s =>
7+
type A = Int
8+
val n: A
9+
}
10+
11+
// It would be nice if the following could typecheck. We'd need to apply
12+
// a reasoning like this:
13+
//
14+
// Since there is an argument `e2` of type `Lit & e1.type`, it follows that
15+
// e1.type == e2.type Hence, e1.A == e2.A == Int. This looks similar
16+
// to techniques used in GADTs.
17+
//
18+
def castTestFail2a(e1: ExprBase)(e2: Lit & e1.type)(x: e1.A): Int = x // error: Found: (x : e1.A) Required: Int
19+
}

tests/pos/i6635.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,12 @@ object Test {
2727
def castTest5a(e1: ExprBase)(e2: LitU with e1.type)(x: e2.A): e1.A = x
2828
def castTest5b(e1: ExprBase)(e2: LitL with e1.type)(x: e2.A): e1.A = x
2929

30-
//fail:
3130
def castTestFail1(e1: ExprBase)(e2: Lit with e1.type)(x: e2.A): e1.A = x // this is like castTest5a/b, but with Lit instead of LitU/LitL
32-
// the other direction never works:
33-
def castTestFail2a(e1: ExprBase)(e2: Lit with e1.type)(x: e1.A): e2.A = x
31+
32+
// The next example fails rechecking. It is repeated in i6635a.scala
33+
// def castTestFail2a(e1: ExprBase)(e2: Lit with e1.type)(x: e1.A): e2.A = x
3434
def castTestFail2b(e1: ExprBase)(e2: LitL with e1.type)(x: e1.A): e2.A = x
35+
3536
def castTestFail2c(e1: ExprBase)(e2: LitU with e1.type)(x: e1.A): e2.A = x
3637

3738
// the problem isn't about order of intersections.

tests/pos/i6635a.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
object Test {
2+
abstract class ExprBase { s =>
3+
type A
4+
}
5+
6+
abstract class Lit extends ExprBase { s =>
7+
type A = Int
8+
val n: A
9+
}
10+
11+
// Fails recheck since the result type e2.A is converted to Int to avoid
12+
// a false dependency on e2.
13+
def castTestFail2a(e1: ExprBase)(e2: Lit with e1.type)(x: e1.A): e2.A = x
14+
}

0 commit comments

Comments
 (0)