@@ -68,20 +68,59 @@ something like this:
68
68
You can see the exact dependencies by reading the ` Cargo.toml ` for the various
69
69
crates, just like a normal Rust crate.
70
70
71
- You may ask why the compiler is broken into so many crates. There are two major reasons:
71
+ One final thing: [ ` src/llvm-project ` ] is a submodule for our fork of LLVM.
72
+
73
+ Most of this book is about the compiler, so we won't have any further
74
+ explanation of these crates here.
75
+
76
+ [ `src/llvm-project` ] : https://github.com/rust-lang/rust/tree/master/src
77
+
78
+ ### Big picture
72
79
73
- 1 . Organization. The compiler is a _ huge_ codebase; it would be an impossibly large crate.
80
+ The dependency structure is influenced strongly by two main factors:
81
+
82
+ 1 . Organization. The compiler is a _ huge_ codebase; it would be an impossibly
83
+ large crate. In part, the dependency structure reflects the code structure
84
+ of the compiler.
74
85
2 . Compile time. By breaking the compiler into multiple crates, we can take
75
86
better advantage of incremental/parallel compilation using cargo. In
76
87
particular, we try to have as few dependencies between crates as possible so
77
88
that we dont' have to rebuild as many crates if you change one.
78
89
79
- Most of this book is about the compiler, so we won't have any further
80
- explanation of these crates here.
81
-
82
- One final thing: [ ` src/llvm-project ` ] is a submodule for our fork of LLVM.
83
-
84
- [ `src/llvm-project` ] : https://github.com/rust-lang/rust/tree/master/src
90
+ At the very bottom of the dependency tree are a handful of crates that are used
91
+ by the whole compiler (e.g. [ ` rustc_span ` ] ). The very early parts of the
92
+ compilation process (e.g. parsing and the AST) depend on only these.
93
+
94
+ Pretty soon after the AST is constructed, the compiler's [ query system] [ query ]
95
+ gets set up. The query system is set up in a clever way using function
96
+ pointers. This allows us to break dependencies between crates, allowing more
97
+ parallel compilation.
98
+
99
+ However, since the query system is defined in [ ` rustc_middle ` ] , nearly all
100
+ subsequent parts of the compiler depend on this crate. It is a really large
101
+ crate, leading to long compile times. Some efforts have been made to move stuff
102
+ out of it with limited success. Another unfortunate sideffect is that sometimes
103
+ related functionality gets scattered across different crates. For example,
104
+ linting functionality is scattered across earlier parts of the crate,
105
+ [ ` rustc_lint ` ] , [ ` rustc_middle ` ] , and other places.
106
+
107
+ More generally, in an ideal world, it seems like there would be fewer, more
108
+ cohesive crates, with incremental and parallel compilation making sure compile
109
+ times stay reasonable. However, our incremental and parallel compilation haven't
110
+ gotten good enough for that yet, so breaking things into separate crates has
111
+ been our solution so far.
112
+
113
+ At the top of the dependency tree are the [ ` rustc_interface ` ] and
114
+ [ ` rustc_driver ` ] crates. [ ` rustc_interface ` ] is an unstable wrapper around the
115
+ query system that helps to drive the various stages of compilation. Other
116
+ consumers of the compiler may use this interface in different ways (e.g.
117
+ rustdoc or maybe eventually rust-analyzer). The [ ` rustc_driver ` ] crate first
118
+ parses command line arguments and then uses [ ` rustc_interface ` ] to drive the
119
+ compilation to completion.
120
+
121
+ [ query ] : ./query.md
122
+
123
+ [ orgch ] : ./overview.md
85
124
86
125
## rustdoc
87
126
0 commit comments