Skip to content

Inconsistent compilation results in mirror-deriving code #13001

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

Closed
Daenyth opened this issue Jul 2, 2021 · 2 comments · Fixed by #13206
Closed

Inconsistent compilation results in mirror-deriving code #13001

Daenyth opened this issue Jul 2, 2021 · 2 comments · Fixed by #13206

Comments

@Daenyth
Copy link

Daenyth commented Jul 2, 2021

Compiler version

3.0.0

Minimized code

Not minimized, but the github4s project at this specific commit:
https://github.com/47degrees/github4s/tree/bab2cd491d948807d364fa73687138d35f9feb6c

Output

With the file: https://github.com/47degrees/github4s/blob/gb-scala3/github4s/src/test/scala/github4s/unit/EncoderDecoderSpec.scala#L83

I've observed three different, seemingly-unrelated behaviors so far:

  • If I comment out all test invocations except the first one, compilation succeeds.
  • If I comment out all test invocations except the first two, compilation fails on both, with errors about not finding the Mirror:
Compiler output
[error] -- Error: /Users/gavin/Code/github4s/github4s/src/test/scala/github4s/unit/EncoderDecoderSpec.scala:83:19 
[error] 83 |  test[BlobContent]
[error]    |                   ^
[error]    |no implicit argument of type org.scalacheck.Arbitrary[github4s.domain.BlobContent] was found for an implicit parameter of method test in class EncoderDecoderSpec.
[error]    |I found:
[error]    |
[error]    |    github4s.ArbitraryDerivation.auto.deriveArb[A](
[error]    |      github4s.DerivedGen.derived[A](
[error]    |        /* missing */
[error]    |          summon[
[error]    |            deriving.Mirror{
[error]    |              Kind = shapeless3.deriving.K0.type; 
[error]    |                MirroredType <: github4s.domain.BlobContent
[error]    |              ; MirroredElemTypes <: Tuple
[error]    |            }
[error]    |          ]
[error]    |      )
[error]    |    )
[error]    |
[error]    |But no implicit values were found that match type deriving.Mirror{
[error]    |  Kind = shapeless3.deriving.K0.type; 
[error]    |    MirroredType <: github4s.domain.BlobContent
[error]    |  ; MirroredElemTypes <: Tuple
[error]    |}.
[error] -- Error: /Users/gavin/Code/github4s/github4s/src/test/scala/github4s/unit/EncoderDecoderSpec.scala:84:20 
[error] 84 |  test[BranchCommit]
[error]    |                    ^
[error]    |no implicit argument of type org.scalacheck.Arbitrary[github4s.domain.BranchCommit] was found for an implicit parameter of method test in class EncoderDecoderSpec.
[error]    |I found:
[error]    |
[error]    |    github4s.ArbitraryDerivation.auto.deriveArb[A](
[error]    |      github4s.DerivedGen.derived[A](
[error]    |        /* missing */
[error]    |          summon[
[error]    |            deriving.Mirror{
[error]    |              Kind = shapeless3.deriving.K0.type; 
[error]    |                MirroredType <: github4s.domain.BranchCommit
[error]    |              ; MirroredElemTypes <: Tuple
[error]    |            }
[error]    |          ]
[error]    |      )
[error]    |    )
[error]    |
[error]    |But no implicit values were found that match type deriving.Mirror{
[error]    |  Kind = shapeless3.deriving.K0.type; 
[error]    |    MirroredType <: github4s.domain.BranchCommit
[error]    |  ; MirroredElemTypes <: Tuple
[error]    |}.
[error] two errors found
[error] two errors found
[error] (github4s / Test / compileIncremental) Compilation failed

I've also tried with the first 10-20 or so uncommented, and it fails with those same Mirror errors on each.

  • If I uncomment all test invocations, and try compiling the file as-is, compilation prints no output, the compiler never terminates (I've left it for >20 minutes), and it ignores ctrl-c inputs

Expectation

If the code is correct, it should compile.
If it's incorrect, it should fail consistent, the compiler shouldn't run forever and be uncancelable.

Code that compiles without error should not start producing errors when an unrelated statement is added to the file.

@Daenyth
Copy link
Author

Daenyth commented Jul 14, 2021

I'm unlikely to have time to pursue this and minimize it

@griggt
Copy link
Contributor

griggt commented Jul 16, 2021

This seems to be a separate compilation issue related to opaque types. I reduced the example project to the following self-contained test case, which succeeds with joint compilation but fails separate compilation.

Main_1.scala

case class Foo(a: String)

trait Arbitrary[T]
trait Gen[+T]

object ArbitraryDerivation:
  given deriveArb[A](using gen: DerivedGen[A]): Arbitrary[A] = ???

opaque type DerivedGen[A] = Gen[A]
object DerivedGen extends DerivedGenInstances

sealed abstract class DerivedGenInstances:
  inline given derived[A](using gen: K0.Generic[A]): DerivedGen[A] =
    val dummy: DerivedGen[A] = ???
    gen.derive(dummy, dummy)

// from shapeless3-deriving
import scala.deriving.*
object K0 {
  type Kind[C, O] = C { type Kind = K0.type ; type MirroredType = O ; type MirroredElemTypes <: Tuple }
  type Generic[O] = Kind[Mirror, O]
  type ProductGeneric[O] = Kind[Mirror.Product, O]
  type CoproductGeneric[O] = Kind[Mirror.Sum, O]

  extension [F[_], T](gen: Generic[T])
    inline def derive(f: => (ProductGeneric[T] & gen.type) ?=> F[T], g: => (CoproductGeneric[T] & gen.type) ?=> F[T]): F[T] =
      inline gen match {
        case p: ProductGeneric[T]   => f(using p.asInstanceOf)
        case c: CoproductGeneric[T] => g(using c.asInstanceOf)
      }
}

Test_2.scala

class Test:
  import ArbitraryDerivation.given
  private def test[A: Arbitrary]: Unit = {}
  test[Foo]
$ dotc -version
Scala compiler version 3.0.3-RC1-bin-SNAPSHOT-git-7899462 -- Copyright 2002-2021, LAMP/EPFL

$ dotc Main_1.scala Test_2.scala 
... successful compilation ...

$ rm *.class *.tasty
$ dotc Main_1.scala && dotc Test_2.scala 
-- Error: Test_2.scala:4:11 ----------------------------------------------------------------------------------------------
4 |  test[Foo]
  |           ^
  |no implicit argument of type Arbitrary[Foo] was found for an implicit parameter of method test in class Test.
  |I found:
  |
  |    ArbitraryDerivation.deriveArb[Foo](
  |      DerivedGen.derived[A](
  |        /* missing */summon[deriving.Mirror{Kind = K0.type; MirroredType <: Foo; MirroredElemTypes <: Tuple}]
  |      )
  |    )
  |
  |But no implicit values were found that match type deriving.Mirror{Kind = K0.type; MirroredType <: Foo; MirroredElemTypes <: Tuple}.
1 error found

Separate compilation succeeds if the opqaue type is eliminated, e.g.

-opaque type DerivedGen[A] = Gen[A]
+trait DerivedGen[A]

odersky added a commit to dotty-staging/dotty that referenced this issue Jul 29, 2021
@griggt griggt removed the stat:needs minimization Needs a self contained minimization label Jul 30, 2021
odersky added a commit to dotty-staging/dotty that referenced this issue Jul 30, 2021
odersky added a commit to dotty-staging/dotty that referenced this issue Jul 30, 2021
tanishiking pushed a commit to tanishiking/scala3 that referenced this issue Aug 10, 2021
smarter pushed a commit to dotty-staging/dotty that referenced this issue Aug 11, 2021
@Kordyjan Kordyjan added this to the 3.1.0 milestone Aug 2, 2023
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.

4 participants