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

More strange behavior with derivation mirrors #7050

Open
anatoliykmetyuk opened this issue Aug 15, 2019 · 9 comments
Open

More strange behavior with derivation mirrors #7050

anatoliykmetyuk opened this issue Aug 15, 2019 · 9 comments
Labels
backlog No work planned on this by the core team for the time being. itype:bug

Comments

@anatoliykmetyuk
Copy link
Contributor

import scala.deriving._

case class Foo(x: Int, y: String)

def weird = {
  val m = the[Mirror.ProductOf[Foo]]
  type R = m.MirroredElemTypes
  val mRes = the[Mirror.ProductOf[(Int, String)]]
  given mt as Mirror.ProductOf[R] = mRes
}

Says:

-- [E045] Cyclic Error: ../pg/Main.scala:10:11 ---------------------------------
10 |  type R = m.MirroredElemTypes
   |           ^
   |           Recursive value m needs type

longer explanation available when compiling with `-explain`
one error found
[error] Nonzero exit code returned from runner: 1
[error] (dotty-compiler / Compile / runMain) Nonzero exit code returned from runner: 1
[error] Total time: 15 s, completed Aug 15, 2019 5:24:41 PM

To make it compile:

def weird = {
  val m = the[Mirror.ProductOf[Foo]]
  type R = m.MirroredElemTypes
  val mRes = the[Mirror.ProductOf[(Int, String)]]
  // given mt as Mirror.ProductOf[R] = mRes
}
@anatoliykmetyuk
Copy link
Contributor Author

Also:

def weird = {
  val m = the[Mirror.ProductOf[Foo]]
  // type R = m.MirroredElemTypes
  val mRes = the[Mirror.ProductOf[(Int, String)]]
  given mt as Mirror.ProductOf[m.MirroredElemTypes] = mRes
}

Says:

-- [E045] Cyclic Error: ../pg/Main.scala:30:31 ---------------------------------
30 |  given mt as Mirror.ProductOf[m.MirroredElemTypes] = mRes
   |                               ^
   |                               Recursive value m needs type

longer explanation available when compiling with `-explain`
one error found

@milessabin
Copy link
Contributor

I agree the error message is a bit confusing, but it's nothing to do with Mirror. Here's a standalone reproduction,

class Foo[A] {
  type T
}

given as Foo[Unit] {
  type T = Int
}

given as Foo[Int] {
  type T = Boolean
}

def foo = {
  val f = the[Foo[Unit]]
  type T = f.T
  val g = the[Foo[Int]]
  given as Foo[f.T] = g
}

Yields the same error,

-- [E045] Cyclic Error: tests/pos/mirror-rec.scala:17:15 -----------------------
17 |  given as Foo[f.T] = g
   |               ^
   |               Recursive value f needs type

longer explanation available when compiling with `-explain`
one error found

@bishabosha
Copy link
Member

bishabosha commented Aug 15, 2019

I don't know if this is useful but you can still recover functionality with a closure

import scala.deriving._

case class Foo(x: Int, y: String)

inline def locally[T](body: => T): T = body

def weird = {
  val m = the[Mirror.ProductOf[Foo]]
  type R = m.MirroredElemTypes
  val mRes = the[Mirror.ProductOf[(Int, String)]]
  locally {
    given mt as Mirror.ProductOf[R] = mRes
  }
}

@anatoliykmetyuk
Copy link
Contributor Author

Possibly related:

def (p: P) toTuple[P <: Product] given (m: scala.derivation.Mirror.ProductOf[P]): m.MirroredElemTypes =
  Tuple.fromArray(p.productIterator.toArray).asInstanceOf[m.MirroredElemTypes]

Gives:

[error] -- [E047] Cyclic Error: /Users/anatolii/Projects/dotty/dotty/library/src/dotty/DottyPredef.scala:41:45
[error] 41 |  def (p: P) toTuple[P <: Product] given (m: scala.derivation.Mirror.ProductOf[P]): m.MirroredElemTypes =
[error]    |                                             ^
[error]    |                             Cyclic reference involving implicit value m
[error] one error found

@anatoliykmetyuk
Copy link
Contributor Author

It does look like the above one is mirror-specific... The following works:

class Foo[A] {
  type T
}

def (p: P) toTuple[P <: Product] given (m: Foo[P]): m.T =
  ???

The following works as well:

class Foo {
  type T
}

type Bar[X] = Foo { type T = X; type Y <: Tuple }

def (p: P) toTuple[P <: Product] given (m: Bar[P]): m.Y =
  ???

However, the following fails:

def (p: P) toTuple[P <: Product] given (m: scala.derivation.Mirror.ProductOf[P]): m.MirroredElemTypes =
  ???

Error:

-- [E047] Cyclic Error: ../pg/Main.scala:1:43 ----------------------------------
1 |def (p: P) toTuple[P <: Product] given (m: scala.derivation.Mirror.ProductOf[P]): m.MirroredElemTypes =
  |                                           ^
  |                               Cyclic reference involving implicit value m

@milessabin do you think I am missing something here?

@anatoliykmetyuk
Copy link
Contributor Author

Further minimizes to:

def f[P](p: P) given (m: scala.derivation.Mirror.Of[P]): Any = ???
-- [E047] Cyclic Error: ../pg/Main.scala:1:25 ----------------------------------
1 |def f[P](p: P) given (m: scala.derivation.Mirror.Of[P]): Any = ???
  |                         ^
  |                         Cyclic reference involving implicit value m

longer explanation available when compiling with `-explain`
one error found

@anatoliykmetyuk
Copy link
Contributor Author

Ok, nvm:

def f[P](p: P) given (m: scala.deriving.Mirror.Of[P]): Any = ???

Typo: derivation -> deriving.

@milessabin
Copy link
Contributor

The confusing error messages are a problem.

There's really nothing special about a Mirror though. It's just a term with type members. All the things you're seeing can be reproduced without Mirror as I did above.

@anatoliykmetyuk
Copy link
Contributor Author

The reason I'm fast to blame mirrors is because their instances are synthetic. I can't treat them as ordinary implicits when I see fishy things like cyclic references. You're right though, these errors seem to be unrelated to mirrors.

@anatoliykmetyuk anatoliykmetyuk removed their assignment Aug 22, 2019
@odersky odersky added the backlog No work planned on this by the core team for the time being. label Apr 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backlog No work planned on this by the core team for the time being. itype:bug
Projects
None yet
Development

No branches or pull requests

4 participants