diff --git a/compiler/src/dotty/tools/backend/jvm/GenBCode.scala b/compiler/src/dotty/tools/backend/jvm/GenBCode.scala index 0705839ea504..0c6015fa304d 100644 --- a/compiler/src/dotty/tools/backend/jvm/GenBCode.scala +++ b/compiler/src/dotty/tools/backend/jvm/GenBCode.scala @@ -223,20 +223,24 @@ class GenBCodePipeline(val entryPoints: List[Symbol], val int: DottyBackendInter if (claszSymbol.isClass) // @DarkDimius is this test needed here? for (binary <- ctx.compilationUnit.pickled.get(claszSymbol.asClass)) { - val dataAttr = new CustomAttr(nme.TASTYATTR.mangledString, binary) val store = if (mirrorC ne null) mirrorC else plainC + val tasty = + if (ctx.settings.emitTasty.value) { + val outTastyFile = getFileForClassfile(outF, store.name, ".tasty") + val outstream = new DataOutputStream(outTastyFile.bufferedOutput) + try outstream.write(binary) + finally outstream.close() + // TASTY attribute is created but 0 bytes are stored in it. + // A TASTY attribute has length 0 if and only if the .tasty file exists. + Array.empty[Byte] + } else { + // Create an empty file to signal that a tasty section exist in the corresponding .class + // This is much cheaper and simpler to check than doing classfile parsing + getFileForClassfile(outF, store.name, ".hasTasty") + binary + } + val dataAttr = new CustomAttr(nme.TASTYATTR.mangledString, tasty) store.visitAttribute(dataAttr) - if (ctx.settings.emitTasty.value) { - val outTastyFile = getFileForClassfile(outF, store.name, ".tasty") - val outstream = new DataOutputStream(outTastyFile.bufferedOutput) - - try outstream.write(binary) - finally outstream.close() - } else { - // Create an empty file to signal that a tasty section exist in the corresponding .class - // This is much cheaper and simpler to check than doing classfile parsing - getFileForClassfile(outF, store.name, ".hasTasty") - } } // -------------- bean info class, if needed -------------- diff --git a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala index 483153091f03..e13311ddeb4d 100644 --- a/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala +++ b/compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala @@ -13,7 +13,7 @@ import scala.collection.{ mutable, immutable } import scala.collection.mutable.{ ListBuffer, ArrayBuffer } import scala.annotation.switch import typer.Checking.checkNonCyclic -import io.AbstractFile +import io.{AbstractFile, PlainFile} import scala.util.control.NonFatal object ClassfileParser { @@ -781,7 +781,13 @@ class ClassfileParser( if (scan(tpnme.TASTYATTR)) { val attrLen = in.nextInt - return unpickleTASTY(in.nextBytes(attrLen)) + if (attrLen == 0) { + // A tasty attribute implies the existence of the .tasty file + val file = new PlainFile(io.File(classfile.jpath).changeExtension("tasty")) + if (file.exists) return unpickleTASTY(new AbstractFileReader(file).nextBytes(file.sizeOption.get)) + else ctx.error("Could not find " + file) + } + else return unpickleTASTY(in.nextBytes(attrLen)) } if (scan(tpnme.ScalaATTR) && !scalaUnpickleWhitelist.contains(classRoot.name)) { diff --git a/compiler/test/dotty/tools/dotc/CompilationTests.scala b/compiler/test/dotty/tools/dotc/CompilationTests.scala index cc69e927e26f..cf9b12c26bd7 100644 --- a/compiler/test/dotty/tools/dotc/CompilationTests.scala +++ b/compiler/test/dotty/tools/dotc/CompilationTests.scala @@ -96,6 +96,7 @@ class CompilationTests extends ParallelTesting { compileFilesInDir("../tests/pos-scala2", scala2Mode) + compileFilesInDir("../tests/pos", defaultOptions) + compileFilesInDir("../tests/pos-deep-subtype", allowDeepSubtypes) + + compileDir("../tests/pos/i1137-1", defaultOptions and "-YemitTasty") + compileFile( // succeeds despite -Xfatal-warnings because of -nowarn "../tests/neg/customArgs/xfatalWarnings.scala",