Skip to content

Commit e4b1cfe

Browse files
committed
Use names instead of type symbols when scanning for pickling annotations
When scanning for Scala pickling annotations, all annotations in all classfiles (including those produced by the Java compiler) are considered. Before this commit, a Type and Symbol were created for each discovered annotation and comparared to the known Scala signature annotation types. In certain situations (as in tests/pos/i15166), this is problematic, as the denotation of an annotation symbol defined as a Java inner class may be forced before the inner class table is populated and setClassInfo is called on the class root. Comparing names (as strings) rather than type symbols avoids this situation. Fixes #15166
1 parent 64815bb commit e4b1cfe

File tree

5 files changed

+31
-9
lines changed

5 files changed

+31
-9
lines changed

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -961,13 +961,9 @@ class Definitions {
961961
@tu lazy val NativeAnnot: ClassSymbol = requiredClass("scala.native")
962962
@tu lazy val RepeatedAnnot: ClassSymbol = requiredClass("scala.annotation.internal.Repeated")
963963
@tu lazy val SourceFileAnnot: ClassSymbol = requiredClass("scala.annotation.internal.SourceFile")
964-
@tu lazy val ScalaSignatureAnnot: ClassSymbol = requiredClass("scala.reflect.ScalaSignature")
965-
@tu lazy val ScalaLongSignatureAnnot: ClassSymbol = requiredClass("scala.reflect.ScalaLongSignature")
966964
@tu lazy val ScalaStrictFPAnnot: ClassSymbol = requiredClass("scala.annotation.strictfp")
967965
@tu lazy val ScalaStaticAnnot: ClassSymbol = requiredClass("scala.annotation.static")
968966
@tu lazy val SerialVersionUIDAnnot: ClassSymbol = requiredClass("scala.SerialVersionUID")
969-
@tu lazy val TASTYSignatureAnnot: ClassSymbol = requiredClass("scala.annotation.internal.TASTYSignature")
970-
@tu lazy val TASTYLongSignatureAnnot: ClassSymbol = requiredClass("scala.annotation.internal.TASTYLongSignature")
971967
@tu lazy val TailrecAnnot: ClassSymbol = requiredClass("scala.annotation.tailrec")
972968
@tu lazy val ThreadUnsafeAnnot: ClassSymbol = requiredClass("scala.annotation.threadUnsafe")
973969
@tu lazy val ConstructorOnlyAnnot: ClassSymbol = requiredClass("scala.annotation.constructorOnly")

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

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ object ClassfileParser {
5050
mapOver(tp)
5151
}
5252
}
53+
54+
private inline def sigOfClassName(n: String) = s"L$n;"
55+
val ScalaSignatureAnnot: String = sigOfClassName("scala.reflect.ScalaSignature")
56+
val ScalaLongSignatureAnnot: String = sigOfClassName("scala.reflect.ScalaLongSignature")
57+
val TASTYSignatureAnnot: String = sigOfClassName("scala.annotation.internal.TASTYSignature")
58+
val TASTYLongSignatureAnnot: String = sigOfClassName("scala.annotation.internal.TASTYLongSignature")
5359
}
5460

5561
class ClassfileParser(
@@ -1004,19 +1010,19 @@ class ClassfileParser(
10041010
val nAnnots = in.nextChar
10051011
var i = 0
10061012
while (i < nAnnots) {
1007-
val attrClass = pool.getType(in.nextChar).typeSymbol
1013+
val attrSig = pool.getExternalName(in.nextChar).value
10081014
val nArgs = in.nextChar
10091015
var j = 0
10101016
while (j < nArgs) {
10111017
val argName = pool.getName(in.nextChar)
10121018
if (argName.name == nme.bytes) {
1013-
if (attrClass == defn.ScalaSignatureAnnot)
1019+
if attrSig == ScalaSignatureAnnot then
10141020
return unpickleScala(parseScalaSigBytes)
1015-
else if (attrClass == defn.ScalaLongSignatureAnnot)
1021+
else if attrSig == ScalaLongSignatureAnnot then
10161022
return unpickleScala(parseScalaLongSigBytes)
1017-
else if (attrClass == defn.TASTYSignatureAnnot)
1023+
else if attrSig == TASTYSignatureAnnot then
10181024
return unpickleTASTY(parseScalaSigBytes)
1019-
else if (attrClass == defn.TASTYLongSignatureAnnot)
1025+
else if attrSig == TASTYLongSignatureAnnot then
10201026
return unpickleTASTY(parseScalaLongSigBytes)
10211027
}
10221028
parseAnnotArg(skip = true)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import java.lang.annotation.Retention;
2+
import java.lang.annotation.RetentionPolicy;
3+
4+
@InterfaceStability_JAVA_ONLY_1.Evolving(bytes="no")
5+
public class InterfaceAudience_JAVA_ONLY_1 {
6+
@Retention(RetentionPolicy.RUNTIME)
7+
public @interface Public { String bytes(); }
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import java.lang.annotation.Retention;
2+
import java.lang.annotation.RetentionPolicy;
3+
4+
@InterfaceAudience_JAVA_ONLY_1.Public(bytes="yes")
5+
public class InterfaceStability_JAVA_ONLY_1 {
6+
@Retention(RetentionPolicy.RUNTIME)
7+
public @interface Evolving { String bytes(); }
8+
}

tests/pos/i15166/Test_2.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// scalac: -Xfatal-warnings
2+
object Test {
3+
val x: InterfaceAudience_JAVA_ONLY_1.Public = ???
4+
}

0 commit comments

Comments
 (0)