Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attempt to fix Scala 3 enum in snippet.sc, instead reproduce an issue with TypeRepr.of[A].memberType(subtype) #533

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

MateuszKubuszok
Copy link
Member

@MateuszKubuszok MateuszKubuszok commented May 13, 2024

When Scala CLI snippet.sc is used macro generates assertion errors when Scala 3 enum is used:

  • recommended way of calculating the type is TypeRepr.of[A].memberType(subtypeSymbol)

  • the current way is based on subtypeSymbol.typeRef which cannot be used for types defined in

    class SomeClass {
      type InnerType
    }

    and enum and each case becomes a type defined in another class when we use snippet.sc (interestingly the issue does not appear for case objects nor case classes)

  • however this recommended solution also upcasts parametherless casess, so that children of

     enum Foo:
       case Bar(value: Int)
       case Baz

    are resolved to List(Foo.Bar, Foo) (which breaks macro in another way).

Once this is solved, all Scala 3 snippets in documentation with enums - which required:

@main def example: Unit = {
// actual code
}

can have the workaround removed.

Copy link

codecov bot commented May 13, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 89.53%. Comparing base (35f50d4) to head (7e16b56).
Report is 7 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #533      +/-   ##
==========================================
+ Coverage   87.72%   89.53%   +1.81%     
==========================================
  Files         136      104      -32     
  Lines        5440     2589    -2851     
  Branches      438      243     -195     
==========================================
- Hits         4772     2318    -2454     
+ Misses        668      271     -397     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

fromUntyped[A] {
val isScala3EnumButNotJavaEnum =
subtype.flags.is(Flags.Enum | Flags.StableRealizable) && !subtype.flags.is(Flags.JavaStatic)
if isScala3EnumButNotJavaEnum then TypeRepr.of[A].memberType(subtype)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recommended fix - unfortunately makes parameterless cases upcasted :(

} yield {
import fixedFrom.Underlying as FixedFrom
Ref(name).asExprOf[FixedFrom].asInstanceOf[Expr[From]]
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Naive attempt to apply TypeRepr.of[A].memberType(subtype) fix once we already matched types. Does not work.

val fixedSym =
if !sym.flags.is(Flags.JavaStatic) then TypeRepr.of[From].typeSymbol.children.find(_.name == sym.name).get
else sym
CaseDef(Bind(bindName, Ident(fixedSym.termRef)), None, body)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

.replaceAll("\\$\\d+", "")
catch {
case e: StackOverflowError => expr.toString
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some reason, when working with cases that this PR attempts to fix, I sometimes get StackOverflow from expr.asTerm.show(using Printer.TreeAnsiCode) :O

}

new Snippet().result
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Poorly named test to check if fix worked without sbt publishLocal -> scala-cli scripts/test-snippets.scala trip.

@MateuszKubuszok MateuszKubuszok added the blocked Ticket cannot be implemented because it depends on another ticker or external factor label May 16, 2024
@MateuszKubuszok MateuszKubuszok added the bug Erroneous behavior in existing features label May 23, 2024
@MateuszKubuszok MateuszKubuszok changed the title Attempt to fix things, instead reproduce an issue with TypeRepr.of[A].memberType(subtype) Attempt to fix Scala 3 enum in snippet.sc, instead reproduce an issue with TypeRepr.of[A].memberType(subtype) May 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocked Ticket cannot be implemented because it depends on another ticker or external factor bug Erroneous behavior in existing features
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant