Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upWiP Remove the dependency from linker-interface on scalajs-ir. #4087
Conversation
And since sbt-scalajs only depends on linker-interface, this transively removes the dependency from sbt-scalajs on scalajs-ir as well.
@gzm0 This needs a serious cleanup and decomposition in meaningful commits. At this point I'd like your opinion on whether this is something worth doing at all. This allows the sbt plugin, along with any other build tool depending on the linker-interface, not to have any dependency on scalajs-ir. Currently, the fact that we receive scalajs-ir on the classpath because of linker-interface, but that we then load scalajs-linker reflectively, means that the version of scalajs-linker-interface must be exactly equal to that of scalajs-linker. While that is fine for sbt-scalajs, which is co-developed with scalajs-linker, it can be problematic for other build tools. Indeed, they are typically not built for one specific version of scalajs-linker, but instead load the right one depending on a setting. Nevertheless, they typically have to statically link against one version of scalajs-linker-interface. This means that it is very difficult for them not to encounter clashes. On principles as well, when depending on scalajs-linker-interface we were automatically get scalajs-ir, whose versioning policy is equal to There are some difficulties, the most notable one being the fact that |
Isn't this the case anyways because of |
Yes and no. It is practical to program against the binary interface of scalajs-linker-interface and link with many different versions of scalajs-linker. It's not practical to link scalajs-linker with a version of scalajs-ir that is not exactly equal. At least that's my impression. |
That's fair. So then to me, the major challenge is that the current linker interface assumes that IR file implementations are valid independently from the linker being used. (This is not an entirely hypothetical scenario, one could imagine using the cache of one version with another linker). If we are really strict, this is something we have committed to, in the public interface. (I did, at some point, toy with path-dependent types for these things, but rejected it, because the typing would be a nightmare in sbt). An idea of how to address this:
We'd have to leave the existing type definitions around, but we can make them less efficient (basically only have them work on byte blobs). The downside is the funky API, where you cannot create a single linker, you have to create a |
Have we? I don't think we have, because at the moment it's simply impossible to have two different scalajs-linker's at all (at least not without loading two different scalajs-linker-interface's as well, in which case the whole thing here is a non-issue). To make sure we are talking about the same thing, when you say "independently from the linker being used", are you talking about a) the instance of
it seems you meant a). But in the a) case, nothing changes with this PR. We're still able to pass (cached) IR files to different instances of |
In the context of loading different artifacts, yes. But different linker implementations is absolutely possible: val myFiles = PathIRFile(...)
val irCache = StandardImpl.irFileCache()
val stdLinker: Linker = StandardImpl.linker(config)
val myAwesomeLinker: Linker = new MyAwesomeLinker()
stdLinker.link(irCache.cached(myFiles))
myAwesomeLinker.link(irCache.cached(myFiles)) If |
Right. That's in theory possible, indeed. I don't think it's a valid use case, though. In my mind the abstract types in |
Hum, but your argument requires implementation details from the point of view of If casting the abstract types to something else is incorrect, the interface giving access to it should not allow it. Maybe to put it in other words: In the current API, there is nothing (theoretical or practical) that prevents two different concrete instances of If we want to remove the second restriction (and I do believe this is a desirable goal), we need to make sure the interface does not pretend to have more degrees of freedom than will actually work. So if there are two different concrete instances of |
sjrd commentedJun 17, 2020
And since sbt-scalajs only depends on linker-interface, this transitively removes the dependency from sbt-scalajs on scalajs-ir as well.