I know this will not be easy. However, it would be a grate beneficial: it allows us to “reuse” code that have already compiled under nightly, and just compile your own code in stable.
A concrete example of this is the
fn_trait feature. This was not being stabilized for a long while and stopping us from writing our own function objects in stable. However, if someone created a crate with customized function objects, I didn’t see a reason why this would not be compatible with the stable crates.
Other “desugaring” features also should not affect the output compatibility, for example use
Try Trait in a crate should not make the output of the crate being incompatible to the stable. I think this is also the case for
NLL is in the MIR level, I also believe this should also work.
I am not sure about the “unsized rvalues” feature, but if it is just use
alloca as an FFI to do the job, I believe this should work as well. So technically there is a long list of hightly demanded features to be sit in this category.
For the difficulties that I could think of:
Some features may affect the intermediate formats and so will not be compatible with the stable. This can be handled by having a special flag on the feature gates, so if a specific feature was triggered, the crate will be marked as “incompatible” with the stable.
cargo.tomlfile will need to be extended to allow specifying a dependency to be compiled in nightly, in nightly and compatible with stable, or have to be in stable.
The user will need to have the nightly toolchain being installed to compile their stable crate, if it depends on any traits that need to be built under nightly. We can add a global flag on
cargo.tomlto indicate we need the nightly tool chain, and allow the dependencies to specify they have to be built under stable.
The user should be able to compile without installing the nightly toolchain. Instead, they can use
cargo.tomlto indicate they want to download a pre-compiled intermediate result for the stable version. Of cause, they can also compile with the nightly toolchain, but this will subject to breaking changes on nightly anyways.
We start with adding a flag to the crate output indicating the compatibility level. It can be a minimum version of the stable Rust version.
We review or adjust the current MIR design, to see if we can define a intermediate format that preserve all crate config options (most importantly, crate features) available, but not the targets, and functions remains generic for monomorphization.
We add a new feature gate to allow nightly
rustcto generate “compatible” output targeting a stable Rust version.
cargoto specify how it should compile each dependency, and check the compatibility flag on the output to verify. When publishing to
crates.iothe intermediate result should be uploaded with the source code. The user then should be able to use the uploaded result instead of compiling their own, as an option. Of cause they can choose to compile but they should know this may fail even when they have the nightly toolchain installed, because there would be breaking changes.
We are now ready to make the mixing of compiles happen: just let the stable toolchain to combine all compatible crate outputs to generate the result.
However we still need to review the features/libraries to make sure they are actually compatible with stable Rust, and if so, modify to make sure they use the flag to allow stable compatible output.
Some of the steps above are really complicated (5 for example), but I believe it is conservative enough to avoid many unexpected problems. Furthermore, once the first steps has been done the last step can be working in a per-request mode: we only review and check compatibility for features that the users requested.
If we follow the steps above, we will be able to use intermediate results from
crates.io, which will accelerate the first build of new crate imports.
Furthermore, being able to reuse intermediate results on stable versions technically freezes a specification of the format - because it is connected to a stable version. This will motivate third party tool developers, and encourage unofficial documentations.