Skip to content

Commit

Permalink
Fail early & more clearly on shaded-broken classfiles
Browse files Browse the repository at this point in the history
The shading utility uses for the coursier or coursierapi classes has
removed the RuntimeVisibleAnnotation attribute after the ScalaSignature
attribute.  Parsing such a classfile caused the Scala 3 compiler to
parse the file as a Java classfile.  It seems there something about how
we deal with packages and package objects (which don't exist in Java)
when we are incorrectly sent down this code path.  The Scala 2 compiler
already correctly caught and failed on this early, with this detail, so
look to do the same here.

Automating the test for this isn't easy.  Because relying on an external
dependency would be a hazard for CI, long term.  Perhaps we could try to
recreate a classfile with a similar bytecode problem, but that would be
quite involved as well.  I guess we could commit some or all of the
classfiles from the original, but it's generally advised not to commit
binaries to the source repo.

So instead I'm leaving instructions as to how I manually tested this, in
preparing this change.  I used coursier's `cs` binary to download the
jars and produce a classpath string:

     cs fetch -p org.scalameta:scalafmt-dynamic_2.13:3.8.1

Then I invoked `scalac` in the sbt shell, passing that classpath string:

    scalac -classpath $classpathAbove i20405.scala
    scalac -classpath $classpathAbove i20555.scala

Using the two minisations in the 20405 and 20555 issues.

[Cherry-picked cecfa8c]
  • Loading branch information
dwijnand authored and WojciechMazur committed Aug 27, 2024
1 parent 0c280c7 commit 5a7cc67
Showing 1 changed file with 4 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -1163,7 +1163,10 @@ class ClassfileParser(
// attribute isn't, this classfile is a compilation artifact.
return Some(NoEmbedded)

if (scan(tpnme.ScalaSignatureATTR) && scan(tpnme.RuntimeVisibleAnnotationATTR)) {
if (scan(tpnme.ScalaSignatureATTR)) {
if !scan(tpnme.RuntimeVisibleAnnotationATTR) then
report.error(em"No RuntimeVisibleAnnotations in classfile with ScalaSignature attribute: ${classRoot.fullName}")
return None
val attrLen = in.nextInt
val nAnnots = in.nextChar
var i = 0
Expand Down

0 comments on commit 5a7cc67

Please sign in to comment.