Skip to content

Fix REPL usage of macros loaded via :dep and :jar#25312

Merged
Gedochao merged 1 commit intoscala:mainfrom
lihaoyi:25291
Feb 19, 2026
Merged

Fix REPL usage of macros loaded via :dep and :jar#25312
Gedochao merged 1 commit intoscala:mainfrom
lihaoyi:25291

Conversation

@lihaoyi
Copy link
Contributor

@lihaoyi lihaoyi commented Feb 19, 2026

Fixed #25291, vibe coded. Seems to pass manual testing and regression tests that fail without this fix. This is an existing bug with :jar that was only noticed in :dep because people actually want to use it (whereas nobody uses :jar)

lihaoyi scala3$ sbt "scala3-repl/run"
Welcome to Scala 3.8.4-RC1-bin-SNAPSHOT-git-e48a0d9 (25.0.1, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.

scala> :dep com.lihaoyi::upickle:4.4.3
Resolved 1 dependencies (8 JARs)

scala> case class Foo(x: Int) derives upickle.ReadWriter
// defined case class Foo

scala> upickle.write(Foo(123))
val res0: String = "{\"x\":123}"

Root cause: REPL commands :dep and :jar update the runtime/compiler classpath dynamically, but macro expansion was using a macro classloader derived from the static settings classpath (and cached), so newly added macro implementation classes were invisible.

Why this fix works:

  • In interactive mode, MacroClassLoader.fromContext now rebuilds from the live ctx.platform.classPath instead of reusing the cached/static loader.
  • :dep and :jar both call ctx.platform.addToClassPath(...), so their additions are now visible to macro expansion immediately.
  • Fallback to settings classpath is kept only for early initialization when platform is not ready yet.

Why this is the correct fix:

  • It fixes the mismatch at the actual abstraction boundary: macro loading should follow the compiler’s effective classpath in REPL sessions, not startup CLI settings.
  • It is scoped: non-interactive compiler behavior remains unchanged (still uses cached loader).
  • It unifies behavior for both dynamic classpath mechanisms (:dep and :jar) with one coherent change.
  • It is validated by regression tests showing:
    • failures without patch (macro CNF on both :dep and :jar)
    • passes with patch for all reproduced scenarios.

Copy link
Contributor

@Gedochao Gedochao left a comment

Choose a reason for hiding this comment

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

lgtm

@Gedochao Gedochao added the backport:nominated If we agree to backport this PR, replace this tag with "backport:accepted", otherwise delete it. label Feb 19, 2026
@Gedochao Gedochao added this to the 3.8.3 milestone Feb 19, 2026
@Gedochao Gedochao merged commit 75cea31 into scala:main Feb 19, 2026
60 checks passed
@bishabosha
Copy link
Member

seems to work well in local testing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:nominated If we agree to backport this PR, replace this tag with "backport:accepted", otherwise delete it.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cannot exec macros in repl resolved with :dep

3 participants

Comments