Skip to content

Unused import results in unnecessary compilation from 1.10.0-M1 onwards (regression from 1.9.6) #1461

@lihaoyi

Description

@lihaoyi

project/build.properties

sbt.version=1.10.0-M1

build.sbt

scalaVersion := "2.13.15"

src/main/scala/build.scala

package build

object outer {
  def foo = { build.subfolder.inner.helperFoo }
}

src/main/scala/subfolder/package.scala

package build.subfolder

import build.{outer => unused}

object inner  {
  def helperFoo = { 1 }
}
  • In SBT/Zinc 1.10.0-M1 onwards, adding a newline to the end of either file results in 2 files being recompiled
  • In SBT/Zinc 1.9.6 and before, adding a newline to the end of either file results in only 1 file being recompiled
  • Removing the unused import build.{outer => unused} results in SBT/Zinc 1.10.0-M1 behaving correctly, only re-compiling 1 file when a newline is added to the end of either of them

It seems to me that Zinc 1.9.6 is correct and Zinc 1.10.0-M1 is wrong. In none of the cases above are any signatures or implementation code changing - I am just adding newlines to the end of the file, so even the line numbers didn't change - and thus we should not need to re-compile any downstream code. But even if we did change implementations (e.g. changing = { 1 } to = { 2 }) we should not need to recompile downstream code unless signatures change

Noticed in Mill com-lihaoyi/mill#3748

Bisected the Zinc commit log and the misbehavior seems to have been introduced in 8f40c41. That code seems incorrect to me:

  • We are blindly including mutually-dependent files meaning two files a <-> b that depend on one another will be forcibly recompiled even if nothing at all changed (the test case above)

  • We are only including directly mutually-dependent files. That means that although a 2-file cycle a -> b -> a is considered, a three file cycle a -> b -> c -> a is not considered. I have verified this behavior experimentally, and can't imagine any scenarios where this distinction would be something we actually want

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions