Rust Compilers and the Rust Spec

Disclaimer

The author of this post is a Lead and Developer of the LCCC project. This post is does not represent the views of the LCCC Project and is purely the opinion of the author.

The author of this post does work on the Rust Specification along side the Specification Team. This post is not intended to represent any consensus of that team, nor any demand to that team, merely as an opinion to consider.

Background of the Rust Spec

Work on the Rust Specification was started by a mandate put forth in RFC 3355, as a result of that RFC, a Formal Team was created, which started work on the Rust Specification in November of 2023.

While a complete developmental history of the Spec is not in scope for this, as of the date of writing (March 14th, 2024), the process has roughly been:

  • (Pre 2023-11) Background work, initial setup, Foundation Hires an Editor
  • (2023-11) T-spec setup work, meeting arrangements, first official meeting
  • (2023-12 - 2024-01) Tooling discussions, first sample chapters written and presented to Team/Stakeholders
  • (2024-01 - 2024-02) Review of sample chapters, refinement of tooling discussions, discussions (including with teams) on Specification Structure
  • (2024-03) First direct work started on Rust Specification Chapters

The Rust Specification does not define the language, but merely describes the language. From the specification RFC

The goal is not to change how the language evolves; the relevant teams (Language, Libs-API, …) remain in charge of the evolution of their respective parts of Rust, and will continue to use processes as they see fit (e.g. RFCs).

However, it is anticipated that the evolution process will eventually include work on the spec, ensuring that once the spec is in a "complete" state, it will remain in that state in sync with the rest of the language.

Background of Rust Compilers/Implementations

To my knowledge, including the Reference compiler rustc, there are 4 purported implementations of the Rust Programming Language, in various stages of development. The implementations that are not the reference compiler, known typically as "Alternative Implementations" or "Alternative Compilers" (the two are used in this post interchangibly, though Implementation conceptually includes the standard library, which may or may not be implemented separately), are developed for a variety of reasons. Some of the reasons for alternative implementation development include solving issues with rustc, such as bootstrapping or lack of target support, better integration with toolchains, tooling, and ecosystems other than llvm, or simply because the maintainers believe they can (I personally like to refer to this last reason as the "Mountain Climber Reason").

The first Rust compiler, being the Reference compiler, known commonly as the program rustc (and this blog will continue to refer to it as rustc) was released in the stable 1.0 version in May 2015, though work on it (and the Rust language) started as early as 2009. As the reference implementation, the evolution of rustc corresponds exactly to the evolution of the Rust Programming language, with a new stable version of each every 6 weeks - the most recent one as of the date of writing being Rust 1.77 (released on March 21st, 2024) with the next stable version being Rust 1.78 (stable on May 2nd, 2024)1.

The first alternative compiler of rust, mrustc started development even before the first stable version of rust (With a first commit to the mrustc repository on Novmeber 28th, 2014). mrustc, developed primarily by thepowersgang on github, is primarily intended to ease the bootstrapping process of rustc, by providing a compilation path to various versions of rustc through a non-rust language (in the case of mrustc, C++14). The exact development history of mrustc could not be discovered by the author in the 15 minutes of research done on it, but currently it supports Rust 1.19, Rust 1.29, Rust 1.39, and Rust 1.54, with Rust 1.74 support being actively worked on. The support for Rust 1.54, the most recent fully supported version, was added in December of 2021.

The second alternative compiler of rust, gcc-rs also started sometime in 2014, shortly after the start of mrustc, though work on the most recent iteration of the frontend started arround 2020 after funding was provided for the work. The current status is a work in progress implementation targetting rust 1.49. As of March 3rd, 20242, gcc-rs has made substantial progress towards this support, recently adding a significant portion of the support for the format_args!() macro, and have implemented a basic println!() macro using that support. The println!() macro also leveraged already completed work, such as the work done for iterators.

The third alternative compiler is part of the lccc project (which I work on). Inclusion of rust in the project began in 2020 under the group Lightning Creations when the project that then contained lccc, lcnix, considered using rust code as part of its development. While development of the top-level lcnix project was discontinued, many of its subprojects continued development (and many were absorbed into lccc). The entire project has seen a few iterations (two main ones in C++, one now in Rust with an MSRV of 1.54), and the Rust frontend itself several iterations. The most recent iteration of the Rust frontend began in 2023, with a bottom up test-iterative approach. The most recent thing completed in the frontend is various complex branches (if/else statements and some basic matches).

Rust Specification and Rust Implementations

The Specification RFC states the following in relation to alternative implementations

It is not a primary goal of the specification to aid in the development of alternative Rust implementations, although authors of alternative compilers might still find the specification to be useful.

Based on discussions with project members3, this in particular refers to the fact the specification will not, as part of it's initial goal, be intended to validate implementations. However, in more recent discussions, it seems me that such implementations are not being considered as a consumer of the specification either.

It is reasonable that the initial scope of the specification would not render it complete enough to fully validate an implementation and be used for that purpose, however I think it is reasonable to conclude that it should eventually include that scope and thus implementors as consumers is something the spec now should consider.

The Future of Rust

Currently, Rust has 4 different compilers, in various phases of development. In addition to rustc, developed in tandom with the prescriptive work of the Rust project by the lang team, libs-api team, types team, and operational semantics team, the current set of implementations are intent on ensuring compatibility in various manners (including collaboration with the project). However, such work currently requires substantial amounts of research work, that should eventually be ameliorated by the Rust Specification.

It is not reasonable to expect that all implementations of Rust in the future will start or continue to collaborate to the extent that the existing ones do now, and they might expect a specification to inform them of the necessary elements for conformance. The specification should thus eventually be that specification implementations want. In order to ensure that it will be, the work on the specification now should prepare it for that future. It does not necessarily need to be perfect now, but it should be able to be made as good as it needs to be in the future.

Conclusion

Both lccc and gcc-rs have, as part of their stated goals, the promotion of the development of a Rust Specification. In my view, that goal is completed when any implementation can be written solely from the technical document signed off by the Rust Project as the official Rust Specification.

The 4 existing compilers for Rust will not be the last ones, particularily if gcc-rs and/or lccc succeeds in producing a production compiler. In my opinion, there will be another production-targetting Rust implementation either complete or in-progress within 5 years of this post, and in 10 years there will be a more substantial sphere of competition. The Rust project, including the specification, should be ready for it. The Specification today should consider implementors as a class of consumer of the spec, and should accept implementors as stakeholders in the spec, albeit future stakeholders. It would not be good if we write a spec today that rejects implementors, to a design that cannot be adapted to one useful for ensuring compliance and thus compatibility, in a future where use of a compiler other than rustc is as commonplace as use of rustc itself.

Copyright (C) 2024 Connor Horman This blog is licensed under the terms of the CC-BY-SA 4.0 License. See Copyright Info for details.

CC-BY-SA