The introduction of
@experimental annotation seems to have some unforeseen consequences which might force us to rethink how it is supposed to be used, what restrictions it should imply and in what circumstances.
Currently both defining and using experimental features requires that you use a snapshot or nightly version of the compiler. Introducing new experimental definitions requires annotating them with
@experimental and you also need to annotate all subclasses of classes or traits defined as experimental. Usage of experimental features, without exposing them further in one’s API in general doesn’t require annotating but there are some corner cases, e.g. instantiating an experimental class works perfectly fine without any boilerplate but you cannot analogously instantiate an experimental trait (see Experimental trait cannot be instantiated anonymously · Issue #13091 · lampepfl/dotty · GitHub).
@experimental also causes problems while bootstrapping the compiler. As scala 3 standard library codebase contains features marked as experimental (including the
@experimental annotation itself) it cannot be built with a previous stable release or a published RC (unless it’s a nightly), which forces us to still use 3.0.0 as the reference compiler (which didn’t yet have all the restrictions related to
Also authors of libraries might want to add experimental features to their APIs without using experimental features defined in their dependencies and yet still be able to compile with a stable version of the compiler and even publish binaries containing experimental definitions but having a guarantee that nobody else will be able to depend on this part of the API unless just for experimenting.
It’s also not clear whether the sole fact of using a snapshot version of the compiler should be enough to enable usage of experimental features or this should be enabled explicitly e.g. with a compiler option or a language import.
Any suggestions about how to solve the problems described above would be welcome.