-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Typer regression in getkyo/kyo
#22974
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
Comments
Another kyo issue refering to the same bisect, but not minimized: //> using dep "io.getkyo::kyo-core:0.17.0"
//> using dep "org.scalatest::scalatest-freespec:3.2.19"
package kyo
import org.scalatest.freespec.AsyncFreeSpec
import org.scalatest.Assertion
class Test extends AsyncFreeSpec {
def run(v: Assertion < (Abort[Any] & Async & Resource)): Assertion = ???
given Frame = ???
"test" in run {
(for
size <- Choice.get(Seq(1))
channel <- Channel.init[Int](size)
latch <- Latch.init(1)
pollFiber <- Async.run(
latch.await.andThen(Async.fill(100, 100)(Abort.run(channel.poll)))
)
polled <- pollFiber.get
yield assert(0 == polled.count(_.toMaybe.flatten.isDefined)))
.pipe(Choice.run, _.unit, Loop.repeat(1))
.andThen(succeed)
}
}
[error] ./defs.scala:21:36
[error] Found: $proxy38.Absent | $proxy38.Present[Int]
[error] Required: (kyo.Maybe.Absent | kyo.Maybe.Present[Int]) & ($proxy38.Absent | $proxy38.Present[Int])
[error] yield assert(0 == polled.count(_.toMaybe.flatten.isDefined)))
[error] |
cc @jchyb |
fyi @fwbrasil |
Minimised further (same error, the issue seems to be that somewhere when retyping the inlined f function and it's application, we lose the data about proxies - f$proxy.apply is typed as opaque type Queue = Queue.Unsafe
object Queue:
abstract class Unsafe
opaque type Unbounded = Queue
object Unbounded:
inline def initWith()(f: Unbounded => Unit): Unit =
f(Unsafe.init())
opaque type Unsafe <: Queue.Unsafe = Queue
object Unsafe:
def init[A](): Unsafe = ???
sealed trait Resource
object Resource:
def run: Unit =
Queue.Unbounded.initWith() { q =>
???
} |
Minimisation without inlines: object outer:
opaque type Queue = Queue.Unsafe
object Queue:
abstract class Unsafe
opaque type Unbounded = Queue
object Unbounded:
opaque type Unsafe <: Queue.Unsafe = Queue
object Unsafe:
def init[A](): Unsafe = ???
object Resource:
def run: Unit =
// we would generate these as part of inlining
val $proxy2: outer.type{type Queue = outer.Queue.Unsafe} =
outer.asInstanceOf[outer.type{type Queue = outer.Queue.Unsafe}]
val $proxy1: $proxy2.Queue.type{type Unbounded = $proxy2.Queue} =
$proxy2.Queue.asInstanceOf[$proxy2.Queue.type{type Unbounded = $proxy2.Queue}]
val $proxy3: $proxy1.Unbounded.type{type Unsafe = $proxy2.Queue} =
$proxy1.Unbounded.asInstanceOf[$proxy1.Unbounded.type{type Unsafe = $proxy2.Queue}]
val Unbounded$_this:
$proxy1.Unbounded.type{type Unsafe = $proxy2.Queue} = $proxy3
val f$proxy1: (outer.Queue.Unbounded => Unit) & ($proxy1.Unbounded => Unit) =
((q: outer.Queue.Unbounded) => ???).asInstanceOf[(outer.Queue.Unbounded => Unit) & ($proxy1.Unbounded => Unit)]
val app: Unbounded$_this.Unsafe = Unbounded$_this.Unsafe.init()
f$proxy1(app) The underlying issue seems to be with the type comparer. The above should compile, yet it does not, as the apply method of |
Minimisation derived from the second issue listed here (although with a different error); object other:
sealed abstract class Absent
case object Absent extends Absent
case class PresentAbsent(val depth: Int)
opaque type Present[+A] = A | PresentAbsent
opaque type Maybe[+A] >: (Absent | Present[A]) = Absent | Present[A]
extension [A](self: Maybe[A]) {
inline def flatten[B]: Maybe[B] = if isEmpty then Absent else ???
inline def isDefined: Boolean = !isEmpty
def isEmpty: Boolean = self.isInstanceOf[Absent]
}
class Test {
def main(): Unit =
import other.Maybe
val res: Maybe[Maybe[Int]] = ???
res.flatten.isDefined
} error: 20 | res.flatten.isDefined
| ^^^
| Found: (self$proxy1 : (res : other.Maybe[other.Maybe[Int]]) &
| $proxy1.Maybe[$proxy1.Maybe[Int]])
| Required: other$_this.Maybe[other.Maybe[Int]] |
Minimisation of the second issue (different error, and a different bug from the above) - needs two modules/compilation steps. import scala.quoted._
inline def passThorugh(inline condition: Boolean): Any =
${ passThorughImpl('{condition}) }
def passThorughImpl(condition: Expr[Boolean])(using Quotes): Expr[Any] = condition Maybe.scala: package pack
import Maybe._
opaque type Maybe[+A] >: (Absent | Present[A]) = Absent | Present[A]
object Maybe:
sealed abstract class Absent
case object Absent extends Absent
object internal:
case class PresentAbsent(val depth: Int)
opaque type Present[+A] = A | internal.PresentAbsent
extension [A](self: Maybe[A]) {
inline def flatten[B]: Maybe[B] = ???
inline def isDefined: Boolean = ???
} main.test.scala: object Test {
def main(): Unit =
import pack.Maybe
val res: Maybe[Maybe[Int]] = ???
passThorugh(res.flatten.isDefined)
} scala-cli compile --test --server=false Maybe.scala main.test.scala macro.scala |
Based on OpenCB failure in
getkyo/kyo
- build logsWe failed to spot the problem earlier, becouse it previously failed due to different errors since
3.6.4-RC1-bin-20241121-5d1d274-NIGHTLY
(when using different project revision)Compiler version
3.7.0-RC2
Last good release: 3.7.0-RC1-bin-20250119-bd699fc-NIGHTLY
First bad release: 3.7.0-RC1-bin-20250120-db23c08-NIGHTLY
Bisect points to fe2e6e9 but some revisions fail with different errors or StackOverflowError
Minimized code
Output
Different error
3.7.0-RC1-bin-20250120-db23c08-NIGHTLY
Expectation
The text was updated successfully, but these errors were encountered: