-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make incremental compilation aware of synthesized mirrors
A product mirror needs to be resynthesized if any class parameter changes, and a sum mirror needs to be resynthesized if any child of the sealed type changes, but previously this did not reliably work because the dependency recording in ExtractDependencies was unaware of mirrors. Instead of making ExtractDependencies aware of mirrors, we solve this by directly recording the dependencies when the mirror is synthesized, this way we can be sure to always correctly invalidate users of mirrors, even if the synthesized mirror type is not present in the AST at phase ExtractDependencies. This is the first time that we record dependencies outside of the ExtractDependencies phase, in the future we should see if we can extend this mechanism to record more dependencies during typechecking to make incremental compilation more robust (e.g. by keeping track of symbols looked up by macros). Eventually, we might even want to completely get rid of the ExtractDependencies phase and record all dependencies on the fly if it turns out to be faster.
- Loading branch information
Showing
13 changed files
with
91 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
case class MyProduct(x: Int) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import scala.deriving.Mirror | ||
import scala.compiletime.erasedValue | ||
|
||
transparent inline def foo[T](using m: Mirror.Of[T]): Int = | ||
inline erasedValue[m.MirroredElemTypes] match | ||
case _: (Int *: EmptyTuple) => 1 | ||
case _: (Int *: String *: EmptyTuple) => 2 | ||
|
||
@main def Test = | ||
assert(foo[MyProduct] == 2) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
scalaVersion := sys.props("plugin.scalaVersion") |
1 change: 1 addition & 0 deletions
1
sbt-test/source-dependencies/mirror-product/changes/MyProduct.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
case class MyProduct(x: Int, y: String) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
> compile | ||
|
||
# change the case class constructor | ||
$ copy-file changes/MyProduct.scala MyProduct.scala | ||
|
||
# Both MyProduct.scala and Test.scala should be recompiled, otherwise the assertion will fail | ||
> run |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
sealed trait Sum | ||
case class Child1() extends Sum |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import scala.deriving.Mirror | ||
import scala.compiletime.erasedValue | ||
|
||
object Test: | ||
transparent inline def foo[T](using m: Mirror.Of[T]): Int = | ||
inline erasedValue[m.MirroredElemLabels] match | ||
case _: ("Child1" *: EmptyTuple) => 1 | ||
case _: ("Child1" *: "Child2" *: EmptyTuple) => 2 | ||
|
||
def main(args: Array[String]): Unit = | ||
assert(foo[Sum] == 2) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
scalaVersion := sys.props("plugin.scalaVersion") | ||
// Use more precise invalidation, otherwise the reference to `Sum` in | ||
// Test.scala is enough to invalidate it when a child is added. | ||
ThisBuild / incOptions ~= { _.withUseOptimizedSealed(true) } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
sealed trait Sum | ||
case class Child1() extends Sum | ||
case class Child2() extends Sum |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
> compile | ||
|
||
# Add a child | ||
$ copy-file changes/Sum.scala Sum.scala | ||
|
||
# Both Sum.scala and Test.scala should be recompiled, otherwise the assertion will fail | ||
> run |