I'm running into an unexpected (only for me?) ScalaC behavior.
The TL;DR is that the following is a recreation of an issue I saw while trying to migrate a codebase from maven to bazel. One of the main focuses of this migration is to try to minimize the dependencies each class needs for compilation so that builds will be triggered only when needed.
Unfortunately what I saw is that given ClassIndirectlyNeedingFoo
(uses)->ClassUsingFoo
(uses)->Supplier
the compilation of ClassIndirectlyNeedingFoo
breaks if Supplier
is not on the classpath.
The full details are here (https://github.com/ittaiz/scalac-troubleshooting).
If anyone knows why scalac behaves like this I'd really appreciate it.
Thanks!
BTW, Supplier is not in the source or bytecode of ClassIndirectlyNeedingFoo...
Ok so the short answer is that Why
isn't totally clear to anyone (see #4). What is clear is that it's known scalac sometimes needs more dependencies than one would think and it's also clear that sometimes when this happens it's a bug.
Furthermore from a discussion with Jason Zaugg on Gitter he seems to think my above issue is just apart of a family of bugs like the one linked above.
As Seth linked in the comments the ScalaCenter has accepted a proposal (original PR) for clarifying this area.
Most related to this issue are the four proposals there:
- Improvements to the user experience of stub errors, centered around the
Statement
: that they are an expected common case, rather than a
rare, unexpected, or fatal condition.
- Reduction of the number of cases that result in stub errors... ie, allowing more usecases that currently result in a stub error to
successfully compile, and thus allowing for fewer direct dependencies.
- A compiler flag to require
import
statements for all symbols used during compilation (including those not otherwise mentioned in the
source). For symmetry with -Ywarn-unused-imports
, this option might
potentially be called -Ywarn-undeclared-imports
. It would primarily
assist with making the transition from transitive to direct
dependencies, rather than helping to maintain a build that is already
using direct dependencies. (as suggested by
@posco and
@adriaanm)
- An expansion of the Scala Language Specification to list all cases in which a symbol from another compilation unit must be present on the
classpath, including: 1) subclassing, 2) return types of superclasses'
public methods, 3) direct reference, 4) etc.
It was agreed to go ahead with #3 though I don't know when the work will commence.
Eugeene Burmako, who co-authored the proposal, started prototyping the solution and I've made a small change on top of that.
For now this will have to do for my problem.