From 7863e97c32b02b22496688b130941f24ef60ffdd Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Tue, 11 May 2021 12:44:22 +0200 Subject: [PATCH] Tasty: set experimental to zero --- tasty/src/dotty/tools/tasty/TastyFormat.scala | 19 +++++++-- .../tools/tasty/TastyVersionFormatTest.scala | 42 +++++++++++-------- 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/tasty/src/dotty/tools/tasty/TastyFormat.scala b/tasty/src/dotty/tools/tasty/TastyFormat.scala index f8c077c0aa0b..5fc64f6c08a9 100644 --- a/tasty/src/dotty/tools/tasty/TastyFormat.scala +++ b/tasty/src/dotty/tools/tasty/TastyFormat.scala @@ -301,14 +301,27 @@ object TastyFormat { * is able to read final TASTy documents if the file's * `MinorVersion` is strictly less than the current value. */ - final val ExperimentalVersion: Int = 3 + final val ExperimentalVersion: Int = 0 /**This method implements a binary relation (`<:<`) between two TASTy versions. + * * We label the lhs `file` and rhs `compiler`. * if `file <:< compiler` then the TASTy file is valid to be read. * - * TASTy versions have a partial order, - * for example `a <:< b` and `b <:< a` are both false if `a` and `b` have different major versions. + * A TASTy version, e.g. `v := 28.0-3` is composed of three fields: + * - v.major == 28 + * - v.minor == 0 + * - v.experimental == 3 + * + * TASTy versions have a partial order, for example, + * `a <:< b` and `b <:< a` are both false if + * - `a` and `b` have different `major` fields. + * - `a` and `b` have different `experimental` fields, both non-zero. + * + * A zero value for an `experimental` field is considered + * to be a stable TASTy version, and has higher precedence + * than a TASTy version with the same `major`/`minor` fields + * but a non-zero `experimental` field. * * We follow the given algorithm: * ``` diff --git a/tasty/test/dotty/tools/tasty/TastyVersionFormatTest.scala b/tasty/test/dotty/tools/tasty/TastyVersionFormatTest.scala index b5cb58910e36..3e29c9baaf81 100644 --- a/tasty/test/dotty/tools/tasty/TastyVersionFormatTest.scala +++ b/tasty/test/dotty/tools/tasty/TastyVersionFormatTest.scala @@ -11,61 +11,69 @@ class TastyVersionFormatTest { import TastyVersionFormatTest._ /** aliases `TastyVersion.apply` */ - def compiler(major: Int, minor: Int, experimental: Int) = TastyVersion(major, minor, experimental) + def compiler(major: Int, minor: Int, experimental: Experimental) = TastyVersion(major, minor, experimental) /** aliases `TastyVersion.apply` */ - def file(major: Int, minor: Int, experimental: Int) = TastyVersion(major, minor, experimental) + def file(major: Int, minor: Int, experimental: Experimental) = TastyVersion(major, minor, experimental) @Test def accept_ExperimentalReadEQExperimental_EQMinor: Unit = { - assert(file(28,1,1) <:< compiler(28,1,1)) // same minor, same experimental + assert(file(28,1,Exp(1)) <:< compiler(28,1,Exp(1))) // same minor, same experimental } @Test def accept_ExperimentalReadFinal_LTMinor: Unit = { - assert(file(28,0,0) <:< compiler(28,1,1)) // preceding minor + assert(file(28,0,Final) <:< compiler(28,1,Exp(1))) // preceding minor } @Test def accept_FinalReadFinal_LTEqualMinor: Unit = { - assert(file(28,0,0) <:< compiler(28,1,0)) // preceding minor - assert(file(28,0,0) <:< compiler(28,0,0)) // same minor + assert(file(28,0,Final) <:< compiler(28,1,Final)) // preceding minor + assert(file(28,0,Final) <:< compiler(28,0,Final)) // same minor } /** these cases are unrelated because a final compiler can only read final tasty of <= minor version */ @Test def reject_FinalReadFinal_GTMinor: Unit = { - assert(file(28,2,0) unrelatedTo compiler(28,1,0)) // succeeding minor + assert(file(28,2,Final) unrelatedTo compiler(28,1,Final)) // succeeding minor } /** these cases are unrelated because a final compiler can not read experimental tasty */ @Test def reject_FinalReadExperimental: Unit = { - assert(file(28,0,1) unrelatedTo compiler(28,1,0)) // preceding minor - assert(file(28,1,1) unrelatedTo compiler(28,1,0)) // same minor - assert(file(28,2,1) unrelatedTo compiler(28,1,0)) // succeeding minor + assert(file(28,0,Exp(1)) unrelatedTo compiler(28,1,Final)) // preceding minor + assert(file(28,1,Exp(1)) unrelatedTo compiler(28,1,Final)) // same minor + assert(file(28,2,Exp(1)) unrelatedTo compiler(28,1,Final)) // succeeding minor } /** These cases are unrelated because an experimental compiler can only read final tasty of < minor version */ @Test def reject_ExperimentalReadFinal_GTEqualMinor: Unit = { - assert(file(28,2,0) unrelatedTo compiler(28,1,1)) // succeeding minor - assert(file(28,1,0) unrelatedTo compiler(28,1,1)) // equal minor + assert(file(28,2,Final) unrelatedTo compiler(28,1,Exp(1))) // succeeding minor + assert(file(28,1,Final) unrelatedTo compiler(28,1,Exp(1))) // equal minor } /**These cases are unrelated because both compiler and file are experimental, * and with unequal experimental part. */ @Test def reject_ExperimentalReadNEExperimental: Unit = { - assert(file(28,1,2) unrelatedTo compiler(28,1,1)) // same minor version, succeeding experimental - assert(file(28,1,1) unrelatedTo compiler(28,1,2)) // same minor version, preceding experimental + assert(file(28,1,Exp(2)) unrelatedTo compiler(28,1,Exp(1))) // same minor version, succeeding experimental + assert(file(28,1,Exp(1)) unrelatedTo compiler(28,1,Exp(2))) // same minor version, preceding experimental } /** these cases are unrelated because the major version must be identical */ @Test def reject_NEMajor: Unit = { - assert(file(27,0,0) unrelatedTo compiler(28,0,0)) // less than - assert(file(29,0,0) unrelatedTo compiler(28,0,0)) // greater than + assert(file(27,0,Final) unrelatedTo compiler(28,0,Final)) // less than + assert(file(29,0,Final) unrelatedTo compiler(28,0,Final)) // greater than } } object TastyVersionFormatTest { - case class TastyVersion(major: Int, minor: Int, experimental: Int) { file => + type Experimental = Int + val Final: Experimental = 0 + def Exp(i: Int): Experimental = i.ensuring(_ > 0) + + case class TastyVersion(major: Int, minor: Int, experimental: Experimental) { file => + assert(major >= 0) + assert(minor >= 0) + assert(experimental >= 0) + def <:<(compiler: TastyVersion): Boolean = TastyFormat.isVersionCompatible( fileMajor = file.major, fileMinor = file.minor,