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

Feature Request: Make zinc Scala 3 macro-aware #1478

Open
gzoller opened this issue Oct 21, 2024 · 3 comments
Open

Feature Request: Make zinc Scala 3 macro-aware #1478

gzoller opened this issue Oct 21, 2024 · 3 comments

Comments

@gzoller
Copy link

gzoller commented Oct 21, 2024

It would be amazing if incremental compilation was aware of macro dependencies—changes in code generated by a Scala 3 macro. The problem is described here: https://github.com/gzoller/scala-reflection#learning-to-drive-with-macros

If this could be made to work, code using macros would be as seamless as non-macro code with respect to compilation.

@Friendseeker
Copy link
Member

Friendseeker commented Oct 21, 2024

Since macros are the only access to reflected class information in Scala 3, it's an "ism" we'll all have to live with, until such time as someone invents a way to track macro dependencies in sbt.

Zinc actually do... track macro dependencies (kinda), with a fully fledged development roadmap back in 2014 and partial implementations of the roadmap scattered around the years, with the latest in #1282, #1316. The example mentioned in the article

// File1.scala
case  class  Foo(name: String)

// File2.scala
val  fooRType = RType.of[Foo]

actually works if one uses Scala 2.12 and latest sbt version. (assuming RType.of[T] is a macro that reflectively inspect T).

I would say that macro invalidation is practically a solved problem if one sufficiently familiar with Macro Engine is willing to give it a last push. The only puzzle piece missing is tracking symbols touched reflectively during macro reflection, and a 2014 POC showed that it is feasible. (Just that 2014 POC did it in a really hacky way, so it was unmerged).

@gzoller
Copy link
Author

gzoller commented Oct 24, 2024

You mention Scala 2 macros. Is this partial capability also present for Scala 3 macros? So far I haven’t seen that anything picks up changes in the macro vs generated code, so its very easy to get in a situation where you change the code your macro expands over (ex: RType.of[Foo] where Foo has just changed) yet the macro is not re-expanded. You still have expanded code for the old, pre-change Foo. It’ll all compile fine and explode quite dramatically when run, usually with an obscure error that means nothing to the uninitiated. In an ideal world, zinc would detect Foo’s change and when it happened upon RType.of[Foo] would re-run the macro expansion, giving a seamless experience.

@Friendseeker
Copy link
Member

Friendseeker commented Oct 25, 2024

You mention Scala 2 macros. Is this partial capability also present for Scala 3 macros? So far I haven’t seen that anything picks up changes in the macro vs generated code, so its very easy to get in a situation where you change the code your macro expands over (ex: RType.of[Foo] where Foo has just changed) yet the macro is not re-expanded. You still have expanded code for the old, pre-change Foo. It’ll all compile fine and explode quite dramatically when run, usually with an obscure error that means nothing to the uninitiated. In an ideal world, zinc would detect Foo’s change and when it happened upon RType.of[Foo] would re-run the macro expansion, giving a seamless experience.

Not yet. Currently the partial capability is only available for Scala 2.12. Still need to port to Scala 2.13 and Scala 3. I plan to do it soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants