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

Finding implicit Tag fails sometimes for generic type argument #8834

Open
andrzejressel opened this issue May 9, 2024 · 5 comments · May be fixed by #8883
Open

Finding implicit Tag fails sometimes for generic type argument #8834

andrzejressel opened this issue May 9, 2024 · 5 comments · May be fixed by #8883

Comments

@andrzejressel
Copy link
Contributor

andrzejressel commented May 9, 2024

I couldn't find a pattern why these errors are happening.

ZIO: 2.0 and 2.1
Scala: 3.3 and 3.4

Example1

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

import zio.ZIOApp
import zio.*

trait SourceOfC

trait ABC[MyC: Tag] {

  def run: ZIO[Any, Any, Any] = {
    val t = (for {
      _ <- ZIO.service[MyC]
      _ <- ZIO.service[SourceOfC] // Comment 1
      p <- useMyC() // Comment 2
    } yield ())
    
    val o = t.provide(sourceOfCLayer, obtainC)

    o
  }

  val sourceOfCLayer: ZLayer[Any, Throwable, SourceOfC] = ???
  val obtainC: ZLayer[SourceOfC, Any, MyC] = ???
  def useMyC(): ZIO[MyC & SourceOfC, Nothing, Unit] = ???
}

Commenting either line 11 or 12 fixes the issue. Replacing MyC with empty trait also fixes it.

Example 2

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

import zio.ZIOApp
import zio.*

trait ABC[MyC: Tag] {

  def run2() = {
    (for {
      _ <- ZIO.service[MyC]
    } yield ()).provide(provideC, anotherLayer) // Removing anotherLayer fixes
  }

  val provideC: ZLayer[Any, Any, MyC] = ???
  val anotherLayer: ZLayer[Any, Any, Unit] = ???

}

Here the existence of Unit layer (like Logging ones) breaks stuff. Making anotherLayer return type non-Unit or extracting MyC to empty trait fixes.

At the beginning I thought it has to do with number of abstract arguments, but that's not the case: https://scastie.scala-lang.org/6h5rekHNSZKybKnOEMYO2A

Error for SEO:

ABC.this.MyC is a type parameter without an implicit Tag!
  could not find implicit value for izumi.reflect.Tag[ABC.this.MyC]. Did you forget to put on a Tag, TagK or TagKK context bound on one of the parameters in ABC.this.MyC? e.g. def x[T: Tag, F[_]: TagK] = ...
@jdegoes
Copy link
Member

jdegoes commented May 15, 2024

/bounty $100

Copy link

algora-pbc bot commented May 15, 2024

💎 $100 bounty • ZIO

Steps to solve:

  1. Start working: Comment /attempt #8834 with your implementation plan
  2. Submit work: Create a pull request including /claim #8834 in the PR body to claim the bounty
  3. Receive payment: 100% of the bounty is received 2-5 days post-reward. Make sure you are eligible for payouts

Thank you for contributing to zio/zio!

Add a bountyShare on socials

Attempt Started (GMT+0) Solution
🟢 @andrzejressel May 20, 2024, 6:17:56 PM #8883

@andrzejressel
Copy link
Contributor Author

andrzejressel commented May 19, 2024

Index: core/shared/src/main/scala-3/zio/internal/macros/LayerMacroUtils.scala
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/core/shared/src/main/scala-3/zio/internal/macros/LayerMacroUtils.scala b/core/shared/src/main/scala-3/zio/internal/macros/LayerMacroUtils.scala
--- a/core/shared/src/main/scala-3/zio/internal/macros/LayerMacroUtils.scala	(revision b9f54f5211389cf2fb807c3774f400e7ed336339)
+++ b/core/shared/src/main/scala-3/zio/internal/macros/LayerMacroUtils.scala	(date 1716157106781)
@@ -1,8 +1,9 @@
 package zio.internal.macros
 
-import zio._
-import scala.quoted._
-import scala.compiletime._
+import zio.*
+
+import scala.quoted.*
+import scala.compiletime.*
 import zio.internal.macros.StringUtils.StringOps
 import zio.internal.ansi.AnsiStringOps
 
@@ -61,7 +62,11 @@
         case '{$lhs: ZLayer[i, e, o]} =>
           rhs match {
             case '{$rhs: ZLayer[i2, e2, o2]} =>
-              '{$lhs.++($rhs)}
+              Expr.summon[Tag[o2]] match {
+                case Some(t) =>
+                  '{$lhs.++($rhs)(using $t)}
+                case _ => throw new Error("OptionalImplicit should be always available")
+              }
           }
       }

Seems to fix it, but I hate it. Maybe it's compiler problem?

EDIT: Yeah - it seems that compiler will take the most outer implicit instead of closest one

EDIT2: I've asked on users forum about that: https://users.scala-lang.org/t/scala-3-when-calling-method-with-implicit-value-within-quotes-implicit-in-scope-is-not-found/10003

EDIT3: I believe the message is not from implicitnotfound annotation, but from macro that generates Izumi tag - I'll try to verify it today

@andrzejressel
Copy link
Contributor Author

andrzejressel commented May 20, 2024

/attempt #8834

Algora profile Completed bounties Tech Active attempts Options
@andrzejressel 6 ZIO bounties
Kotlin, Scala,
Java & more
Cancel attempt

andrzejressel added a commit to andrzejressel/zio that referenced this issue May 20, 2024
@andrzejressel andrzejressel linked a pull request May 20, 2024 that will close this issue
Copy link

algora-pbc bot commented May 20, 2024

💡 @andrzejressel submitted a pull request that claims the bounty. You can visit your bounty board to reward.

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

Successfully merging a pull request may close this issue.

2 participants