Skip to content

[BUG]: type inference within scope of opaque types breaks effect handling #1367

@hearnadam

Description

@hearnadam

Version

0.19.0

Scala Version

3.7.1

Expected Behavior

Adding extension methods that involve effect handling with an effect type should work.

import kyo.*


opaque type X = Int
object X:
  def apply(i: Int): X = i
  extension (x: X)
    def emit: Unit < Emit[X] = Emit.value(x)

object Test:
  import X.*
  val x = X(0)
  @main def main = println(Emit.run(x.emit).eval)

Actual Behavior

def emit: Unit < Emit[X] = Emit.value(x) infers Emit.value[Int] instead of Emit.value[X], causing an effect to register with the Tag[Emit[scala.Int]], instead of Tag[Emit[X]]

kyo.bug$KyoBugException: BUG Unexpected pending effect while handling scala.Any: Kyo(kyo.Emit[scala.Int], Input(0), main.scala:13:36, @main def main = println(Emit.run) Please open an issue 🥹 https://github.com/getkyo/kyo/issues
	at kyo.bug$KyoBugException$.apply(data.scala:14)
	at kyo.bug$.apply(data.scala:26)
	at kyo.kernel$package$.failTag(kernel.scala:36)
	at kyo.kernel.Pending$package$$less$.inline$failTag$i1(Pending.scala:18)
	at  @main def main = println(Emit.run(x.emit).eval @ Test$.main(main.scala:13)
	at Test$.main(main.scala:13)
	at main.main(main.scala:13)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at sbt.Run.invokeMain(Run.scala:144)
	at sbt.Run.execute$1(Run.scala:94)
	at sbt.Run.$anonfun$runWithLoader$5(Run.scala:121)
	at sbt.Run$.executeSuccess(Run.scala:187)
	at sbt.Run.runWithLoader(Run.scala:121)
	at sbt.Run.run(Run.scala:128)
	at com.olegych.scastie.sbtscastie.SbtScastiePlugin$$anon$1.$anonfun$run$1(SbtScastiePlugin.scala:38)
	at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
	at sbt.util.InterfaceUtil$$anon$1.get(InterfaceUtil.scala:32)
	at sbt.ScastieTrapExit$App.run(ScastieTrapExit.scala:258)
	at java.base/java.lang.Thread.run(Thread.java:840)

Steps to Reproduce

https://scastie.scala-lang.org/wjcx4Tj5TrypdwC2jKOpNA

Current Workaround

Manual type annotation or moving effect handlers outside the opaque object.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions