-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix "Still can't use scala-parallel-collections in REPL via :dep" #25092
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
base: main
Are you sure you want to change the base?
Conversation
|
CC @bishabosha |
|
First impression without looking at the wider context - is there a time where actually you do want to re-enter the symbol - such as recompilation and the classpath adds a new definition- unless that is handled at a higher level Of course if there are already incremental compilation tests that pass that scenario then this is probably not a concern |
|
Yeah this area of the code seems pretty gnarly but I'm assuming that if I do something wrong, then something in CI should break??? |
| for (classRep <- classReps) | ||
| if (!maybeModuleClass(classRep) && hasFlatName(classRep) == flat && | ||
| (!flat || isAbsent(classRep))) // on 2nd enter of flat names, check that the name has not been entered before | ||
| isAbsent(classRep)) // Always check isAbsent to avoid re-entering existing classes (important for REPL :jar/:dep) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This edit makes the two loops identical, for module class and non-module.
|
i havent reviewed the code, but i have tried and indeed REPL works now with scala-parallel-collections, scala-parser-combinators, scala-collection-contrib added through |
|
@lihaoyi it seems libraries with some sort of jar dep on a library that introduces the same package, e.g. scala> :dep com.lihaoyi::os-lib-watch:0.11.6
Exception in thread "main" dotty.tools.dotc.core.CyclicReference: Cyclic reference involving module class os
Run with -explain-cyclic for more details.(couldnt actually get the -explain-cyclic option to work) |
|
Did some more vibing, agent@claude-sandbox-2026-01-21-224815:/Users/lihaoyi/Github/scala3$ sbt scala3-repl/run
Welcome to Scala 3.8.3-RC1-bin-SNAPSHOT-git-67dddb2 (17.0.17, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.
scala> :dep com.lihaoyi::os-lib-watch:0.11.6-M1
Resolved 1 dependencies (7 JARs)
scala> os.watch.watch
val res0: (Seq[os.Path], Set[os.Path] => Unit, (String, Any) => Unit, os.Path =>
Boolean) => AutoCloseable = Lambda$2361/0x0000008801790400@48f3210f
|
|
scala> :dep com.lihaoyi::scalasql-simple:0.2.7
Resolved 1 dependencies (11 JARs)
scala> import scalasql.simple.*
scala> type T[V] = SimpleTable[V]
// defined alias type T[V] = scalasql.namedtuples.SimpleTable[V] |
|
Seems like not quite there yet, a long session still results in errors scala> :dep com.lihaoyi::scalasql-simple:0.2.7
-- [E103] Syntax Error: --------------------------------------------------------
1 | :dep com.lihaoyi::scalasql-simple:0.2.7
| ^
| Illegal start of statement
|
| longer explanation available when compiling with `-explain`
scala> ^[[A
--
|^
|illegal character '\u001b'
scala> :dep com.lihaoyi::scalasql-simple:0.2.7
Resolved 1 dependencies (11 JARs)
scala> import scalasql.simple.*
scala> type T[V] = SimpleTable[V]
// defined alias type T[V] = scalasql.namedtuples.SimpleTable[V]
scala> :dep com.lihaoyi::os-lib-watch:0.11.6-M1
Resolved 1 dependencies (7 JARs)
scala> os.watch.watch
exception caught when loading module class Predef$: java.lang.AssertionError: assertion failed: scala.Predef$.Ensuring$ already has a symbol
-- [E044] Cyclic Error: --------------------------------------------------------
1 |os.watch.watch
| ^
| Overloaded or recursive method watch needs return type
|
| Run with -explain-cyclic for more details.
|
| longer explanation available when compiling with `-explain`
1 error found |
|
Ok seems to work now, at least at a cursory glance scala> :dep com.lihaoyi::scalasql-simple:0.2.7
Resolved 1 dependencies (11 JARs)
scala> import scalasql.simple.*
scala> type T[V] = SimpleTable[V]
// defined alias type T[V] = scalasql.namedtuples.SimpleTable[V]
scala> :dep com.lihaoyi::os-lib-watch:0.11.6-M1
Resolved 1 dependencies (7 JARs)
scala> os.watch.watch
val res0: (Seq[os.Path], Set[os.Path] => Unit, (String, Any) => Unit, os.Path =>
Boolean) => AutoCloseable = Lambda$2251/0x00000006016a8400@4cda59e6
scala> :dep org.scala-lang.modules::scala-parallel-collections:1.2.0
Resolved 1 dependencies (3 JARs)
scala> import scala.collection.parallel.CollectionConverters.seqIsParallelizable
scala> List(1,2,3).par
val res1: collection.parallel.ParSeq[Int] = ParVector(1, 2, 3)
scala> scala.collection.parallel.ParSeq(List(1,2,3)*)
val res2: collection.parallel.ParSeq[Int] = ParArray(1, 2, 3) |
|
rebuilt on your latest changes - seems loading scala> :dep com.lihaoyi::os-lib:0.11.6
Resolved 1 dependencies (5 JARs)
scala> List(1,2,3).foo // compiler will search for extension method `foo`.
exception caught when loading module class ZipFile$: java.lang.AssertionError: os.shaded_org_apache_tools_zip.ZipFile$Entry
-- [E008] Not Found Error: -----------------------------------------------------
1 |List(1,2,3).foo
|^^^^^^^^^^^^^^^
|value foo is not a member of List[Int]
1 error foundunsure if these |
|
The last few commits
|
| // This is important because :dep/:jar commands add JARs to the platform's classpath, | ||
| // and we must not lose those when a new Run is created for each input. | ||
| // In non-interactive mode, always create a fresh platform to preserve original behavior. | ||
| if _platform == null || !ctx.mode.is(Mode.Interactive) then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why we need to guard this under !ctx.mode.is(Mode.Interactive), but if we don't then all the CI jobs explode, and since the problem seems to be limited in scope to the REPL guarding it under the REPL seems fine???
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i guess the more conservative solution is that platform has some extra classpath field like "dep jars" and you copy that classpath after calling newPlatform rather than re-use the whole platform.
Edit: idk tho splitting the classpath and merging on access seems dodgy, even AggregateClassPath is mutable, although just a cache)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have any opinion here between the options, compiler/src/dotty/tools/dotc/config/JavaPlatform.scala looks pretty thin with only var currentClassPath as its mutable state. So whether we re-use the Platform itself or re-use the currentClassPath within the Platform seems immaterial
Attempts to fix #25078, vibe coded. I won't pretend I understand the fix, but I manually tested the issue reproduction and it seems to work