Skip to content

Cyclic reference error when refering to an implicit parameter from another implicit parameter's type #18258

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

Open
Sporarum opened this issue Jul 20, 2023 · 6 comments

Comments

@Sporarum
Copy link
Contributor

Compiler version

3.3.0 / 3.3.1-RC1

Minimized code & Ouptut

class myAnnot(s: String) extends scala.annotation.Annotation

trait Showable[A]

def show[A : Showable](x: A) = x.toString


def f1(using Showable[Int])(otherParam: Int @myAnnot(show[Int](4))) = ???

def f2(using Showable[Int])(using otherParam: Int @myAnnot(show[Int](4))) = ??? // error: Cyclic reference involving implicit parameter otherParam

Expectation

Either both methods should compile, or neither of them should

As I don't see any cyclic reference with otherParam, I assume the correct fix is to make f2 succeed

This also has implications for the following:

def f3[A](x: A)(using shower: Showable[A], otherParam: Int @myAnnot(show[A](x))) = ??? // error: Cyclic reference involving implicit parameter otherParam

def f4[A : Showable](x: A)(using otherParam: Int @myAnnot(show[A](x))) = ??? // error: Cyclic reference involving implicit parameter otherParam

(f4 surprisingly desugars to f3: https://docs.scala-lang.org/scala3/reference/contextual/context-bounds.html#)

@Sporarum Sporarum added itype:bug area:annotations area:implicits related to implicits Spree Suitable for a future Spree labels Jul 20, 2023
@Sporarum
Copy link
Contributor Author

The error seems self-contained enough for a spree, and might offer an interesting tour of rare parts of the compiler

@Sporarum
Copy link
Contributor Author

Might be related to:
#17242
#17224

@mbovel
Copy link
Member

mbovel commented Jul 1, 2024

This issue was picked for the Scala Issue Spree of tomorrow, July 2nd. @mbovel and @jan-pieter will be working on it! If you have any insight into the issue or guidance on how to fix it, please leave it here.

@mbovel
Copy link
Member

mbovel commented Jul 2, 2024

Reproduced.

Let tests/pos/18258.scala be:

class myAnnot(s: String) extends scala.annotation.Annotation
trait Showable[A]
def f(using Showable[Int])(using otherParam: Unit @myAnnot(summon[Showable[Int]](4))) = ???
sbt:scala3> scalac -explain-cyclic tests/pos/18258.scala
[info] running (fork) dotty.tools.dotc.Main -d /Users/mbovel/dotty/compiler/../out/default-last-scalac-out.jar -classpath /Users/mbovel/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.14/scala-library-2.13.14.jar:/Users/mbovel/dotty/library/../out/bootstrap/scala3-library-bootstrapped/scala-3.5.1-RC1-bin-SNAPSHOT-nonbootstrapped/scala3-library_3-3.5.1-RC1-bin-SNAPSHOT.jar -explain-cyclic tests/pos/18258.scala
-- [E047] Cyclic Error: tests/pos/18258.scala:3:65 -----------------------------
3 |def f(using Showable[Int])(using otherParam: Unit @myAnnot(summon[Showable[Int]](4))) = ???
  |                                                                 ^
  |Cyclic reference involving implicit parameter otherParam
  |
  |The error occurred while trying to compute the signature of method f
  |  which required to compute the signature of parameter otherParam
  |  which required to searching for an implicit argument of type Showable[Int]
  |  which required to compute the signature of parameter otherParam
  |
  | Run with both -explain-cyclic and -Ydebug-cyclic to see full stack trace.
  |
  | longer explanation available when compiling with `-explain`

@mbovel
Copy link
Member

mbovel commented Jul 2, 2024

Further minimized thanks to @EugeneFlesselle:

class myAnnot(s: Int) extends scala.annotation.Annotation
def f(using otherParam: Unit @myAnnot(summon[Int])) = ???

So it seems otherParam is in the implicit scope when typechecking the argument of @myAnnot.

Arguably, it should not?

@Sporarum
Copy link
Contributor Author

Sporarum commented Jul 9, 2024

This can also be minimized like so:

class myAnnot(s: Int) extends scala.annotation.Annotation

given String @myAnnot(summon[Int]) = "" // error: Cyclic reference involving val given_String

In that case it seems even more dubious that it should see itself.

Both these cases are also surprising, as the type of the given/using is different from the one of the summon, so there is no recursion going on !

@mbovel mbovel removed the Spree Suitable for a future Spree label Jul 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants