When it comes to dynamic libraries and monomorphization, I'm curious to know/understand whether some sort of opt-in cross-product-of-crates dynamic libraries may work, partly because the orphan rules exist and the dependency graph must have no cycles.
For example: serde_json
defines a type Error
. If mycrate
uses thiserror
for its own error type and includes a variant Json(#[from] serde_json::Error)
then the impl From<serde_json::Error> for mycrate::Error
can be monomorpized and included in a library rust1.54+std+serde_json+mycrate
when compiling and packaging mycrate
for a distro.
This is where the orphan rules come into play: even with specialization, only mycrate
, serde_json
or std
would ever be allowed to provide that implementation, without even knowing whether mycrate
depends on serde_json
or the other way around. So given a set of enabled crates that a distro would like to provide this "early monomorphization" for, and a set of rules which functions to generate (e.g. "no generics on structs", "no cfg'd functions", "only these features for that crate"), it should be possible to find out whether any particular function should be pre-compiled both when packaging and when using mycrate
.
So a new cargo
subcommand that scans crates like rustdoc
/cargo doc
could invoke rustc
to precompile all qualifying functions from these enabled crates and a hook could be added to rustc to check whether a function that is supposed to be codegen'd matches the crate list & rules to skip codegen.
That way, functions like
serde_json::to_string(value: SmallVec<[i32; 4]>) -> Result<String, serde_json::Error>
(in std+smallvec+serde_json
) or
ring::hmac::sign(key: &ring::hmac::Key, data: &[u8]) -> ring::hmac::Tag
(in std+ring
) might someday be commonly available in distros.
When that is the case, it might become feasible to configure rustc
to use the intersection of the list of enabled crates and rules from packaging with those from other major distros by default.
The idea is for this to be opt-in and easily automated. A distro would have a single "sysroot-precompile-config" and rustc would write out a list of required libs while packaging a crate. If that list is empty, great! If it includes std
, std+serde
and a handful of others, it should be easy have a script add those to the dependency spec of the published app package.