From c2ab1b408aa87c9b22522e29f946f93f9a08d862 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Marks?= Date: Thu, 5 May 2022 13:06:16 +0200 Subject: [PATCH 1/6] Remove support for `-scala-output-version` flag --- .../tools/dotc/config/ScalaSettings.scala | 1 - .../src/dotty/tools/dotc/core/Contexts.scala | 22 ++---------- .../dotty/tools/dotc/core/Definitions.scala | 1 - .../dotc/core/classfile/ClassfileParser.scala | 33 ++--------------- .../dotc/core/tasty/DottyUnpickler.scala | 2 +- .../tools/dotc/core/tasty/TastyPickler.scala | 12 +++---- .../tools/dotc/core/tasty/TastyVersion.scala | 23 ------------ .../tools/dotc/quoted/PickledQuotes.scala | 2 +- .../dotty/tools/dotc/transform/Pickler.scala | 2 +- .../tools/dotc/typer/CrossVersionChecks.scala | 35 ++++-------------- .../dotc/core/tasty/CommentPicklingTest.scala | 2 +- .../dotty/tools/vulpix/ParallelTesting.scala | 13 +++---- docs/_docs/contributing/testing.md | 11 ------ ...-compatibility.md => language-versions.md} | 6 ++-- .../language-versions/binary-compatibility.md | 36 ------------------- .../language-versions/language-versions.md | 6 ---- docs/sidebar.yml | 5 --- library/src/scala/CanEqual.scala | 6 +--- library/src/scala/Selectable.scala | 3 +- library/src/scala/Tuple.scala | 4 +-- .../src/scala/annotation/experimental.scala | 1 - .../annotation/internal/ErasedParam.scala | 1 - .../internal/ProvisionalSuperClass.scala | 1 - library/src/scala/annotation/since.scala | 4 --- library/src/scala/quoted/Quotes.scala | 17 +-------- library/src/scala/quoted/Type.scala | 3 +- project/MiMaFilters.scala | 6 +--- .../neg/forwardCompat-export/Test_r3.0.scala | 5 --- .../Test_r3.0.scala | 31 ---------------- tests/neg/forwardCompat-invalidSince.scala | 21 ----------- .../Test_r3.0.scala | 1 - .../Lib_1_r3.0.scala | 8 ----- .../Test_2_c3.0.2.scala | 5 --- .../Bar_2_r3.0.scala | 1 - .../Foo_1_r3.1.scala | 1 - .../Test_r3.0.scala | 2 -- .../Lib_1_r3.0.scala | 13 ------- .../Test_2_c3.0.2.scala | 7 ---- .../Lib1_1_r3.0.scala | 8 ----- .../Lib2_2_r3.0.scala | 3 -- .../Test_3_c3.0.2.scala | 3 -- .../Lib_1_r3.0.scala | 16 --------- .../Test_2_c3.0.2.scala | 7 ---- .../Equality_1_r3.0.scala | 5 --- .../Test_2_c3.0.2.scala | 3 -- .../Imports_1_r3.0.scala | 14 -------- .../Test_2_c3.0.2.scala | 7 ---- 47 files changed, 32 insertions(+), 387 deletions(-) delete mode 100644 compiler/src/dotty/tools/dotc/core/tasty/TastyVersion.scala rename docs/_docs/reference/{language-versions/source-compatibility.md => language-versions.md} (74%) delete mode 100644 docs/_docs/reference/language-versions/binary-compatibility.md delete mode 100644 docs/_docs/reference/language-versions/language-versions.md delete mode 100644 library/src/scala/annotation/since.scala delete mode 100644 tests/neg/forwardCompat-export/Test_r3.0.scala delete mode 100644 tests/neg/forwardCompat-illegalReferences/Test_r3.0.scala delete mode 100644 tests/neg/forwardCompat-invalidSince.scala delete mode 100644 tests/neg/forwardCompat-leakingImplicit/Test_r3.0.scala delete mode 100644 tests/neg/forwardCompat-nestedSumMirror/Lib_1_r3.0.scala delete mode 100644 tests/neg/forwardCompat-nestedSumMirror/Test_2_c3.0.2.scala delete mode 100644 tests/neg/forwardCompat-rejectNewerTasty/Bar_2_r3.0.scala delete mode 100644 tests/neg/forwardCompat-rejectNewerTasty/Foo_1_r3.1.scala delete mode 100644 tests/pos/forwardCompat-excludedExport/Test_r3.0.scala delete mode 100644 tests/pos/forwardCompat-exportInExtension/Lib_1_r3.0.scala delete mode 100644 tests/pos/forwardCompat-exportInExtension/Test_2_c3.0.2.scala delete mode 100644 tests/run/forwardCompat-nestedSumMirror/Lib1_1_r3.0.scala delete mode 100644 tests/run/forwardCompat-nestedSumMirror/Lib2_2_r3.0.scala delete mode 100644 tests/run/forwardCompat-nestedSumMirror/Test_3_c3.0.2.scala delete mode 100644 tests/run/forwardCompat-refinedGivens/Lib_1_r3.0.scala delete mode 100644 tests/run/forwardCompat-refinedGivens/Test_2_c3.0.2.scala delete mode 100644 tests/run/forwardCompat-strictEquals/Equality_1_r3.0.scala delete mode 100644 tests/run/forwardCompat-strictEquals/Test_2_c3.0.2.scala delete mode 100644 tests/run/forwardCompat-unusedImport/Imports_1_r3.0.scala delete mode 100644 tests/run/forwardCompat-unusedImport/Test_2_c3.0.2.scala diff --git a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala index 20cbcd136fee..33fad20bffd6 100644 --- a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala +++ b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala @@ -106,7 +106,6 @@ trait CommonScalaSettings: val silentWarnings: Setting[Boolean] = BooleanSetting("-nowarn", "Silence all warnings.", aliases = List("--no-warnings")) 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")) - 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, "") val deprecation: Setting[Boolean] = BooleanSetting("-deprecation", "Emit warning and location for usages of deprecated APIs.", aliases = List("--deprecation")) val feature: Setting[Boolean] = BooleanSetting("-feature", "Emit warning and location for usages of features that should be imported explicitly.", aliases = List("--feature")) diff --git a/compiler/src/dotty/tools/dotc/core/Contexts.scala b/compiler/src/dotty/tools/dotc/core/Contexts.scala index 19b1a8ac5e11..44446080c106 100644 --- a/compiler/src/dotty/tools/dotc/core/Contexts.scala +++ b/compiler/src/dotty/tools/dotc/core/Contexts.scala @@ -24,7 +24,7 @@ import io.{AbstractFile, NoAbstractFile, PlainFile, Path} import scala.io.Codec import collection.mutable import printing._ -import config.{JavaPlatform, SJSPlatform, Platform, ScalaSettings, ScalaRelease} +import config.{JavaPlatform, SJSPlatform, Platform, ScalaSettings} import classfile.ReusableDataReader import StdNames.nme @@ -38,9 +38,6 @@ import xsbti.AnalysisCallback import plugins._ import java.util.concurrent.atomic.AtomicInteger import java.nio.file.InvalidPathException -import dotty.tools.tasty.TastyFormat -import dotty.tools.dotc.config.{ NoScalaVersion, SpecificScalaVersion, AnyScalaVersion, ScalaBuild } -import dotty.tools.dotc.core.tasty.TastyVersion object Contexts { @@ -478,22 +475,7 @@ object Contexts { /** A new context that summarizes an import statement */ def importContext(imp: Import[?], sym: Symbol): FreshContext = - fresh.setImportInfo(ImportInfo(sym, imp.selectors, imp.expr)) - - def scalaRelease: ScalaRelease = - val releaseName = base.settings.scalaOutputVersion.value - if releaseName.nonEmpty then ScalaRelease.parse(releaseName).get else ScalaRelease.latest - - def tastyVersion: TastyVersion = - import math.Ordered.orderingToOrdered - val latestRelease = ScalaRelease.latest - val specifiedRelease = scalaRelease - if specifiedRelease < latestRelease then - // This is needed to make -scala-output-version a no-op when set to the latest release for unstable versions of the compiler - // (which might have the tasty format version numbers set to higher values before they're decreased during a release) - TastyVersion.fromStableScalaRelease(specifiedRelease.majorVersion, specifiedRelease.minorVersion) - else - TastyVersion.compilerVersion + fresh.setImportInfo(ImportInfo(sym, imp.selectors, imp.expr)) /** Is the debug option set? */ def debug: Boolean = base.settings.Ydebug.value diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index e09b7ca98955..ddcee28c5739 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -988,7 +988,6 @@ class Definitions { @tu lazy val FunctionalInterfaceAnnot: ClassSymbol = requiredClass("java.lang.FunctionalInterface") @tu lazy val TargetNameAnnot: ClassSymbol = requiredClass("scala.annotation.targetName") @tu lazy val VarargsAnnot: ClassSymbol = requiredClass("scala.annotation.varargs") - @tu lazy val SinceAnnot: ClassSymbol = requiredClass("scala.annotation.since") @tu lazy val JavaRepeatableAnnot: ClassSymbol = requiredClass("java.lang.annotation.Repeatable") diff --git a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala index a45ff756173a..8ef5bd6c84e4 100644 --- a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala +++ b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala @@ -20,7 +20,6 @@ import java.util.UUID import scala.collection.immutable import scala.collection.mutable.{ ListBuffer, ArrayBuffer } import scala.annotation.switch -import tasty.TastyVersion import typer.Checking.checkNonCyclic import io.{AbstractFile, ZipArchive} import scala.util.control.NonFatal @@ -914,7 +913,7 @@ class ClassfileParser( } def unpickleTASTY(bytes: Array[Byte]): Some[Embedded] = { - val unpickler = new tasty.DottyUnpickler(bytes, ctx.tastyVersion) + val unpickler = new tasty.DottyUnpickler(bytes) unpickler.enter(roots = Set(classRoot, moduleRoot, moduleRoot.sourceModule))(using ctx.withSource(util.NoSource)) Some(unpickler) } @@ -980,37 +979,9 @@ class ClassfileParser( if (tastyBytes.nonEmpty) { val reader = new TastyReader(bytes, 0, 16) val expectedUUID = new UUID(reader.readUncompressedLong(), reader.readUncompressedLong()) - val tastyHeader = new TastyHeaderUnpickler(tastyBytes).readFullHeader() - val fileTastyVersion = TastyVersion(tastyHeader.majorVersion, tastyHeader.minorVersion, tastyHeader.experimentalVersion) - val tastyUUID = tastyHeader.uuid + val tastyUUID = new TastyHeaderUnpickler(tastyBytes).readHeader() if (expectedUUID != tastyUUID) report.warning(s"$classfile is out of sync with its TASTy file. Loaded TASTy file. Try cleaning the project to fix this issue", NoSourcePosition) - - val tastyFilePath = classfile.path.stripSuffix(".class") + ".tasty" - - def reportWrongTasty(reason: String, highestAllowed: TastyVersion) = - report.error(s"""The class ${classRoot.symbol.showFullName} cannot be loaded from file ${tastyFilePath} because $reason: - |highest allowed: ${highestAllowed.show} - |found: ${fileTastyVersion.show} - """.stripMargin) - - val isTastyReadable = fileTastyVersion.isCompatibleWith(TastyVersion.compilerVersion) - if !isTastyReadable then - reportWrongTasty("its TASTy format cannot be read by the compiler", TastyVersion.compilerVersion) - else - def isStdlibClass(cls: ClassDenotation): Boolean = - ctx.platform.classPath.findClassFile(cls.fullName.mangledString) match { - case Some(entry: ZipArchive#Entry) => - entry.underlyingSource.map(_.name.startsWith("scala3-library_")).getOrElse(false) - case _ => false - } - // 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. - // This is OK however because references to elements of stdlib API are validated according to the values of their `@since` annotations. - // This should guarantee that the code won't crash at runtime when used with the stdlib provided by an older compiler. - val isTastyCompatible = fileTastyVersion.isCompatibleWith(ctx.tastyVersion) || isStdlibClass(classRoot) - if !isTastyCompatible then - reportWrongTasty(s"its TASTy format is not compatible with the one of the targeted Scala release (${ctx.scalaRelease.show})", ctx.tastyVersion) - return unpickleTASTY(tastyBytes) } } diff --git a/compiler/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala index f80f9688073e..b35c5c9f1acc 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/DottyUnpickler.scala @@ -41,7 +41,7 @@ object DottyUnpickler { * @param bytes the bytearray containing the Tasty file from which we unpickle * @param mode the tasty file contains package (TopLevel), an expression (Term) or a type (TypeTree) */ -class DottyUnpickler(bytes: Array[Byte], maximalTastyVersion: TastyVersion, mode: UnpickleMode = UnpickleMode.TopLevel) extends ClassfileParser.Embedded with tpd.TreeProvider { +class DottyUnpickler(bytes: Array[Byte], mode: UnpickleMode = UnpickleMode.TopLevel) extends ClassfileParser.Embedded with tpd.TreeProvider { import tpd._ import DottyUnpickler._ diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyPickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyPickler.scala index 1ff1642ecce1..202e844ce13c 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TastyPickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TastyPickler.scala @@ -9,8 +9,6 @@ import dotty.tools.tasty.{TastyBuffer, TastyFormat, TastyHash} import TastyFormat._ import TastyBuffer._ -import Contexts._ - import collection.mutable import core.Symbols.ClassSymbol import Decorators._ @@ -33,7 +31,7 @@ class TastyPickler(val rootCls: ClassSymbol) { def newSection(name: String, buf: TastyBuffer): Unit = sections += ((nameBuffer.nameIndex(name.toTermName), buf)) - def assembleParts()(using Context): Array[Byte] = { + def assembleParts(): Array[Byte] = { def lengthWithLength(buf: TastyBuffer) = buf.length + natSize(buf.length) @@ -43,8 +41,6 @@ class TastyPickler(val rootCls: ClassSymbol) { val nameBufferHash = TastyHash.pjwHash64(nameBuffer.bytes) val treeSectionHash +: otherSectionHashes = sections.map(x => TastyHash.pjwHash64(x._2.bytes)) - val tastyVersion = ctx.tastyVersion - // Hash of name table and tree val uuidLow: Long = nameBufferHash ^ treeSectionHash // Hash of positions, comments and any additional section @@ -53,9 +49,9 @@ class TastyPickler(val rootCls: ClassSymbol) { val headerBuffer = { val buf = new TastyBuffer(header.length + TastyPickler.versionStringBytes.length + 32) for (ch <- header) buf.writeByte(ch.toByte) - buf.writeNat(tastyVersion.major) - buf.writeNat(tastyVersion.minor) - buf.writeNat(tastyVersion.experimental) + buf.writeNat(MajorVersion) + buf.writeNat(MinorVersion) + buf.writeNat(ExperimentalVersion) buf.writeNat(TastyPickler.versionStringBytes.length) buf.writeBytes(TastyPickler.versionStringBytes, TastyPickler.versionStringBytes.length) buf.writeUncompressedLong(uuidLow) diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TastyVersion.scala b/compiler/src/dotty/tools/dotc/core/tasty/TastyVersion.scala deleted file mode 100644 index 9c417563a1e3..000000000000 --- a/compiler/src/dotty/tools/dotc/core/tasty/TastyVersion.scala +++ /dev/null @@ -1,23 +0,0 @@ -package dotty.tools.dotc.core.tasty - -import dotty.tools.tasty.TastyFormat - -case class TastyVersion(major: Int, minor: Int, experimental: Int) { - def show = s"$major.$minor-$experimental" - - def isCompatibleWith(that: TastyVersion): Boolean = TastyFormat.isVersionCompatible( - this.major, this.minor, this.experimental, - that.major, that.minor, that.experimental - ) -} - -object TastyVersion { - def compilerVersion = TastyVersion(TastyFormat.MajorVersion, TastyFormat.MinorVersion, TastyFormat.ExperimentalVersion) - - def fromStableScalaRelease(majorVersion: Int, minorVersion: Int) = { - val tastyMajor = majorVersion + 25 - val tastyMinor = minorVersion - TastyVersion(tastyMajor, tastyMinor, 0) - } - -} \ No newline at end of file diff --git a/compiler/src/dotty/tools/dotc/quoted/PickledQuotes.scala b/compiler/src/dotty/tools/dotc/quoted/PickledQuotes.scala index 2e0454c3a7aa..d2f842cb9d9e 100644 --- a/compiler/src/dotty/tools/dotc/quoted/PickledQuotes.scala +++ b/compiler/src/dotty/tools/dotc/quoted/PickledQuotes.scala @@ -251,7 +251,7 @@ object PickledQuotes { quotePickling.println(s"**** unpickling quote from TASTY\n${TastyPrinter.showContents(bytes, ctx.settings.color.value == "never")}") val mode = if (isType) UnpickleMode.TypeTree else UnpickleMode.Term - val unpickler = new DottyUnpickler(bytes, ctx.tastyVersion, mode) + val unpickler = new DottyUnpickler(bytes, mode) unpickler.enter(Set.empty) val tree = unpickler.tree diff --git a/compiler/src/dotty/tools/dotc/transform/Pickler.scala b/compiler/src/dotty/tools/dotc/transform/Pickler.scala index cd2a6f33dc6f..579d42ce9e46 100644 --- a/compiler/src/dotty/tools/dotc/transform/Pickler.scala +++ b/compiler/src/dotty/tools/dotc/transform/Pickler.scala @@ -128,7 +128,7 @@ class Pickler extends Phase { ctx.initialize() val unpicklers = for ((cls, pickler) <- picklers) yield { - val unpickler = new DottyUnpickler(pickler.assembleParts(), ctx.tastyVersion) + val unpickler = new DottyUnpickler(pickler.assembleParts()) unpickler.enter(roots = Set.empty) cls -> unpickler } diff --git a/compiler/src/dotty/tools/dotc/typer/CrossVersionChecks.scala b/compiler/src/dotty/tools/dotc/typer/CrossVersionChecks.scala index a807d8299b41..5a0ea82468b9 100644 --- a/compiler/src/dotty/tools/dotc/typer/CrossVersionChecks.scala +++ b/compiler/src/dotty/tools/dotc/typer/CrossVersionChecks.scala @@ -29,7 +29,6 @@ class CrossVersionChecks extends MiniPhase: private def checkUndesiredProperties(sym: Symbol, pos: SrcPos)(using Context): Unit = checkDeprecated(sym, pos) checkExperimentalRef(sym, pos) - checkSinceAnnot(sym, pos) val xMigrationValue = ctx.settings.Xmigration.value if xMigrationValue != NoScalaVersion then @@ -85,29 +84,6 @@ class CrossVersionChecks extends MiniPhase: for annot <- sym.annotations if annot.symbol.isExperimental do Feature.checkExperimentalDef(annot.symbol, annot.tree) - private def checkSinceAnnot(sym: Symbol, pos: SrcPos)(using Context): Unit = - for - annot <- sym.getAnnotation(defn.SinceAnnot) - releaseName <- annot.argumentConstantString(0) - do - ScalaRelease.parse(releaseName) match - case Some(release) if release > ctx.scalaRelease => - report.error( - i"$sym was added in Scala release ${releaseName.show}, therefore it cannot be used in the code targeting Scala ${ctx.scalaRelease.show}", - pos) - case None => - report.error(i"$sym has an unparsable release name: '${releaseName}'", annot.tree.srcPos) - case _ => - - private def checkSinceAnnotInSignature(sym: Symbol, pos: SrcPos)(using Context) = - new TypeTraverser: - def traverse(tp: Type) = - if tp.typeSymbol.hasAnnotation(defn.SinceAnnot) then - checkSinceAnnot(tp.typeSymbol, pos) - else - traverseChildren(tp) - .traverse(sym.info) - /** If @migration is present (indicating that the symbol has changed semantics between versions), * emit a warning. */ @@ -152,15 +128,12 @@ class CrossVersionChecks extends MiniPhase: checkDeprecatedOvers(tree) checkExperimentalAnnots(tree.symbol) checkExperimentalSignature(tree.symbol, tree) - checkSinceAnnot(tree.symbol, tree.srcPos) - checkSinceAnnotInSignature(tree.symbol, tree) tree override def transformDefDef(tree: DefDef)(using Context): DefDef = checkDeprecatedOvers(tree) checkExperimentalAnnots(tree.symbol) checkExperimentalSignature(tree.symbol, tree) - checkSinceAnnotInSignature(tree.symbol, tree) tree override def transformTemplate(tree: Template)(using Context): Tree = @@ -189,12 +162,19 @@ class CrossVersionChecks extends MiniPhase: tpe.foreachPart { case TypeRef(_, sym: Symbol) => checkDeprecated(sym, tree.srcPos) +<<<<<<< HEAD checkExperimentalRef(sym, tree.srcPos) checkSinceAnnot(sym, tree.srcPos) case TermRef(_, sym: Symbol) => checkDeprecated(sym, tree.srcPos) checkExperimentalRef(sym, tree.srcPos) checkSinceAnnot(sym, tree.srcPos) +======= + checkExperimental(sym, tree.srcPos) + case TermRef(_, sym: Symbol) => + checkDeprecated(sym, tree.srcPos) + checkExperimental(sym, tree.srcPos) +>>>>>>> d5b33c5f14 (Remove support for `-scala-output-version` flag) case _ => } tree @@ -202,7 +182,6 @@ class CrossVersionChecks extends MiniPhase: override def transformTypeDef(tree: TypeDef)(using Context): TypeDef = { checkExperimentalAnnots(tree.symbol) - checkSinceAnnot(tree.symbol, tree.srcPos) tree } diff --git a/compiler/test/dotty/tools/dotc/core/tasty/CommentPicklingTest.scala b/compiler/test/dotty/tools/dotc/core/tasty/CommentPicklingTest.scala index fc6731652ada..0af4434fdcde 100644 --- a/compiler/test/dotty/tools/dotc/core/tasty/CommentPicklingTest.scala +++ b/compiler/test/dotty/tools/dotc/core/tasty/CommentPicklingTest.scala @@ -116,7 +116,7 @@ class CommentPicklingTest { implicit val ctx: Context = setup(args, initCtx).map(_._2).getOrElse(initCtx) ctx.initialize() val trees = files.flatMap { f => - val unpickler = new DottyUnpickler(f.toByteArray(), ctx.tastyVersion) + val unpickler = new DottyUnpickler(f.toByteArray()) unpickler.enter(roots = Set.empty) unpickler.rootTrees(using ctx) } diff --git a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala index 5a57ede4ceb5..02819be3cdbb 100644 --- a/compiler/test/dotty/tools/vulpix/ParallelTesting.scala +++ b/compiler/test/dotty/tools/vulpix/ParallelTesting.scala @@ -177,25 +177,23 @@ trait ParallelTesting extends RunnerOrchestration { self => flags: TestFlags, outDir: JFile ) extends TestSource { - case class Group(ordinal: Int, compiler: String, release: String) + case class Group(ordinal: Int, compiler: String) lazy val compilationGroups: List[(Group, Array[JFile])] = - val Release = """r([\d\.]+)""".r val Compiler = """c([\d\.]+)""".r val Ordinal = """(\d+)""".r def groupFor(file: JFile): Group = val groupSuffix = file.getName.dropWhile(_ != '_').stripSuffix(".scala").stripSuffix(".java") val groupSuffixParts = groupSuffix.split("_") val ordinal = groupSuffixParts.collectFirst { case Ordinal(n) => n.toInt }.getOrElse(Int.MinValue) - val release = groupSuffixParts.collectFirst { case Release(r) => r }.getOrElse("") val compiler = groupSuffixParts.collectFirst { case Compiler(c) => c }.getOrElse("") - Group(ordinal, compiler, release) + Group(ordinal, compiler) dir.listFiles .filter(isSourceFile) .groupBy(groupFor) .toList - .sortBy { (g, _) => (g.ordinal, g.compiler, g.release) } + .sortBy { (g, _) => (g.ordinal, g.compiler) } .map { (g, f) => (g, f.sorted) } def sourceFiles = compilationGroups.map(_._2).flatten.toArray @@ -218,11 +216,10 @@ trait ParallelTesting extends RunnerOrchestration { self => case testSource @ SeparateCompilationSource(_, dir, flags, outDir) => testSource.compilationGroups.map { (group, files) => - val flags1 = if group.release.isEmpty then flags else flags.and("-scala-output-version", group.release) if group.compiler.isEmpty then - compile(files, flags1, suppressErrors, outDir) + compile(files, flags, suppressErrors, outDir) else - compileWithOtherCompiler(group.compiler, files, flags1, outDir) + compileWithOtherCompiler(group.compiler, files, flags, outDir) } }) diff --git a/docs/_docs/contributing/testing.md b/docs/_docs/contributing/testing.md index e3f93eb0baec..fa333634f07b 100644 --- a/docs/_docs/contributing/testing.md +++ b/docs/_docs/contributing/testing.md @@ -127,17 +127,6 @@ $ sbt > testCompilation --help ``` -### Joint and separate sources compilation - -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`. - -There are also other suffixes indicating how some particular files are compiled: -* `_c${compilerVersion}` - compile a file with a specific version of the compiler instead of the one developed on the current branch - (e.g. `Foo_c3.0.2.scala`) -* `_r${release}` - compile a file with a given value of `-scala-output-version` flag (e.g. `Foo_r3.0.scala`) - -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`. - ### Bootstrapped-only tests To run `testCompilation` on a bootstrapped Dotty compiler, use diff --git a/docs/_docs/reference/language-versions/source-compatibility.md b/docs/_docs/reference/language-versions.md similarity index 74% rename from docs/_docs/reference/language-versions/source-compatibility.md rename to docs/_docs/reference/language-versions.md index 029a3674ba73..ef31ccc28707 100644 --- a/docs/_docs/reference/language-versions/source-compatibility.md +++ b/docs/_docs/reference/language-versions.md @@ -1,12 +1,10 @@ --- layout: doc-page -title: "Source Compatibility" +title: "Language Versions" movedTo: https://docs.scala-lang.org/scala3/reference/language-versions.html --- -Scala 3 does NOT guarantee source compatibility between different minor language versions (e.g. some syntax valid in 3.x might get deprecated and then phased out in 3.y for y > x). There are also some syntax structures that were valid in Scala 2 but are not anymore in Scala 3. However the compiler provides a possibility to specify the desired version of syntax used in a particular file or globally for a run of the compiler to make migration between versions easier. - -The default Scala language syntax version currently supported by the Dotty compiler is [`3.0`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$3/0$.html). There are also other language versions that can be specified instead: +The default Scala language version currently supported by the Dotty compiler is [`3.0`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$3/0$.html). There are also other language versions that can be specified instead: - [`3.0-migration`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$3/0-migration$.html): Same as `3.0` but with a Scala 2 compatibility mode that helps moving Scala 2.13 sources over to Scala 3. In particular, it diff --git a/docs/_docs/reference/language-versions/binary-compatibility.md b/docs/_docs/reference/language-versions/binary-compatibility.md deleted file mode 100644 index 3e48090ba8c5..000000000000 --- a/docs/_docs/reference/language-versions/binary-compatibility.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -layout: doc-page -title: "Binary Compatibility" ---- - -In Scala 2 different minor versions of the compiler were free to change the way how they encode different language features in JVM bytecode so each bump of the compiler's minor version resulted in breaking binary compatibility and if a project had any Scala dependencies they all needed to be (cross-)compiled to the same minor Scala version that was used in that project itself. On the contrary, Scala 3 has a stable encoding into JVM bytecode. - -In addition to classfiles the compilation process in Scala 3 also produces files with `.tasty` extension. The [TASTy](https://docs.scala-lang.org/scala3/guides/tasty-overview.html) format is an intermediate representation of Scala code containing full information about sources together with information provided by the typer. Some of this information is lost during generation of bytecode so Scala 3 compilers read TASTy files during compilation in addition to classfiles to know the exact types of values, methods, etc. in already compiled classes (although compilation from TASTy files only is also possible). TASTy files are also typically distributed together with classfiles in published artifacts. - -TASTy format is extensible but it preserves backward compatibility and the evolution happens between minor releases of the language. This means a Scala compiler in version `3.x1.y1` is able to read TASTy files produced by another compiler in version `3.x2.y2` if `x1 >= x2` (assuming two stable versions of the compiler are considered - `SNAPSHOT` or `NIGHTLY` compiler versions can read TASTy in an older stable format but their TASTY versions are not compatible between each other even if the compilers have the same minor version; also compilers in stable versions cannot read TASTy generated by an unstable version). - -TASTy version number has the format of `.-` and the numbering changes in parallel to language releases in such a way that a bump in language minor version corresponds to a bump in TASTy minor version (e.g. for Scala `3.0.0` the TASTy version is `28.0-0`). Experimental version set to 0 signifies a stable version while others are considered unstable/experimental. TASTy version is not strictly bound to the data format itself - any changes to the API of the standard library also require a change in TASTy minor version. - -Being able to bump the compiler version in a project without having to wait for all of its dependencies to do the same is already a big leap forward when compared to Scala 2. However, we might still try to do better, especially from the perspective of authors of libraries. -If you maintain a library and you would like it to be usable as a dependency for all Scala 3 projects, you would have to always emit TASTy in a version that would be readble by everyone, which would normally mean getting stuck at 3.0.x forever. - -To solve this problem a new experimental compiler flag `-scala-output-version ` (available since 3.1.2) has been added. Setting this flag makes the compiler produce TASTy files that should be possible to use by all Scala 3 compilers in version `` or newer. This flag was inspired by how `-java-output-version` (formerly `-release`) works for specifying the target version of JDK. More specifically this enforces emitting TASTy files in an older format ensuring that: -* the code contains no references to parts of the standard library which were added to the API after `` and would crash at runtime when a program is executed with the older version of the standard library on the classpath -* no dependency found on the classpath during compilation (except for the standard library itself) contains TASTy files produced by a compiler newer than `` (otherwise they could potentially leak such disallowed references to the standard library). - -If any of the checks above is not fulfilled or for any other reason older TASTy cannot be emitted (e.g. the code uses some new language features which cannot be expressed the the older format) the entire compilation fails (with errors reported for each of such issues). - -As this feature is experimental it does not have any special support in build tools yet (at least not in sbt 1.6.1 or lower). -E.g. when a project gets compiled with Scala compiler `3.x1.y1` and `-scala-output-version 3.x2` option and then published using sbt -then the standard library in version `3.x1.y1` gets added to the project's dependencies instead of `3.x2.y2`. -When the dependencies are added to the classpath during compilation with Scala `3.x2.y2` the compiler will crash while trying to read TASTy files in the newer format. -A currently known workaround is to modify the build definition of the dependent project by explicitly overriding the version of Scala standard library in dependencies, e.g. - -```scala -dependencyOverrides ++= Seq( - scalaOrganization.value %% "scala3-library" % scalaVersion.value, - scalaOrganization.value %% "scala3-library_sjs1" % scalaVersion.value // for Scala.js projects -) -``` - -The behaviour of `-scala-output-version` flag might still change in the future, especially it's not guaranteed that every new version of the compiler would be able to generate TASTy in all older formats going back to the one produced by `3.0.x` compiler. diff --git a/docs/_docs/reference/language-versions/language-versions.md b/docs/_docs/reference/language-versions/language-versions.md deleted file mode 100644 index c38538d3a82a..000000000000 --- a/docs/_docs/reference/language-versions/language-versions.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -layout: index -title: "Language Versions" ---- - -Additional information on interoperability and migration between Scala 2 and 3 can be found [here](https://docs.scala-lang.org/scala3/guides/migration/compatibility-intro.html). diff --git a/docs/sidebar.yml b/docs/sidebar.yml index c7edc92c1530..a4441e6589cb 100644 --- a/docs/sidebar.yml +++ b/docs/sidebar.yml @@ -152,11 +152,6 @@ subsection: - page: reference/experimental/cc.md - page: reference/experimental/tupled-function.md - page: reference/syntax.md - - title: Language Versions - index: reference/language-versions/language-versions.md - subsection: - - page: reference/language-versions/source-compatibility.md - - page: reference/language-versions/binary-compatibility.md - page: reference/soft-modifier.md - page: reference/features-classification.md - title: Contributing diff --git a/library/src/scala/CanEqual.scala b/library/src/scala/CanEqual.scala index f09df1455c2c..dfb4ec7d2bfc 100644 --- a/library/src/scala/CanEqual.scala +++ b/library/src/scala/CanEqual.scala @@ -1,6 +1,6 @@ package scala -import annotation.{ implicitNotFound, since } +import annotation.implicitNotFound import scala.collection.{Seq, Set} /** A marker trait indicating that values of type `L` can be compared to values of type `R`. */ @@ -29,18 +29,14 @@ object CanEqual { // The next 6 definitions can go into the companion objects of their corresponding // classes. For now they are here in order not to have to touch the // source code of these classes - @since("3.1") given canEqualSeqs[T, U](using eq: CanEqual[T, U]): CanEqual[Seq[T], Seq[U]] = derived given canEqualSeq[T](using eq: CanEqual[T, T]): CanEqual[Seq[T], Seq[T]] = derived // for `case Nil` in pattern matching given canEqualSet[T, U](using eq: CanEqual[T, U]): CanEqual[Set[T], Set[U]] = derived - @since("3.1") given canEqualOptions[T, U](using eq: CanEqual[T, U]): CanEqual[Option[T], Option[U]] = derived - @since("3.1") given canEqualOption[T](using eq: CanEqual[T, T]): CanEqual[Option[T], Option[T]] = derived // for `case None` in pattern matching - @since("3.1") given canEqualEither[L1, R1, L2, R2]( using eqL: CanEqual[L1, L2], eqR: CanEqual[R1, R2] ): CanEqual[Either[L1, R1], Either[L2, R2]] = derived diff --git a/library/src/scala/Selectable.scala b/library/src/scala/Selectable.scala index 51dcc4af549f..3aaa50c280f5 100644 --- a/library/src/scala/Selectable.scala +++ b/library/src/scala/Selectable.scala @@ -1,6 +1,6 @@ package scala -import scala.annotation.since +import scala.annotation.experimental /** A marker trait for objects that support structural selection via * `selectDynamic` and `applyDynamic` @@ -49,6 +49,5 @@ object Selectable: * the additional restriction that the signatures of the refinement and * the definition that implements the refinement must match. */ - @since("3.1") trait WithoutPreciseParameterTypes extends Selectable end Selectable diff --git a/library/src/scala/Tuple.scala b/library/src/scala/Tuple.scala index 58b4d121196b..52cf5c560ab9 100644 --- a/library/src/scala/Tuple.scala +++ b/library/src/scala/Tuple.scala @@ -1,6 +1,6 @@ package scala -import annotation.{experimental, showAsInfix, since} +import annotation.{experimental, showAsInfix} import compiletime._ import compiletime.ops.int._ @@ -260,9 +260,7 @@ object Tuple { def fromProductTyped[P <: Product](p: P)(using m: scala.deriving.Mirror.ProductOf[P]): m.MirroredElemTypes = runtime.Tuples.fromProduct(p).asInstanceOf[m.MirroredElemTypes] - @since("3.1") given canEqualEmptyTuple: CanEqual[EmptyTuple, EmptyTuple] = CanEqual.derived - @since("3.1") given canEqualTuple[H1, T1 <: Tuple, H2, T2 <: Tuple]( using eqHead: CanEqual[H1, H2], eqTail: CanEqual[T1, T2] ): CanEqual[H1 *: T1, H2 *: T2] = CanEqual.derived diff --git a/library/src/scala/annotation/experimental.scala b/library/src/scala/annotation/experimental.scala index abd8012fbe54..3d7a023176e3 100644 --- a/library/src/scala/annotation/experimental.scala +++ b/library/src/scala/annotation/experimental.scala @@ -5,5 +5,4 @@ package scala.annotation * @see [[https://dotty.epfl.ch/docs/reference/other-new-features/experimental-defs]] * @syntax markdown */ -@since("3.1") class experimental extends StaticAnnotation diff --git a/library/src/scala/annotation/internal/ErasedParam.scala b/library/src/scala/annotation/internal/ErasedParam.scala index 769b9a710d5f..a5ed192820c3 100644 --- a/library/src/scala/annotation/internal/ErasedParam.scala +++ b/library/src/scala/annotation/internal/ErasedParam.scala @@ -2,5 +2,4 @@ package scala.annotation package internal /** An annotation produced by Namer to indicate an erased parameter */ -@since("3.1") final class ErasedParam() extends Annotation diff --git a/library/src/scala/annotation/internal/ProvisionalSuperClass.scala b/library/src/scala/annotation/internal/ProvisionalSuperClass.scala index a9748540de56..147b7b087c5a 100644 --- a/library/src/scala/annotation/internal/ProvisionalSuperClass.scala +++ b/library/src/scala/annotation/internal/ProvisionalSuperClass.scala @@ -2,6 +2,5 @@ package scala.annotation package internal /** An annotation to record a provisional super class */ -@since("3.1") class ProvisionalSuperClass extends StaticAnnotation diff --git a/library/src/scala/annotation/since.scala b/library/src/scala/annotation/since.scala deleted file mode 100644 index 3c335dc020ba..000000000000 --- a/library/src/scala/annotation/since.scala +++ /dev/null @@ -1,4 +0,0 @@ -package scala.annotation - -/** An annotation that is used to mark symbols added to the stdlib after 3.0 release */ -private[scala] class since(scalaRelease: String) extends scala.annotation.StaticAnnotation diff --git a/library/src/scala/quoted/Quotes.scala b/library/src/scala/quoted/Quotes.scala index ce524f7166a1..dca20e972d40 100644 --- a/library/src/scala/quoted/Quotes.scala +++ b/library/src/scala/quoted/Quotes.scala @@ -1,6 +1,6 @@ package scala.quoted -import scala.annotation.{ experimental, since } +import scala.annotation.experimental import scala.reflect.TypeTest /** Current Quotes in scope @@ -66,7 +66,6 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => * Emits an error and aborts if the expression does not represent a value or possibly contains side effects. * Otherwise returns the value. */ - @since("3.1") def valueOrAbort(using FromExpr[T]): T end extension @@ -846,18 +845,15 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => end IdentMethods /** Pattern representing a `_` wildcard. */ - @since("3.1") type Wildcard <: Ident /** `TypeTest` that allows testing at runtime in a pattern match if a `Tree` is a `Wildcard` */ - @since("3.1") given WildcardTypeTest: TypeTest[Tree, Wildcard] /** Module object of `type Wildcard` */ val Wildcard: WildcardModule /** Methods of the module object `val Wildcard` */ - @since("3.1") trait WildcardModule { this: Wildcard.type => /** Create a tree representing a `_` wildcard. */ def apply(): Wildcard @@ -1675,19 +1671,15 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => end WhileMethods /** `TypeTest` that allows testing at runtime in a pattern match if a `Tree` is a `TypedOrTest` */ - @since("3.1") given TypedOrTestTypeTest: TypeTest[Tree, TypedOrTest] /** Tree representing a type ascription or type test pattern `x: T` in the source code. */ - @since("3.1") type TypedOrTest <: Tree /** Module object of `type TypedOrTest` */ - @since("3.1") val TypedOrTest: TypedOrTestModule /** Methods of the module object `val TypedOrTest` */ - @since("3.1") trait TypedOrTestModule { this: TypedOrTest.type => /** Create a type ascription `: ` */ @@ -1700,11 +1692,9 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => } /** Makes extension methods on `TypedOrTest` available without any imports */ - @since("3.1") given TypedOrTestMethods: TypedOrTestMethods /** Extension methods of `TypedOrTest` */ - @since("3.1") trait TypedOrTestMethods: extension (self: TypedOrTest) def tree: Tree @@ -2239,7 +2229,6 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => /** Methods of the module object `val Unapply` */ trait UnapplyModule { this: Unapply.type => /** Create an `Unapply` tree representing a pattern `()(using )` */ - @since("3.1") def apply(fun: Term, implicits: List[Term], patterns: List[Tree]): Unapply /** Copy an `Unapply` tree representing a pattern `()(using )` */ def copy(original: Tree)(fun: Term, implicits: List[Term], patterns: List[Tree]): Unapply @@ -2352,7 +2341,6 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => /** Is this a given parameter clause `(using X1, ..., Xn)` or `(using x1: X1, ..., xn: Xn)` */ def isGiven: Boolean /** Is this a erased parameter clause `(erased x1: X1, ..., xn: Xn)` */ - @since("3.1") def isErased: Boolean end TermParamClauseMethods @@ -2642,7 +2630,6 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => * * @return true if the dealiased type of `self` is `TupleN[T1, T2, ..., Tn]` */ - @since("3.1") def isTupleN: Boolean /** The type , reduced if possible */ @@ -3847,7 +3834,6 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => def memberField(name: String): Symbol /** Get named non-private fields declared or inherited */ - @since("3.1") def fieldMember(name: String): Symbol /** Get all non-private fields declared or inherited */ @@ -3855,7 +3841,6 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => def memberFields: List[Symbol] /** Get all non-private fields declared or inherited */ - @since("3.1") def fieldMembers: List[Symbol] /** Get non-private named methods defined directly inside the class */ diff --git a/library/src/scala/quoted/Type.scala b/library/src/scala/quoted/Type.scala index b4306a51fff0..bd6f578a0a8b 100644 --- a/library/src/scala/quoted/Type.scala +++ b/library/src/scala/quoted/Type.scala @@ -1,6 +1,6 @@ package scala.quoted -import scala.annotation.{compileTimeOnly, experimental, since} +import scala.annotation.{compileTimeOnly, experimental} /** Type (or type constructor) `T` needed contextually when using `T` in a quoted expression `'{... T ...}` */ abstract class Type[T <: AnyKind] private[scala]: @@ -66,7 +66,6 @@ object Type: * //} * ``` */ - @since("3.1") def valueOfTuple[T <: Tuple](using Type[T])(using Quotes): Option[T] = valueOfTuple(quotes.reflect.TypeRepr.of[T]).asInstanceOf[Option[T]] diff --git a/project/MiMaFilters.scala b/project/MiMaFilters.scala index ef450919d806..f5b83f0a3d4e 100644 --- a/project/MiMaFilters.scala +++ b/project/MiMaFilters.scala @@ -9,10 +9,6 @@ object MiMaFilters { ProblemFilters.exclude[ReversedMissingMethodProblem]("scala.quoted.runtime.QuoteUnpickler.unpickleTypeV2"), ProblemFilters.exclude[DirectMissingMethodProblem]("scala.quoted.runtime.QuoteUnpickler.unpickleTypeV2"), - // Experimental `MainAnnotation` APIs. Can be added in 3.3.0 or later. - // MiMa bug: classes nested in an experimental object should be ignored - ProblemFilters.exclude[MissingClassProblem]("scala.annotation.MainAnnotation$Info"), - ProblemFilters.exclude[MissingClassProblem]("scala.annotation.MainAnnotation$Parameter"), - ProblemFilters.exclude[MissingClassProblem]("scala.annotation.MainAnnotation$ParameterAnnotation"), + ProblemFilters.exclude[MissingClassProblem]("scala.annotation.since"), ) } diff --git a/tests/neg/forwardCompat-export/Test_r3.0.scala b/tests/neg/forwardCompat-export/Test_r3.0.scala deleted file mode 100644 index 92ba88d36d85..000000000000 --- a/tests/neg/forwardCompat-export/Test_r3.0.scala +++ /dev/null @@ -1,5 +0,0 @@ -object A: - export CanEqual.canEqualOption // error - -object B: - export CanEqual.given // error diff --git a/tests/neg/forwardCompat-illegalReferences/Test_r3.0.scala b/tests/neg/forwardCompat-illegalReferences/Test_r3.0.scala deleted file mode 100644 index 8dfeeeff3d29..000000000000 --- a/tests/neg/forwardCompat-illegalReferences/Test_r3.0.scala +++ /dev/null @@ -1,31 +0,0 @@ -import scala.quoted.* - -def useQuotes(using Quotes) = - import quotes.reflect.* - - def useFieldMember(s: Symbol) = s.fieldMember("abc") // error - def getWildcard: Wildcard = ??? // error - def acceptWildcard(w: Wildcard) = "" // error - def boundByWildcard[T <: Wildcard]: T = ??? // error - - val wildcard = getWildcard // error - - type MyWildcard = Wildcard // error - - type Foo[W <: Wildcard] = Any // error - - type Bar[T] = T match { case Wildcard => Any } // error - - type Baz[T] = T match { case String => Wildcard } // error - - trait Wrapped[T] - trait WrappedWildcard extends Wrapped[Wildcard] // error - trait WrappedLikeWildcard[W <: Wildcard] extends Wrapped[W] // error - - class Box(w: Wildcard) // error - - // The inferred result type also gets reported even though it's not written explicitly - def castToWildcard(x: Any) = x.asInstanceOf[Wildcard] // error // error - - // 2 errors reported because at the stage of compilation when this is checked (already after some code transformations) the illegal type is referred to more than once - val selectable: Any = new Selectable.WithoutPreciseParameterTypes {} // error // error diff --git a/tests/neg/forwardCompat-invalidSince.scala b/tests/neg/forwardCompat-invalidSince.scala deleted file mode 100644 index dfd128e84061..000000000000 --- a/tests/neg/forwardCompat-invalidSince.scala +++ /dev/null @@ -1,21 +0,0 @@ -package scala.test - -import annotation.since - -@since("") // error -val x = 1 - -@since("1.2.3.4") // error -val y = "abc" - -@since("xyz") // error -class Foo - -@since("-3") // error -trait Bar - -@since("3.0.2") // error -type Baz = Int - -@since("3.0 ") // error -given String = "" \ No newline at end of file diff --git a/tests/neg/forwardCompat-leakingImplicit/Test_r3.0.scala b/tests/neg/forwardCompat-leakingImplicit/Test_r3.0.scala deleted file mode 100644 index c9f0835bc053..000000000000 --- a/tests/neg/forwardCompat-leakingImplicit/Test_r3.0.scala +++ /dev/null @@ -1 +0,0 @@ -val canEq = summon[CanEqual[EmptyTuple, EmptyTuple]] // error diff --git a/tests/neg/forwardCompat-nestedSumMirror/Lib_1_r3.0.scala b/tests/neg/forwardCompat-nestedSumMirror/Lib_1_r3.0.scala deleted file mode 100644 index aaac31229228..000000000000 --- a/tests/neg/forwardCompat-nestedSumMirror/Lib_1_r3.0.scala +++ /dev/null @@ -1,8 +0,0 @@ -// Adapted from i11050 - -sealed trait TreeValue - -sealed trait SubLevel extends TreeValue - -case class Leaf1(value: String) extends TreeValue -case class Leaf2(value: Int) extends SubLevel diff --git a/tests/neg/forwardCompat-nestedSumMirror/Test_2_c3.0.2.scala b/tests/neg/forwardCompat-nestedSumMirror/Test_2_c3.0.2.scala deleted file mode 100644 index 9fa2e4003002..000000000000 --- a/tests/neg/forwardCompat-nestedSumMirror/Test_2_c3.0.2.scala +++ /dev/null @@ -1,5 +0,0 @@ -import scala.deriving._ - -object Test: - def main(args: Array[String]): Unit = - println(summon[Mirror.Of[TreeValue]]) // error diff --git a/tests/neg/forwardCompat-rejectNewerTasty/Bar_2_r3.0.scala b/tests/neg/forwardCompat-rejectNewerTasty/Bar_2_r3.0.scala deleted file mode 100644 index d78004d6dedf..000000000000 --- a/tests/neg/forwardCompat-rejectNewerTasty/Bar_2_r3.0.scala +++ /dev/null @@ -1 +0,0 @@ -def bar = foo // nopos-error diff --git a/tests/neg/forwardCompat-rejectNewerTasty/Foo_1_r3.1.scala b/tests/neg/forwardCompat-rejectNewerTasty/Foo_1_r3.1.scala deleted file mode 100644 index fe04f0623a1c..000000000000 --- a/tests/neg/forwardCompat-rejectNewerTasty/Foo_1_r3.1.scala +++ /dev/null @@ -1 +0,0 @@ -def foo = 1 diff --git a/tests/pos/forwardCompat-excludedExport/Test_r3.0.scala b/tests/pos/forwardCompat-excludedExport/Test_r3.0.scala deleted file mode 100644 index c635935471d8..000000000000 --- a/tests/pos/forwardCompat-excludedExport/Test_r3.0.scala +++ /dev/null @@ -1,2 +0,0 @@ -object A: - export Tuple.{canEqualEmptyTuple as _, canEqualTuple as _, given, *} diff --git a/tests/pos/forwardCompat-exportInExtension/Lib_1_r3.0.scala b/tests/pos/forwardCompat-exportInExtension/Lib_1_r3.0.scala deleted file mode 100644 index 099782b74c8a..000000000000 --- a/tests/pos/forwardCompat-exportInExtension/Lib_1_r3.0.scala +++ /dev/null @@ -1,13 +0,0 @@ -case class ShortString(value: String) - -class StringOps(x: ShortString): - def *(n: Int): ShortString = ??? - def capitalize: ShortString = ??? - -object stringsyntax: - - extension (x: ShortString) - def take(n: Int): ShortString = ??? - def drop(n: Int): ShortString = ??? - private def moreOps = StringOps(x) - export moreOps.* diff --git a/tests/pos/forwardCompat-exportInExtension/Test_2_c3.0.2.scala b/tests/pos/forwardCompat-exportInExtension/Test_2_c3.0.2.scala deleted file mode 100644 index 0abe6283609f..000000000000 --- a/tests/pos/forwardCompat-exportInExtension/Test_2_c3.0.2.scala +++ /dev/null @@ -1,7 +0,0 @@ -import stringsyntax.* - -def test = - ShortString("Hello").take(2) - ShortString("Hello").drop(3) - ShortString("Hello") * 5 - ShortString("Hello").capitalize diff --git a/tests/run/forwardCompat-nestedSumMirror/Lib1_1_r3.0.scala b/tests/run/forwardCompat-nestedSumMirror/Lib1_1_r3.0.scala deleted file mode 100644 index aaac31229228..000000000000 --- a/tests/run/forwardCompat-nestedSumMirror/Lib1_1_r3.0.scala +++ /dev/null @@ -1,8 +0,0 @@ -// Adapted from i11050 - -sealed trait TreeValue - -sealed trait SubLevel extends TreeValue - -case class Leaf1(value: String) extends TreeValue -case class Leaf2(value: Int) extends SubLevel diff --git a/tests/run/forwardCompat-nestedSumMirror/Lib2_2_r3.0.scala b/tests/run/forwardCompat-nestedSumMirror/Lib2_2_r3.0.scala deleted file mode 100644 index 833fe13bb71e..000000000000 --- a/tests/run/forwardCompat-nestedSumMirror/Lib2_2_r3.0.scala +++ /dev/null @@ -1,3 +0,0 @@ -import scala.deriving._ - -val treeValueMirror = summon[Mirror.Of[TreeValue]] \ No newline at end of file diff --git a/tests/run/forwardCompat-nestedSumMirror/Test_3_c3.0.2.scala b/tests/run/forwardCompat-nestedSumMirror/Test_3_c3.0.2.scala deleted file mode 100644 index 13438d173ffb..000000000000 --- a/tests/run/forwardCompat-nestedSumMirror/Test_3_c3.0.2.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test: - def main(args: Array[String]): Unit = - println(treeValueMirror) diff --git a/tests/run/forwardCompat-refinedGivens/Lib_1_r3.0.scala b/tests/run/forwardCompat-refinedGivens/Lib_1_r3.0.scala deleted file mode 100644 index 6da2077b0086..000000000000 --- a/tests/run/forwardCompat-refinedGivens/Lib_1_r3.0.scala +++ /dev/null @@ -1,16 +0,0 @@ -// Adapted from i12949 - -object Catch22: - trait TC[V] - object TC: - export Hodor.TC.given - -object Hodor: - object TC: - import Catch22.TC - given fromString[V <: String]: TC[V] = new TC[V] {} - transparent inline given fromDouble[V <: Double]: TC[V] = - new TC[V]: - type Out = Double - given fromInt[V <: Int]: TC[V] with - type Out = Int \ No newline at end of file diff --git a/tests/run/forwardCompat-refinedGivens/Test_2_c3.0.2.scala b/tests/run/forwardCompat-refinedGivens/Test_2_c3.0.2.scala deleted file mode 100644 index 35f2b594881d..000000000000 --- a/tests/run/forwardCompat-refinedGivens/Test_2_c3.0.2.scala +++ /dev/null @@ -1,7 +0,0 @@ -// Adapted from i12949 - -object Test: - def main(args: Array[String]): Unit = - summon[Catch22.TC["hi"]] - summon[Catch22.TC[7.7]] - summon[Catch22.TC[1]] diff --git a/tests/run/forwardCompat-strictEquals/Equality_1_r3.0.scala b/tests/run/forwardCompat-strictEquals/Equality_1_r3.0.scala deleted file mode 100644 index 538b85075bf9..000000000000 --- a/tests/run/forwardCompat-strictEquals/Equality_1_r3.0.scala +++ /dev/null @@ -1,5 +0,0 @@ -// Instances of CanEqual are erased during compilation so their absence at runtime should not cause a crash - -import scala.language.strictEquality - -def emptyTupleEquality = EmptyTuple == EmptyTuple diff --git a/tests/run/forwardCompat-strictEquals/Test_2_c3.0.2.scala b/tests/run/forwardCompat-strictEquals/Test_2_c3.0.2.scala deleted file mode 100644 index 1d1d811d0a9b..000000000000 --- a/tests/run/forwardCompat-strictEquals/Test_2_c3.0.2.scala +++ /dev/null @@ -1,3 +0,0 @@ -object Test: - def main(args: Array[String]): Unit = - println(emptyTupleEquality) diff --git a/tests/run/forwardCompat-unusedImport/Imports_1_r3.0.scala b/tests/run/forwardCompat-unusedImport/Imports_1_r3.0.scala deleted file mode 100644 index 7946a9c9e2cc..000000000000 --- a/tests/run/forwardCompat-unusedImport/Imports_1_r3.0.scala +++ /dev/null @@ -1,14 +0,0 @@ -object A: - import scala.quoted.Type.valueOfTuple - -object B: - import scala.quoted.Type.* - -object C: - import Tuple.canEqualTuple - -object D: - import Tuple.given - -object E: - import Selectable.WithoutPreciseParameterTypes diff --git a/tests/run/forwardCompat-unusedImport/Test_2_c3.0.2.scala b/tests/run/forwardCompat-unusedImport/Test_2_c3.0.2.scala deleted file mode 100644 index c670ace4e768..000000000000 --- a/tests/run/forwardCompat-unusedImport/Test_2_c3.0.2.scala +++ /dev/null @@ -1,7 +0,0 @@ -object Test: - def main(args: Array[String]): Unit = - println(A) - println(B) - println(C) - println(D) - println(E) From df119a2a514a97c422a33276bf3987c401fd3813 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Marks?= Date: Mon, 16 May 2022 11:25:33 +0200 Subject: [PATCH 2/6] Re-revert and edit the info about test suffixes --- docs/_docs/contributing/testing.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/_docs/contributing/testing.md b/docs/_docs/contributing/testing.md index fa333634f07b..38f7725cdf3f 100644 --- a/docs/_docs/contributing/testing.md +++ b/docs/_docs/contributing/testing.md @@ -127,6 +127,14 @@ $ sbt > testCompilation --help ``` +### Joint and separate sources compilation + +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`. + +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. + +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`. + ### Bootstrapped-only tests To run `testCompilation` on a bootstrapped Dotty compiler, use From 5c44e9761534c071fe3de9c506e8b7c3aa7cee50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Marks?= Date: Mon, 16 May 2022 11:26:43 +0200 Subject: [PATCH 3/6] Update library/src/scala/Selectable.scala Co-authored-by: Nicolas Stucki --- library/src/scala/Selectable.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/library/src/scala/Selectable.scala b/library/src/scala/Selectable.scala index 3aaa50c280f5..5b4bb3d17194 100644 --- a/library/src/scala/Selectable.scala +++ b/library/src/scala/Selectable.scala @@ -1,6 +1,5 @@ package scala -import scala.annotation.experimental /** A marker trait for objects that support structural selection via * `selectDynamic` and `applyDynamic` From 29fcd2002ea99a816aff52eca7312216b39469da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Marks?= Date: Mon, 16 May 2022 12:10:17 +0200 Subject: [PATCH 4/6] Re-revert languge-version.md --- .../src/dotty/tools/dotc/typer/CrossVersionChecks.scala | 9 --------- docs/sidebar.yml | 1 + library/src/scala/runtime/LazyVals.scala | 3 --- project/resources/referenceReplacements/sidebar.yml | 6 +----- 4 files changed, 2 insertions(+), 17 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/typer/CrossVersionChecks.scala b/compiler/src/dotty/tools/dotc/typer/CrossVersionChecks.scala index 5a0ea82468b9..41c0b6193c13 100644 --- a/compiler/src/dotty/tools/dotc/typer/CrossVersionChecks.scala +++ b/compiler/src/dotty/tools/dotc/typer/CrossVersionChecks.scala @@ -162,19 +162,10 @@ class CrossVersionChecks extends MiniPhase: tpe.foreachPart { case TypeRef(_, sym: Symbol) => checkDeprecated(sym, tree.srcPos) -<<<<<<< HEAD checkExperimentalRef(sym, tree.srcPos) - checkSinceAnnot(sym, tree.srcPos) case TermRef(_, sym: Symbol) => checkDeprecated(sym, tree.srcPos) checkExperimentalRef(sym, tree.srcPos) - checkSinceAnnot(sym, tree.srcPos) -======= - checkExperimental(sym, tree.srcPos) - case TermRef(_, sym: Symbol) => - checkDeprecated(sym, tree.srcPos) - checkExperimental(sym, tree.srcPos) ->>>>>>> d5b33c5f14 (Remove support for `-scala-output-version` flag) case _ => } tree diff --git a/docs/sidebar.yml b/docs/sidebar.yml index a4441e6589cb..bd211e2bbabb 100644 --- a/docs/sidebar.yml +++ b/docs/sidebar.yml @@ -152,6 +152,7 @@ subsection: - page: reference/experimental/cc.md - page: reference/experimental/tupled-function.md - page: reference/syntax.md + - page: reference/language-versions.md - page: reference/soft-modifier.md - page: reference/features-classification.md - title: Contributing diff --git a/library/src/scala/runtime/LazyVals.scala b/library/src/scala/runtime/LazyVals.scala index aabbd489d589..f3fe52beb9ee 100644 --- a/library/src/scala/runtime/LazyVals.scala +++ b/library/src/scala/runtime/LazyVals.scala @@ -1,7 +1,5 @@ package scala.runtime -import scala.annotation.since - /** * Helper methods used in thread-safe lazy vals. */ @@ -108,7 +106,6 @@ object LazyVals { r } - @since("3.2") def getOffsetStatic(field: java.lang.reflect.Field) = val r = unsafe.objectFieldOffset(field) if (debug) diff --git a/project/resources/referenceReplacements/sidebar.yml b/project/resources/referenceReplacements/sidebar.yml index 06507028c723..2aaca9a94599 100644 --- a/project/resources/referenceReplacements/sidebar.yml +++ b/project/resources/referenceReplacements/sidebar.yml @@ -148,10 +148,6 @@ subsection: - page: reference/experimental/cc.md - page: reference/experimental/tupled-function.md - page: reference/syntax.md - - title: Language Versions - index: reference/language-versions/language-versions.md - subsection: - - page: reference/language-versions/source-compatibility.md - - page: reference/language-versions/binary-compatibility.md + - page: reference/language-versions.md - page: reference/soft-modifier.md - page: reference/features-classification.md From d79602a11138ce0a23f6529735876e521cabfba8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Marks?= Date: Tue, 17 May 2022 15:21:56 +0200 Subject: [PATCH 5/6] Retain the documentation --- .../language-versions/binary-compatibility.md | 12 ++++++++++++ .../reference/language-versions/language-versions.md | 6 ++++++ .../source-compatibility.md} | 6 ++++-- docs/sidebar.yml | 6 +++++- 4 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 docs/_docs/reference/language-versions/binary-compatibility.md create mode 100644 docs/_docs/reference/language-versions/language-versions.md rename docs/_docs/reference/{language-versions.md => language-versions/source-compatibility.md} (74%) diff --git a/docs/_docs/reference/language-versions/binary-compatibility.md b/docs/_docs/reference/language-versions/binary-compatibility.md new file mode 100644 index 000000000000..8e24ddd6796a --- /dev/null +++ b/docs/_docs/reference/language-versions/binary-compatibility.md @@ -0,0 +1,12 @@ +--- +layout: doc-page +title: "Binary Compatibility" +--- + +In Scala 2 different minor versions of the compiler were free to change the way how they encode different language features in JVM bytecode so each bump of the compiler's minor version resulted in breaking binary compatibility and if a project had any Scala dependencies they all needed to be (cross-)compiled to the same minor Scala version that was used in that project itself. On the contrary, Scala 3 has a stable encoding into JVM bytecode. + +In addition to classfiles the compilation process in Scala 3 also produces files with `.tasty` extension. The [TASTy](https://docs.scala-lang.org/scala3/guides/tasty-overview.html) format is an intermediate representation of Scala code containing full information about sources together with information provided by the typer. Some of this information is lost during generation of bytecode so Scala 3 compilers read TASTy files during compilation in addition to classfiles to know the exact types of values, methods, etc. in already compiled classes (although compilation from TASTy files only is also possible). TASTy files are also typically distributed together with classfiles in published artifacts. + +TASTy format is extensible but it preserves backward compatibility and the evolution happens between minor releases of the language. This means a Scala compiler in version `3.x1.y1` is able to read TASTy files produced by another compiler in version `3.x2.y2` if `x1 >= x2` (assuming two stable versions of the compiler are considered - `SNAPSHOT` or `NIGHTLY` compiler versions can read TASTy in an older stable format but their TASTY versions are not compatible between each other even if the compilers have the same minor version; also compilers in stable versions cannot read TASTy generated by an unstable version). + +TASTy version number has the format of `.-` and the numbering changes in parallel to language releases in such a way that a bump in language minor version corresponds to a bump in TASTy minor version (e.g. for Scala `3.0.0` the TASTy version is `28.0-0`). Experimental version set to 0 signifies a stable version while others are considered unstable/experimental. TASTy version is not strictly bound to the data format itself - any changes to the API of the standard library also require a change in TASTy minor version. diff --git a/docs/_docs/reference/language-versions/language-versions.md b/docs/_docs/reference/language-versions/language-versions.md new file mode 100644 index 000000000000..c38538d3a82a --- /dev/null +++ b/docs/_docs/reference/language-versions/language-versions.md @@ -0,0 +1,6 @@ +--- +layout: index +title: "Language Versions" +--- + +Additional information on interoperability and migration between Scala 2 and 3 can be found [here](https://docs.scala-lang.org/scala3/guides/migration/compatibility-intro.html). diff --git a/docs/_docs/reference/language-versions.md b/docs/_docs/reference/language-versions/source-compatibility.md similarity index 74% rename from docs/_docs/reference/language-versions.md rename to docs/_docs/reference/language-versions/source-compatibility.md index ef31ccc28707..029a3674ba73 100644 --- a/docs/_docs/reference/language-versions.md +++ b/docs/_docs/reference/language-versions/source-compatibility.md @@ -1,10 +1,12 @@ --- layout: doc-page -title: "Language Versions" +title: "Source Compatibility" movedTo: https://docs.scala-lang.org/scala3/reference/language-versions.html --- -The default Scala language version currently supported by the Dotty compiler is [`3.0`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$3/0$.html). There are also other language versions that can be specified instead: +Scala 3 does NOT guarantee source compatibility between different minor language versions (e.g. some syntax valid in 3.x might get deprecated and then phased out in 3.y for y > x). There are also some syntax structures that were valid in Scala 2 but are not anymore in Scala 3. However the compiler provides a possibility to specify the desired version of syntax used in a particular file or globally for a run of the compiler to make migration between versions easier. + +The default Scala language syntax version currently supported by the Dotty compiler is [`3.0`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$3/0$.html). There are also other language versions that can be specified instead: - [`3.0-migration`](https://scala-lang.org/api/3.x/scala/runtime/stdLibPatches/language$$3/0-migration$.html): Same as `3.0` but with a Scala 2 compatibility mode that helps moving Scala 2.13 sources over to Scala 3. In particular, it diff --git a/docs/sidebar.yml b/docs/sidebar.yml index bd211e2bbabb..c7edc92c1530 100644 --- a/docs/sidebar.yml +++ b/docs/sidebar.yml @@ -152,7 +152,11 @@ subsection: - page: reference/experimental/cc.md - page: reference/experimental/tupled-function.md - page: reference/syntax.md - - page: reference/language-versions.md + - title: Language Versions + index: reference/language-versions/language-versions.md + subsection: + - page: reference/language-versions/source-compatibility.md + - page: reference/language-versions/binary-compatibility.md - page: reference/soft-modifier.md - page: reference/features-classification.md - title: Contributing From 554a3a06d65899a9c937015d60a1edb69b0f0912 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Marks?= Date: Tue, 17 May 2022 15:49:48 +0200 Subject: [PATCH 6/6] Apply changes to the second sidebar --- project/resources/referenceReplacements/sidebar.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/project/resources/referenceReplacements/sidebar.yml b/project/resources/referenceReplacements/sidebar.yml index 2aaca9a94599..06507028c723 100644 --- a/project/resources/referenceReplacements/sidebar.yml +++ b/project/resources/referenceReplacements/sidebar.yml @@ -148,6 +148,10 @@ subsection: - page: reference/experimental/cc.md - page: reference/experimental/tupled-function.md - page: reference/syntax.md - - page: reference/language-versions.md + - title: Language Versions + index: reference/language-versions/language-versions.md + subsection: + - page: reference/language-versions/source-compatibility.md + - page: reference/language-versions/binary-compatibility.md - page: reference/soft-modifier.md - page: reference/features-classification.md