One thing I want to add wrt. "Cross-crate inlining and monomorphization. I wanted crates to allow inlining inside but present stable entrypoints to the outside." [..] is that it was in general well desired AFIK by most developers but so far out of scope that you probably would need to had the resources rust has today _before_ the 1.0 release to get it done right. At lest with the state CS research had been at during that time. By now due to various reasons (e.g. swift) there is much more research in that direction already done hence a new language has it much easier.
The problem is that it's not that simple to make it work nicely you need to design you language around such constraints. Trying to do it the other way around is even harder.
For example rust in it's current design relies quite a bit on the combo of: generics monomorphisation + inlining + dead code elimination. But this reliance doesn't play well with an stable ABI. Similar features like generic associated types and similar do not make the story easier. Like an rust stable ABI likely would only support `dyn Trait` and no generics or "on the fly" provide a `dyn` variant for generic method where possible. But even that isn't really good enough for a lot of use cases in a lot of different ways. Additionally a ton of important rust things are not `dyn` compatible at all.
Even some of the "easy" to solve things aren't that easy for non-technical reasons. E.g. a lot (but not all) of `impl Into<T>`, `impl AsRef<T>`, `impl Borrow<T>` etc. cases are best handled for a stable ABI context by aplying the single function of the trait (`.into()`,`.as_ref()`, etc.) _before_ calling the function and only having an ABI stable version for that. The side of which traits qualify for this is easy (you annotated the traits) the "when not apply it even if it seems valid" part isn't that easy not for technical reasons but for communication/documentation/avoiding unexpected outcomes reasons.