Skip to content

Commit

Permalink
Fix under-compilation when the method type in a SAM changes
Browse files Browse the repository at this point in the history
A lambda that implements a SAM type desugars (either at compile-time or runtime
via invokedynamic) into a class that extends the SAM type, therefore we need to
register an inheritance relationship to get the proper invalidation logic.

Fixes sbt/zinc#830.
  • Loading branch information
smarter committed Feb 22, 2023
1 parent 9a9834e commit 7f0fe63
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 0 deletions.
9 changes: 9 additions & 0 deletions compiler/src/dotty/tools/dotc/sbt/ExtractDependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,13 @@ private class ExtractDependenciesCollector extends tpd.TreeTraverser { thisTreeT
}
}

private def addInheritanceDependencies(tree: Closure)(using Context): Unit =
// If the tpt is empty, this is a non-SAM lambda, so no need to register
// an inheritance relationship.
if !tree.tpt.isEmpty then
val from = resolveDependencySource
_dependencies += ClassDependency(from, tree.tpt.tpe.classSymbol, LocalDependencyByInheritance)

private def addInheritanceDependencies(tree: Template)(using Context): Unit =
if (tree.parents.nonEmpty) {
val depContext = depContextOf(tree.symbol.owner)
Expand Down Expand Up @@ -369,6 +376,8 @@ private class ExtractDependenciesCollector extends tpd.TreeTraverser { thisTreeT
case ref: RefTree =>
addMemberRefDependency(ref.symbol)
addTypeDependency(ref.tpe)
case t: Closure =>
addInheritanceDependencies(t)
case t: Template =>
addInheritanceDependencies(t)
case _ =>
Expand Down
3 changes: 3 additions & 0 deletions sbt-test/source-dependencies/sam/A.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
trait A {
def foo(): Int
}
2 changes: 2 additions & 0 deletions sbt-test/source-dependencies/sam/B.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class B:
val f: A = () => 1
1 change: 1 addition & 0 deletions sbt-test/source-dependencies/sam/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
scalaVersion := sys.props("plugin.scalaVersion")
3 changes: 3 additions & 0 deletions sbt-test/source-dependencies/sam/changes/A.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
trait A {
def foo(): String
}
7 changes: 7 additions & 0 deletions sbt-test/source-dependencies/sam/test
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
> compile

# change the SAM type
$ copy-file changes/A.scala A.scala

# Both A.scala and B.scala should be recompiled, producing a compile error
-> compile

0 comments on commit 7f0fe63

Please sign in to comment.