]> git.lizzy.rs Git - rust.git/blob - src/librustc/README.md
Auto merge of #31254 - tmiasko:macro-pretty-print-fix, r=sfackler
[rust.git] / src / librustc / README.md
1 An informal guide to reading and working on the rustc compiler.
2 ==================================================================
3
4 If you wish to expand on this document, or have a more experienced
5 Rust contributor add anything else to it, please get in touch:
6
7 * https://internals.rust-lang.org/
8 * https://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust
9
10 or file a bug:
11
12 https://github.com/rust-lang/rust/issues
13
14 Your concerns are probably the same as someone else's.
15
16 The crates of rustc
17 ===================
18
19 Rustc consists of a number of crates, including `libsyntax`,
20 `librustc`, `librustc_back`, `librustc_trans`, and `librustc_driver`
21 (the names and divisions are not set in stone and may change;
22 in general, a finer-grained division of crates is preferable):
23
24 - [`libsyntax`][libsyntax] contains those things concerned purely with syntax –
25   that is, the AST, parser, pretty-printer, lexer, macro expander, and
26   utilities for traversing ASTs – are in a separate crate called
27   "syntax", whose files are in `./../libsyntax`, where `.` is the
28   current directory (that is, the parent directory of front/, middle/,
29   back/, and so on).
30
31 - `librustc` (the current directory) contains the high-level analysis
32   passes, such as the type checker, borrow checker, and so forth.
33   It is the heart of the compiler.
34
35 - [`librustc_back`][back] contains some very low-level details that are
36   specific to different LLVM targets and so forth.
37
38 - [`librustc_trans`][trans] contains the code to convert from Rust IR into LLVM
39   IR, and then from LLVM IR into machine code, as well as the main
40   driver that orchestrates all the other passes and various other bits
41   of miscellany. In general it contains code that runs towards the
42   end of the compilation process.
43
44 - [`librustc_driver`][driver] invokes the compiler from
45   [`libsyntax`][libsyntax], then the analysis phases from `librustc`, and
46   finally the lowering and codegen passes from [`librustc_trans`][trans].
47
48 Roughly speaking the "order" of the three crates is as follows:
49
50               librustc_driver
51                       |
52     +-----------------+-------------------+
53     |                                     |
54     libsyntax -> librustc -> librustc_trans
55
56
57 The compiler process:
58 =====================
59
60 The Rust compiler is comprised of six main compilation phases.
61
62 1. Parsing input
63 2. Configuration & expanding (cfg rules & syntax extension expansion)
64 3. Running analysis passes
65 4. Translation to LLVM
66 5. LLVM passes
67 6. Linking
68
69 Phase one is responsible for parsing & lexing the input to the compiler. The
70 output of this phase is an abstract syntax tree (AST). The AST at this point
71 includes all macro uses & attributes. This means code which will be later
72 expanded and/or removed due to `cfg` attributes is still present in this
73 version of the AST. Parsing abstracts away details about individual files which
74 have been read into the AST.
75
76 Phase two handles configuration and macro expansion. You can think of this
77 phase as a function acting on the AST from the previous phase. The input for
78 this phase is the unexpanded AST from phase one, and the output is an expanded
79 version of the same AST. This phase will expand all macros & syntax
80 extensions and will evaluate all `cfg` attributes, potentially removing some
81 code. The resulting AST will not contain any macros or `macro_use` statements.
82
83 The code for these first two phases is in [`libsyntax`][libsyntax].
84
85 After this phase, the compiler allocates IDs to each node in the AST
86 (technically not every node, but most of them). If we are writing out
87 dependencies, that happens now.
88
89 The third phase is analysis. This is the most complex phase in the compiler,
90 and makes up much of the code. This phase included name resolution, type
91 checking, borrow checking, type & lifetime inference, trait selection, method
92 selection, linting and so on. Most of the error detection in the compiler comes
93 from this phase (with the exception of parse errors which arise during
94 parsing). The "output" of this phase is a set of side tables containing
95 semantic information about the source program. The analysis code is in
96 [`librustc`][rustc] and some other crates with the `librustc_` prefix.
97
98 The fourth phase is translation. This phase translates the AST (and the side
99 tables from the previous phase) into LLVM IR (intermediate representation).
100 This is achieved by calling into the LLVM libraries. The code for this is in
101 [`librustc_trans`][trans].
102
103 Phase five runs the LLVM backend. This runs LLVM's optimization passes on the
104 generated IR and generates machine code resulting in object files. This phase
105 is not really part of the Rust compiler, as LLVM carries out all the work.
106 The interface between LLVM and Rust is in [`librustc_llvm`][llvm].
107
108 The final phase, phase six, links the object files into an executable. This is
109 again outsourced to other tools and not performed by the Rust compiler
110 directly. The interface is in [`librustc_back`][back] (which also contains some
111 things used primarily during translation).
112
113 A module called the driver coordinates all these phases. It handles all the
114 highest level coordination of compilation from parsing command line arguments
115 all the way to invoking the linker to produce an executable.
116
117 Modules in the librustc crate
118 =============================
119
120 The librustc crate itself consists of the following submodules
121 (mostly, but not entirely, in their own directories):
122
123 - session: options and data that pertain to the compilation session as
124   a whole
125 - middle: middle-end: name resolution, typechecking, LLVM code
126   generation
127 - metadata: encoder and decoder for data required by separate
128   compilation
129 - plugin: infrastructure for compiler plugins
130 - lint: infrastructure for compiler warnings
131 - util: ubiquitous types and helper functions
132 - lib: bindings to LLVM
133
134 The entry-point for the compiler is main() in the [`librustc_driver`][driver]
135 crate.
136
137 The 3 central data structures:
138 ------------------------------
139
140 1. `./../libsyntax/ast.rs` defines the AST. The AST is treated as
141    immutable after parsing, but it depends on mutable context data
142    structures (mainly hash maps) to give it meaning.
143
144    - Many – though not all – nodes within this data structure are
145      wrapped in the type `spanned<T>`, meaning that the front-end has
146      marked the input coordinates of that node. The member `node` is
147      the data itself, the member `span` is the input location (file,
148      line, column; both low and high).
149
150    - Many other nodes within this data structure carry a
151      `def_id`. These nodes represent the 'target' of some name
152      reference elsewhere in the tree. When the AST is resolved, by
153      `middle/resolve.rs`, all names wind up acquiring a def that they
154      point to. So anything that can be pointed-to by a name winds
155      up with a `def_id`.
156
157 2. `middle/ty.rs` defines the datatype `sty`. This is the type that
158    represents types after they have been resolved and normalized by
159    the middle-end. The typeck phase converts every ast type to a
160    `ty::sty`, and the latter is used to drive later phases of
161    compilation. Most variants in the `ast::ty` tag have a
162    corresponding variant in the `ty::sty` tag.
163
164 3. `./../librustc_llvm/lib.rs` defines the exported types
165    `ValueRef`, `TypeRef`, `BasicBlockRef`, and several others.
166    Each of these is an opaque pointer to an LLVM type,
167    manipulated through the `lib::llvm` interface.
168
169 [libsyntax]: https://github.com/rust-lang/rust/tree/master/src/libsyntax/
170 [trans]: https://github.com/rust-lang/rust/tree/master/src/librustc_trans/
171 [llvm]: https://github.com/rust-lang/rust/tree/master/src/librustc_llvm/
172 [back]: https://github.com/rust-lang/rust/tree/master/src/librustc_back/
173 [rustc]: https://github.com/rust-lang/rust/tree/master/src/librustc/
174 [driver]: https://github.com/rust-lang/rust/tree/master/src/librustc_driver