@@ -19,6 +19,10 @@ import scala.util.control.NonFatal
1919object ClassfileParser {
2020 /** Marker trait for unpicklers that can be embedded in classfiles. */
2121 trait Embedded
22+
23+ /** Indicate that there is nothing to unpickle and the corresponding symbols can
24+ * be invalidated. */
25+ object NoEmbedded extends Embedded
2226}
2327
2428class ClassfileParser (
@@ -147,6 +151,15 @@ class ClassfileParser(
147151
148152 setClassInfo(classRoot, classInfo)
149153 setClassInfo(moduleRoot, staticInfo)
154+ } else if (result == Some (NoEmbedded )) {
155+ for (sym <- List (moduleRoot.sourceModule.symbol, moduleRoot.symbol, classRoot.symbol)) {
156+ classRoot.owner.asClass.delete(sym)
157+ if (classRoot.owner == defn.ScalaShadowingPackageClass ) {
158+ // Symbols in scalaShadowing are also added to scala
159+ defn.ScalaPackageClass .delete(sym)
160+ }
161+ sym.markAbsent()
162+ }
150163 }
151164
152165 // eager load java enum definitions for exhaustivity check of pattern match
@@ -700,6 +713,10 @@ class ClassfileParser(
700713 }
701714 }
702715
716+ // Nothing$ and Null$ were incorrectly emitted with a Scala attribute
717+ // instead of ScalaSignature before 2.13.0-M2, see https://github.com/scala/scala/pull/5952
718+ private [this ] val scalaUnpickleWhitelist = List (tpnme.nothingClass, tpnme.nullClass)
719+
703720 /** Parse inner classes. Expects `in.bp` to point to the superclass entry.
704721 * Restores the old `bp`.
705722 * @return true iff classfile is from Scala, so no Java info needs to be read.
@@ -760,6 +777,18 @@ class ClassfileParser(
760777 return unpickleTASTY(in.nextBytes(attrLen))
761778 }
762779
780+ if (scan(tpnme.ScalaATTR ) && ! scalaUnpickleWhitelist.contains(classRoot.name)) {
781+ // To understand the situation, it's helpful to know that:
782+ // - Scalac emits the `ScalaSig` attribute for classfiles with pickled information
783+ // and the `Scala` attribute for everything else.
784+ // - Dotty emits the `TASTY` attribute for classfiles with pickled information
785+ // and the `Scala` attribute for _every_ classfile.
786+ //
787+ // Therefore, if the `Scala` attribute is present but the `TASTY`
788+ // attribute isn't, this classfile is a compilation artifact.
789+ return Some (NoEmbedded )
790+ }
791+
763792 if (scan(tpnme.RuntimeAnnotationATTR )) {
764793 val attrLen = in.nextInt
765794 val nAnnots = in.nextChar
0 commit comments