Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Incremental compilation and opaque types don't play nice together #13190

Closed
Katrix opened this issue Jul 28, 2021 · 3 comments · Fixed by #13206
Closed

Incremental compilation and opaque types don't play nice together #13190

Katrix opened this issue Jul 28, 2021 · 3 comments · Fixed by #13206

Comments

@Katrix
Copy link
Contributor

Katrix commented Jul 28, 2021

Compiler version

3.0.1

Minimized code

fileA.scala

object Opaque {
  opaque type FieldType[K, +V] <: V = V
}

fileB.scala

import Opaque.*

object Test {
  type FindField[R <: scala.Tuple, K] = R match {
    case FieldType[K, f] *: t => f
    case _ *: t => FindField[t, K]
  }

  val f: FieldType["A", Int] = ???
  val f1: Int = f
  //val f2: Int = f

  type R = FieldType["A", Int] *: FieldType["B", Double] *: FieldType["C", String] *: FieldType["D", Boolean] *: EmptyTuple
  summon[FindField[R, "B"] =:= Double]
}

Steps to reproduce

  1. Compile both files together in a project. Everything should compile fine.
  2. Uncomment val f2: Int = f
  3. Try to compile again (and not cleaning beforehand). It will error for f1, f2, and the summon
  4. Clean and compile. It works again

Output

[error] -- [E007] Type Mismatch Error: D:\DevProjects\Stable\shapeless\core\src\main\scala-3\fileB.scala:10:16
[error] 10 |  val f1: Int = f
[error]    |                ^
[error]    |              Found:    (Test.f : Opaque.FieldType[("A" : String), Int])
[error]    |              Required: Int
[error] -- [E007] Type Mismatch Error: D:\DevProjects\Stable\shapeless\core\src\main\scala-3\fileB.scala:11:16
[error] 11 |  val f2: Int = f
[error]    |                ^
[error]    |              Found:    (Test.f : Opaque.FieldType[("A" : String), Int])
[error]    |              Required: Int
[error] -- Error: D:\DevProjects\Stable\shapeless\core\src\main\scala-3\fileB.scala:14:38
[error] 14 |  summon[FindField[R, "B"] =:= Double]
[error]    |                                      ^
[error]    |Cannot prove that Test.FindField[Test.R, ("B" : String)] =:= Double.
[error]    |
[error]    |One of the following imports might make progress towards fixing the problem:
[error]    |
[error]    |  import shapeless.~?>.idKeyWitness
[error]    |  import shapeless.~?>.idValueWitness
[error]    |  import shapeless.~?>.witness
[error]    |
[error]    |
[error]    |
[error]    |Note: a match type could not be fully reduced:
[error]    |
[error]    |  trying to reduce  Test.FindField[Test.R, ("B" : String)]
[error]    |  failed since selector  Test.R
[error]    |  does not match  case Opaque.FieldType[("B" : String), f] *: t => f
[error]    |  and cannot be shown to be disjoint from it either.
[error]    |  Therefore, reduction cannot advance to the remaining case
[error]    |
[error]    |    case _ *: t => Test.FindField[t, ("B" : String)]

Expectation

It should compile in both cases, also when using incremental compilation.

@griggt
Copy link
Contributor

griggt commented Jul 28, 2021

The example code fails separate compilation, but succeeds with joint compilation:

$ dotc -version
Scala compiler version 3.0.3-RC1-bin-SNAPSHOT-git-c53cc91 -- Copyright 2002-2021, LAMP/EPFL

$ dotc i13190_a.scala i13190_b.scala 
   ... successful compilation ...

$ rm *.class *.tasty
$ dotc i13190_a.scala && dotc i13190_b.scala 
-- [E007] Type Mismatch Error: i13190_b.scala:10:16
-------------------------------------------------------------------------------------------------------
10 |  val f1: Int = f
   |                ^
   |                Found:    (Test.f : Opaque.FieldType[("A" : String), Int])
   |                Required: Int

longer explanation available when compiling with `-explain`
-- Error: i13190_b.scala:14:38 
-------------------------------------------------------------------------------------------------------
14 |  summon[FindField[R, "B"] =:= Double]
   |                                      ^
   |                                      Cannot prove that Test.FindField[Test.R, ("B" : String)] =:= Double.
   |
   |                                      Note: a match type could not be fully reduced:
   |
   |                                        trying to reduce  Test.FindField[Test.R, ("B" : String)]
   |                                        failed since selector  Test.R
   |                                        does not match  case Opaque.FieldType[("B" : String), f] *: t => f
   |                                        and cannot be shown to be disjoint from it either.
   |                                        Therefore, reduction cannot advance to the remaining case
   |
   |                                          case _ *: t => Test.FindField[t, ("B" : String)]
2 errors found

@griggt
Copy link
Contributor

griggt commented Jul 28, 2021

Some other issues with separate compilation involving opaque types and/or match types: #12944, #12945, #13001

@odersky
Copy link
Contributor

odersky commented Jul 30, 2021

@Katrix @griggt Thanks for the minimization! It turned out this could solve quite a few open cases. #12944 stays open. That one seems to be unrelated.

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
# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants