Skip to content

Commit c5710d0

Browse files
authored
Merge pull request #15146 from dotty-staging/remove-scala-output-version
Remove support for `-scala-output-version` flag
2 parents 741bbad + 554a3a0 commit c5710d0

File tree

45 files changed

+24
-359
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+24
-359
lines changed

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@ trait CommonScalaSettings:
106106
val silentWarnings: Setting[Boolean] = BooleanSetting("-nowarn", "Silence all warnings.", aliases = List("--no-warnings"))
107107

108108
val javaOutputVersion: Setting[String] = ChoiceSetting("-java-output-version", "version", "Compile code with classes specific to the given version of the Java platform available on the classpath and emit bytecode for this version. Corresponds to -release flag in javac.", ScalaSettings.supportedReleaseVersions, "", aliases = List("-release", "--release"))
109-
val scalaOutputVersion: Setting[String] = ChoiceSetting("-scala-output-version", "version", "Emit TASTy files that can be consumed by specified version of the compiler. The compilation will fail if for any reason valid TASTy cannot be produced (e.g. the code contains references to some parts of the standard library API that are missing in the older stdlib or uses language features unexpressible in the older version of TASTy format)", ScalaSettings.supportedScalaReleaseVersions, "")
110109

111110
val deprecation: Setting[Boolean] = BooleanSetting("-deprecation", "Emit warning and location for usages of deprecated APIs.", aliases = List("--deprecation"))
112111
val feature: Setting[Boolean] = BooleanSetting("-feature", "Emit warning and location for usages of features that should be imported explicitly.", aliases = List("--feature"))

compiler/src/dotty/tools/dotc/core/Contexts.scala

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import io.{AbstractFile, NoAbstractFile, PlainFile, Path}
2424
import scala.io.Codec
2525
import collection.mutable
2626
import printing._
27-
import config.{JavaPlatform, SJSPlatform, Platform, ScalaSettings, ScalaRelease}
27+
import config.{JavaPlatform, SJSPlatform, Platform, ScalaSettings}
2828
import classfile.ReusableDataReader
2929
import StdNames.nme
3030

@@ -38,9 +38,6 @@ import xsbti.AnalysisCallback
3838
import plugins._
3939
import java.util.concurrent.atomic.AtomicInteger
4040
import java.nio.file.InvalidPathException
41-
import dotty.tools.tasty.TastyFormat
42-
import dotty.tools.dotc.config.{ NoScalaVersion, SpecificScalaVersion, AnyScalaVersion, ScalaBuild }
43-
import dotty.tools.dotc.core.tasty.TastyVersion
4441

4542
object Contexts {
4643

@@ -478,22 +475,7 @@ object Contexts {
478475

479476
/** A new context that summarizes an import statement */
480477
def importContext(imp: Import[?], sym: Symbol): FreshContext =
481-
fresh.setImportInfo(ImportInfo(sym, imp.selectors, imp.expr))
482-
483-
def scalaRelease: ScalaRelease =
484-
val releaseName = base.settings.scalaOutputVersion.value
485-
if releaseName.nonEmpty then ScalaRelease.parse(releaseName).get else ScalaRelease.latest
486-
487-
def tastyVersion: TastyVersion =
488-
import math.Ordered.orderingToOrdered
489-
val latestRelease = ScalaRelease.latest
490-
val specifiedRelease = scalaRelease
491-
if specifiedRelease < latestRelease then
492-
// This is needed to make -scala-output-version a no-op when set to the latest release for unstable versions of the compiler
493-
// (which might have the tasty format version numbers set to higher values before they're decreased during a release)
494-
TastyVersion.fromStableScalaRelease(specifiedRelease.majorVersion, specifiedRelease.minorVersion)
495-
else
496-
TastyVersion.compilerVersion
478+
fresh.setImportInfo(ImportInfo(sym, imp.selectors, imp.expr))
497479

498480
/** Is the debug option set? */
499481
def debug: Boolean = base.settings.Ydebug.value

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -988,7 +988,6 @@ class Definitions {
988988
@tu lazy val FunctionalInterfaceAnnot: ClassSymbol = requiredClass("java.lang.FunctionalInterface")
989989
@tu lazy val TargetNameAnnot: ClassSymbol = requiredClass("scala.annotation.targetName")
990990
@tu lazy val VarargsAnnot: ClassSymbol = requiredClass("scala.annotation.varargs")
991-
@tu lazy val SinceAnnot: ClassSymbol = requiredClass("scala.annotation.since")
992991

993992
@tu lazy val JavaRepeatableAnnot: ClassSymbol = requiredClass("java.lang.annotation.Repeatable")
994993

compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import java.util.UUID
2020
import scala.collection.immutable
2121
import scala.collection.mutable.{ ListBuffer, ArrayBuffer }
2222
import scala.annotation.switch
23-
import tasty.TastyVersion
2423
import typer.Checking.checkNonCyclic
2524
import io.{AbstractFile, ZipArchive}
2625
import scala.util.control.NonFatal
@@ -914,7 +913,7 @@ class ClassfileParser(
914913
}
915914

916915
def unpickleTASTY(bytes: Array[Byte]): Some[Embedded] = {
917-
val unpickler = new tasty.DottyUnpickler(bytes, ctx.tastyVersion)
916+
val unpickler = new tasty.DottyUnpickler(bytes)
918917
unpickler.enter(roots = Set(classRoot, moduleRoot, moduleRoot.sourceModule))(using ctx.withSource(util.NoSource))
919918
Some(unpickler)
920919
}
@@ -980,37 +979,9 @@ class ClassfileParser(
980979
if (tastyBytes.nonEmpty) {
981980
val reader = new TastyReader(bytes, 0, 16)
982981
val expectedUUID = new UUID(reader.readUncompressedLong(), reader.readUncompressedLong())
983-
val tastyHeader = new TastyHeaderUnpickler(tastyBytes).readFullHeader()
984-
val fileTastyVersion = TastyVersion(tastyHeader.majorVersion, tastyHeader.minorVersion, tastyHeader.experimentalVersion)
985-
val tastyUUID = tastyHeader.uuid
982+
val tastyUUID = new TastyHeaderUnpickler(tastyBytes).readHeader()
986983
if (expectedUUID != tastyUUID)
987984
report.warning(s"$classfile is out of sync with its TASTy file. Loaded TASTy file. Try cleaning the project to fix this issue", NoSourcePosition)
988-
989-
val tastyFilePath = classfile.path.stripSuffix(".class") + ".tasty"
990-
991-
def reportWrongTasty(reason: String, highestAllowed: TastyVersion) =
992-
report.error(s"""The class ${classRoot.symbol.showFullName} cannot be loaded from file ${tastyFilePath} because $reason:
993-
|highest allowed: ${highestAllowed.show}
994-
|found: ${fileTastyVersion.show}
995-
""".stripMargin)
996-
997-
val isTastyReadable = fileTastyVersion.isCompatibleWith(TastyVersion.compilerVersion)
998-
if !isTastyReadable then
999-
reportWrongTasty("its TASTy format cannot be read by the compiler", TastyVersion.compilerVersion)
1000-
else
1001-
def isStdlibClass(cls: ClassDenotation): Boolean =
1002-
ctx.platform.classPath.findClassFile(cls.fullName.mangledString) match {
1003-
case Some(entry: ZipArchive#Entry) =>
1004-
entry.underlyingSource.map(_.name.startsWith("scala3-library_")).getOrElse(false)
1005-
case _ => false
1006-
}
1007-
// While emitting older TASTy the the newer standard library used by the compiler will still be on the class path so trying to read its TASTy files should not cause a crash.
1008-
// This is OK however because references to elements of stdlib API are validated according to the values of their `@since` annotations.
1009-
// This should guarantee that the code won't crash at runtime when used with the stdlib provided by an older compiler.
1010-
val isTastyCompatible = fileTastyVersion.isCompatibleWith(ctx.tastyVersion) || isStdlibClass(classRoot)
1011-
if !isTastyCompatible then
1012-
reportWrongTasty(s"its TASTy format is not compatible with the one of the targeted Scala release (${ctx.scalaRelease.show})", ctx.tastyVersion)
1013-
1014985
return unpickleTASTY(tastyBytes)
1015986
}
1016987
}

compiler/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ object DottyUnpickler {
4141
* @param bytes the bytearray containing the Tasty file from which we unpickle
4242
* @param mode the tasty file contains package (TopLevel), an expression (Term) or a type (TypeTree)
4343
*/
44-
class DottyUnpickler(bytes: Array[Byte], maximalTastyVersion: TastyVersion, mode: UnpickleMode = UnpickleMode.TopLevel) extends ClassfileParser.Embedded with tpd.TreeProvider {
44+
class DottyUnpickler(bytes: Array[Byte], mode: UnpickleMode = UnpickleMode.TopLevel) extends ClassfileParser.Embedded with tpd.TreeProvider {
4545
import tpd._
4646
import DottyUnpickler._
4747

compiler/src/dotty/tools/dotc/core/tasty/TastyPickler.scala

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ import dotty.tools.tasty.{TastyBuffer, TastyFormat, TastyHash}
99
import TastyFormat._
1010
import TastyBuffer._
1111

12-
import Contexts._
13-
1412
import collection.mutable
1513
import core.Symbols.ClassSymbol
1614
import Decorators._
@@ -33,7 +31,7 @@ class TastyPickler(val rootCls: ClassSymbol) {
3331
def newSection(name: String, buf: TastyBuffer): Unit =
3432
sections += ((nameBuffer.nameIndex(name.toTermName), buf))
3533

36-
def assembleParts()(using Context): Array[Byte] = {
34+
def assembleParts(): Array[Byte] = {
3735
def lengthWithLength(buf: TastyBuffer) =
3836
buf.length + natSize(buf.length)
3937

@@ -43,8 +41,6 @@ class TastyPickler(val rootCls: ClassSymbol) {
4341
val nameBufferHash = TastyHash.pjwHash64(nameBuffer.bytes)
4442
val treeSectionHash +: otherSectionHashes = sections.map(x => TastyHash.pjwHash64(x._2.bytes))
4543

46-
val tastyVersion = ctx.tastyVersion
47-
4844
// Hash of name table and tree
4945
val uuidLow: Long = nameBufferHash ^ treeSectionHash
5046
// Hash of positions, comments and any additional section
@@ -53,9 +49,9 @@ class TastyPickler(val rootCls: ClassSymbol) {
5349
val headerBuffer = {
5450
val buf = new TastyBuffer(header.length + TastyPickler.versionStringBytes.length + 32)
5551
for (ch <- header) buf.writeByte(ch.toByte)
56-
buf.writeNat(tastyVersion.major)
57-
buf.writeNat(tastyVersion.minor)
58-
buf.writeNat(tastyVersion.experimental)
52+
buf.writeNat(MajorVersion)
53+
buf.writeNat(MinorVersion)
54+
buf.writeNat(ExperimentalVersion)
5955
buf.writeNat(TastyPickler.versionStringBytes.length)
6056
buf.writeBytes(TastyPickler.versionStringBytes, TastyPickler.versionStringBytes.length)
6157
buf.writeUncompressedLong(uuidLow)

compiler/src/dotty/tools/dotc/core/tasty/TastyVersion.scala

Lines changed: 0 additions & 23 deletions
This file was deleted.

compiler/src/dotty/tools/dotc/quoted/PickledQuotes.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ object PickledQuotes {
251251
quotePickling.println(s"**** unpickling quote from TASTY\n${TastyPrinter.showContents(bytes, ctx.settings.color.value == "never")}")
252252

253253
val mode = if (isType) UnpickleMode.TypeTree else UnpickleMode.Term
254-
val unpickler = new DottyUnpickler(bytes, ctx.tastyVersion, mode)
254+
val unpickler = new DottyUnpickler(bytes, mode)
255255
unpickler.enter(Set.empty)
256256

257257
val tree = unpickler.tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ class Pickler extends Phase {
128128
ctx.initialize()
129129
val unpicklers =
130130
for ((cls, pickler) <- picklers) yield {
131-
val unpickler = new DottyUnpickler(pickler.assembleParts(), ctx.tastyVersion)
131+
val unpickler = new DottyUnpickler(pickler.assembleParts())
132132
unpickler.enter(roots = Set.empty)
133133
cls -> unpickler
134134
}

compiler/src/dotty/tools/dotc/typer/CrossVersionChecks.scala

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ class CrossVersionChecks extends MiniPhase:
2929
private def checkUndesiredProperties(sym: Symbol, pos: SrcPos)(using Context): Unit =
3030
checkDeprecated(sym, pos)
3131
checkExperimentalRef(sym, pos)
32-
checkSinceAnnot(sym, pos)
3332

3433
val xMigrationValue = ctx.settings.Xmigration.value
3534
if xMigrationValue != NoScalaVersion then
@@ -85,29 +84,6 @@ class CrossVersionChecks extends MiniPhase:
8584
for annot <- sym.annotations if annot.symbol.isExperimental do
8685
Feature.checkExperimentalDef(annot.symbol, annot.tree)
8786

88-
private def checkSinceAnnot(sym: Symbol, pos: SrcPos)(using Context): Unit =
89-
for
90-
annot <- sym.getAnnotation(defn.SinceAnnot)
91-
releaseName <- annot.argumentConstantString(0)
92-
do
93-
ScalaRelease.parse(releaseName) match
94-
case Some(release) if release > ctx.scalaRelease =>
95-
report.error(
96-
i"$sym was added in Scala release ${releaseName.show}, therefore it cannot be used in the code targeting Scala ${ctx.scalaRelease.show}",
97-
pos)
98-
case None =>
99-
report.error(i"$sym has an unparsable release name: '${releaseName}'", annot.tree.srcPos)
100-
case _ =>
101-
102-
private def checkSinceAnnotInSignature(sym: Symbol, pos: SrcPos)(using Context) =
103-
new TypeTraverser:
104-
def traverse(tp: Type) =
105-
if tp.typeSymbol.hasAnnotation(defn.SinceAnnot) then
106-
checkSinceAnnot(tp.typeSymbol, pos)
107-
else
108-
traverseChildren(tp)
109-
.traverse(sym.info)
110-
11187
/** If @migration is present (indicating that the symbol has changed semantics between versions),
11288
* emit a warning.
11389
*/
@@ -152,15 +128,12 @@ class CrossVersionChecks extends MiniPhase:
152128
checkDeprecatedOvers(tree)
153129
checkExperimentalAnnots(tree.symbol)
154130
checkExperimentalSignature(tree.symbol, tree)
155-
checkSinceAnnot(tree.symbol, tree.srcPos)
156-
checkSinceAnnotInSignature(tree.symbol, tree)
157131
tree
158132

159133
override def transformDefDef(tree: DefDef)(using Context): DefDef =
160134
checkDeprecatedOvers(tree)
161135
checkExperimentalAnnots(tree.symbol)
162136
checkExperimentalSignature(tree.symbol, tree)
163-
checkSinceAnnotInSignature(tree.symbol, tree)
164137
tree
165138

166139
override def transformTemplate(tree: Template)(using Context): Tree =
@@ -190,19 +163,16 @@ class CrossVersionChecks extends MiniPhase:
190163
case TypeRef(_, sym: Symbol) =>
191164
checkDeprecated(sym, tree.srcPos)
192165
checkExperimentalRef(sym, tree.srcPos)
193-
checkSinceAnnot(sym, tree.srcPos)
194166
case TermRef(_, sym: Symbol) =>
195167
checkDeprecated(sym, tree.srcPos)
196168
checkExperimentalRef(sym, tree.srcPos)
197-
checkSinceAnnot(sym, tree.srcPos)
198169
case _ =>
199170
}
200171
tree
201172
}
202173

203174
override def transformTypeDef(tree: TypeDef)(using Context): TypeDef = {
204175
checkExperimentalAnnots(tree.symbol)
205-
checkSinceAnnot(tree.symbol, tree.srcPos)
206176
tree
207177
}
208178

compiler/test/dotty/tools/dotc/core/tasty/CommentPicklingTest.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ class CommentPicklingTest {
116116
implicit val ctx: Context = setup(args, initCtx).map(_._2).getOrElse(initCtx)
117117
ctx.initialize()
118118
val trees = files.flatMap { f =>
119-
val unpickler = new DottyUnpickler(f.toByteArray(), ctx.tastyVersion)
119+
val unpickler = new DottyUnpickler(f.toByteArray())
120120
unpickler.enter(roots = Set.empty)
121121
unpickler.rootTrees(using ctx)
122122
}

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

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -177,25 +177,23 @@ trait ParallelTesting extends RunnerOrchestration { self =>
177177
flags: TestFlags,
178178
outDir: JFile
179179
) extends TestSource {
180-
case class Group(ordinal: Int, compiler: String, release: String)
180+
case class Group(ordinal: Int, compiler: String)
181181

182182
lazy val compilationGroups: List[(Group, Array[JFile])] =
183-
val Release = """r([\d\.]+)""".r
184183
val Compiler = """c([\d\.]+)""".r
185184
val Ordinal = """(\d+)""".r
186185
def groupFor(file: JFile): Group =
187186
val groupSuffix = file.getName.dropWhile(_ != '_').stripSuffix(".scala").stripSuffix(".java")
188187
val groupSuffixParts = groupSuffix.split("_")
189188
val ordinal = groupSuffixParts.collectFirst { case Ordinal(n) => n.toInt }.getOrElse(Int.MinValue)
190-
val release = groupSuffixParts.collectFirst { case Release(r) => r }.getOrElse("")
191189
val compiler = groupSuffixParts.collectFirst { case Compiler(c) => c }.getOrElse("")
192-
Group(ordinal, compiler, release)
190+
Group(ordinal, compiler)
193191

194192
dir.listFiles
195193
.filter(isSourceFile)
196194
.groupBy(groupFor)
197195
.toList
198-
.sortBy { (g, _) => (g.ordinal, g.compiler, g.release) }
196+
.sortBy { (g, _) => (g.ordinal, g.compiler) }
199197
.map { (g, f) => (g, f.sorted) }
200198

201199
def sourceFiles = compilationGroups.map(_._2).flatten.toArray
@@ -218,11 +216,10 @@ trait ParallelTesting extends RunnerOrchestration { self =>
218216

219217
case testSource @ SeparateCompilationSource(_, dir, flags, outDir) =>
220218
testSource.compilationGroups.map { (group, files) =>
221-
val flags1 = if group.release.isEmpty then flags else flags.and("-scala-output-version", group.release)
222219
if group.compiler.isEmpty then
223-
compile(files, flags1, suppressErrors, outDir)
220+
compile(files, flags, suppressErrors, outDir)
224221
else
225-
compileWithOtherCompiler(group.compiler, files, flags1, outDir)
222+
compileWithOtherCompiler(group.compiler, files, flags, outDir)
226223
}
227224
})
228225

docs/_docs/contributing/testing.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,9 @@ $ sbt
131131

132132
When the sources of a test consist of multiple source files places in a single directory they are passed to the compiler in a single run and the compiler decides in which order to compile them. In some cases, however, to reproduce a specific test scenario it might be necessary to compile the source files in several steps in a specified order. To achieve that one can add a `_${step_index}` suffix to a file name (before the `.scala` or `.java` extension) indicating the order of compilation. E.g. if the test directory contains files named `Foo_1.scala`, `Bar_2.scala` and `Baz_2.scala` then `Foo_1.scala` will be compiled first and after that `Bar_2.scala` together with `Baz_2.scala`.
133133

134-
There are also other suffixes indicating how some particular files are compiled:
135-
* `_c${compilerVersion}` - compile a file with a specific version of the compiler instead of the one developed on the current branch
136-
(e.g. `Foo_c3.0.2.scala`)
137-
* `_r${release}` - compile a file with a given value of `-scala-output-version` flag (e.g. `Foo_r3.0.scala`)
134+
The other kind of suffix that can modify how particular files are compiled is `_c${compilerVersion}`. When specified, the file will be compiled with a specific version of the compiler instead of the one developed on the current branch.
138135

139-
Different suffixes can be mixed together (their order is not important although consistency is advised), e.g. `Foo_1_r3.0`, `Bar_2_c3.0.2`.
136+
Different suffixes can be mixed together (their order is not important although consistency is advised), e.g. `Foo_1_c3.0.2`, `Bar_2_c3.1.0`.
140137

141138
### Bootstrapped-only tests
142139

0 commit comments

Comments
 (0)