Home Explore Blog CI



rustc

2nd chunk of `src/compiler-src.md`
3f28b535e97cd2312e8b6e269f3e7e87ca833c82ff94ea6c00000001000008cf
   [`rustc_data_structures`], [`rustc_span`], [`rustc_errors`], etc.


You can see the exact dependencies by running `cargo tree`,
just like you would for any other Rust package:

```console
cargo tree --package rustc_driver
```

One final thing: [`src/llvm-project`] is a submodule for our fork of LLVM.
During bootstrapping, LLVM is built and the [`compiler/rustc_llvm`] crate
contains Rust wrappers around LLVM (which is written in C++), so that the
compiler can interface with it.

Most of this book is about the compiler, so we won't have any further
explanation of these crates here.


### Big picture

The dependency structure of the compiler is influenced by two main factors:

1. Organization. The compiler is a _huge_ codebase; it would be an impossibly
   large crate. In part, the dependency structure reflects the code structure
   of the compiler.
2. Compile-time. By breaking the compiler into multiple crates, we can take
   better advantage of incremental/parallel compilation using cargo. In
   particular, we try to have as few dependencies between crates as possible so
   that we don't have to rebuild as many crates if you change one.

At the very bottom of the dependency tree are a handful of crates that are used
by the whole compiler (e.g. [`rustc_span`]). The very early parts of the
compilation process (e.g. [parsing and the Abstract Syntax Tree (`AST`)][parser]) 
depend on only these.

After the [`AST`][parser] is constructed and other early analysis is done, the
compiler's [query system][query] gets set up. The query system is set up in a
clever way using function pointers. This allows us to break dependencies
between crates, allowing more parallel compilation. The query system is defined
in [`rustc_middle`], so nearly all subsequent parts of the compiler depend on
this crate. It is a really large crate, leading to long compile times. Some
efforts have been made to move stuff out of it with varying success. Another
side-effect is that sometimes related functionality gets scattered across
different crates. For example, linting functionality is found across earlier
parts of the crate, [`rustc_lint`], [`rustc_middle`], and other places.

Ideally there would be fewer, more cohesive crates, with incremental and

Title: Compiler Dependency Structure: Organization and Compile Time
Summary
This section elaborates on the compiler's dependency structure, emphasizing organization and compile-time efficiency. The compiler is split into multiple crates for better management and to leverage Cargo's incremental/parallel compilation. The dependency tree's base includes crates used by the entire compiler (e.g., `rustc_span`), with early compilation stages depending on these. The query system, set up using function pointers to reduce dependencies, is defined in `rustc_middle`, making it a central crate. The section also highlights trade-offs, such as functionality being scattered across different crates, and expresses the desire for fewer, more cohesive crates to improve maintainability.