RFC: Roadmap for 2017 by aturon · Pull Request #1774 · rust-lang/rfcs (original) (raw)
Looking over this, the roadmap overall looks great to me! I'm quite excited to
see increased productivity so front-and-center. I agree that all of the goals
proposed here would have a high impact on Rust, but I'd like to talk about one
of them in more detail. There's been discussion already about
C++ interoperability being on the roadmap, but I also want to about the "area of
support" of embedded vs making is a first class goal. (as a result I'm moving
this comment to the RFC itself rather than the previous thread).
I was personally surprised to see specifically C++ interop so prominently
mentioned in the roadmap. I like how it would transitively encompass better C
interoperability at the same time, and I'd definitely love to have it, but I'm
less convinced that it pulls its weight as an overarching goal. I share
@nagisa's
concern that
it seems like a stretch to see this completely finished and fleshed out by the
end of 2017 (in the sense of the level of completeness other goals likely will
be). We've certainly got plenty of efforts pushing on the C++ integeration right
now, and they've helped discover a lot of problems we're going to have to tackle
to get this right. I'm worried, though, that the scale of the problems we're
talking about here for a butter-smooth story is more time consuming than we
might be anticipating. This, in turn, could possibly limit resources
available to other goals and hinder their "full completion".
Some concrete worries I have about the difficulty of C++ interoperability are:
- Templates are hard. This is the bread-and-butter of many large C++ codebases,
so it's not a problem we can punt on. Effectively this seems like it will
require bundling a C++ compiler somehow to understand templates at all and
generate shims. - Generating shims are also hard. Projects like
rustcxx work through plugins but require
explicitly listing captured variables and signatures, and otherwise doing this
in a seamless fashion seems like it will require intrusive static analysis or
intrusive hooks into trans itself (e.g. what monomorphizations were
requested). - System C++ compilers are also hard. If we take the route of shelling out to a
C++ compiler (which seems most likely, I believe?), then we open the can of
worms related to finding the compiler, passing flags, ensuring it has all of
its own include paths set up correctly, codegen options set, etc, etc. - Bindgen seems like it's still very much an open problem. This has problems of
dealing with headers from the C++ standard library, C headers (e.g. the libc
crate), conditional compilation, C macros not having types, etc.
These are all definitely surmountable problems, of course! And there's lots of
possible solutions to each. My fear, though, is that a "full" solution is so
involved for each of these that it's a mammoth task to put forth. Now that sort
of work is appropriate for the goals of an entire year, however! When contrasted
with other possible routes I feel like we may be able to get more bang for our
buck.
To clarify, as well, my mental model for this comment is to work under the
assumption that this goal for 2017 would make using C++ from Rust becomes a
butter smooth experience. It'll basically be as easy if I'm writing C++. Even if
this happens, though, it'd still be difficult to consume Rust from C++. That is,
the other half of integration would still be difficult. This arguably the right
balance (for an existing C++ codebase there's more C++ code than Rust,
obviously), but I'd just want to highlight that really nailing down one
direction of interop also isn't the whole story.
Ok, so with all that in mind, I'd like to make a case for embedded development
as well. The RFC points out that embedded has the possibility of being quite a
large area of impact for Rust, and I would claim that the groundwork we lay for
embedded support can as far reaching as C++ include!
in its full glory.
Concretely, I'm thinking of two primary features falling under the embedded
umbrella I think we'd want to pursue to completion:
- Std-aware cargo. This enables
Cargo to seamlessly compile the standard library, libcore, etc, on stable
Rust. This is crucial for new platforms to easily build core/std with new
codegen options, patches applied (e.g. overriding), and bootstrapping without
nightlies. Furthermore this also unlocks compilation profiles for the standard
library itself: compiling with debuginfo, optimized with simd, true
panic=abort, etc. I personally believe the benefits we'll reap will benefit
almost everyone using Rust, not just embedded users (who it will primarily
impact, however). - Scenarios in the standard library.
This feature will be a boon to developing any kind of embedded crate. The idea
is to make the standard libary very easily accessible to new platforms while
also allowing you to quickly understand whether a crate works on a platform
or not. The embedded case can use this to forbid float APIs, we could build up
a failable collections API for "I'm in another application" embedded users, or
otherwise just enabling easy compilation to emscripten/web assembly.
I feel like features like this share many features with the C++ interop story.
All of what they enable is possible today, but unduly difficult. That is, C++
interop is possible but hard. Compiling libstd/libcore is possible but xargo but
hard. Porting code is possible with #[cfg]
but hard without strong guarantees.
Each of the features here are targeted at improving on what's already possible,
in other words making you more productive in each area.
To wrap up, I'd propose to reword C++ interop to replace it with the goal of:
Rust should easily support embedded development.
Here when I say "embedded" I mean simultaneously embedded architecture (e.g.
small ARM boards, weird platforms, etc) along with embedded libraries (e.g.
running inside of another application). The C++ features fit squarely within the
embedded library application side of things, with the features I mentioned above
fitting in embedded architectures.
I wonder, though, if this is perhaps too broad of a goal for 2017? It may be too
vauge to be able to meaningfully set goals for or evaluate how far we've come.
In terms of what it means, though, I prefer how it puts the embedded
architecture case on the same level of C++, which I personally feel like
pursuing either direction can have similar impact on Rust adoption as a whole.
So that's a bit of a long comment, but I'm curious what others think about this
as well!