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

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
Collaborator

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
Collaborator

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/dotty 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.

6 participants