Added a very rough rustc-driver chapter
This commit is contained in:
parent
73cc6098c9
commit
558f16cc8a
|
|
@ -9,6 +9,7 @@
|
||||||
- [Using `compiletest` + commands to control test execution](./compiletest.md)
|
- [Using `compiletest` + commands to control test execution](./compiletest.md)
|
||||||
- [Walkthrough: a typical contribution](./walkthrough.md)
|
- [Walkthrough: a typical contribution](./walkthrough.md)
|
||||||
- [High-level overview of the compiler source](./high-level-overview.md)
|
- [High-level overview of the compiler source](./high-level-overview.md)
|
||||||
|
- [The Rustc Driver](./rustc-driver.md)
|
||||||
- [Queries: demand-driven compilation](./query.md)
|
- [Queries: demand-driven compilation](./query.md)
|
||||||
- [Incremental compilation](./incremental-compilation.md)
|
- [Incremental compilation](./incremental-compilation.md)
|
||||||
- [The parser](./the-parser.md)
|
- [The parser](./the-parser.md)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
# The Rustc Driver
|
||||||
|
|
||||||
|
The [`rustc_driver`] is essentially `rustc`'s `main()` function. It acts as
|
||||||
|
the glue for running the various phases of the compiler in the correct order,
|
||||||
|
managing state such as the [`CodeMap`] \(maps AST nodes to source code),
|
||||||
|
[`Session`] \(general build context and error messaging) and the [`TyCtxt`]
|
||||||
|
\(the "typing context", allowing you to query the type system and other cool
|
||||||
|
stuff). The `rustc_driver` crate also provides external users with a method
|
||||||
|
for running code at particular times during the compilation process, allowing
|
||||||
|
third parties to effectively use `rustc`'s internals as a library for
|
||||||
|
analysing a crate.
|
||||||
|
|
||||||
|
For those using `rustc` as a library, the `run_compiler()` function is the main
|
||||||
|
entrypoint to the compiler. Its main parameters are a list of command-line
|
||||||
|
arguments and a reference to something which implements the `CompilerCalls`
|
||||||
|
trait. A `CompilerCalls` creates the overall `CompileController`, letting it
|
||||||
|
govern which compiler passes are run and attach callbacks to be fired at the end
|
||||||
|
of each phase.
|
||||||
|
|
||||||
|
From `rustc_driver`'s perspective, the main phases of the compiler are:
|
||||||
|
|
||||||
|
1. *Parse Input:* Initial crate parsing
|
||||||
|
2. *Configure and Expand:* Resolve `#[cfg]` attributes and expand macros
|
||||||
|
3. *Run Analysis Passes:* Run the resolution, typechecking, region checking
|
||||||
|
and other miscellaneous analysis passes on the crate
|
||||||
|
4. *Translate to LLVM:* Turn the analysed program into executable code
|
||||||
|
|
||||||
|
The `CompileController` then gives users the ability to inspect the ongoing
|
||||||
|
compilation process
|
||||||
|
|
||||||
|
- after parsing
|
||||||
|
- after AST expansion
|
||||||
|
- after HIR lowering
|
||||||
|
- after analysis, and
|
||||||
|
- when compilation is done
|
||||||
|
|
||||||
|
The `CompileState`'s various `state_after_*()` constructors can be inspected to
|
||||||
|
determine what bits of information are available to which callback.
|
||||||
|
|
||||||
|
## A Note On Lifetimes
|
||||||
|
|
||||||
|
The Rust compiler is a fairly large program containing lots of big data
|
||||||
|
structures (e.g. the AST, HIR, and the type system) and as such, arenas and
|
||||||
|
references are heavily relied upon to minimize unnecessary memory use. This
|
||||||
|
manifests itself in the way people can plug into the compiler, preferring a
|
||||||
|
"push"-style API (callbacks) instead of the more Rust-ic "pull" style (think
|
||||||
|
the `Iterator` trait).
|
||||||
|
|
||||||
|
For example the [`CompileState`], the state passed to callbacks after each
|
||||||
|
phase, is essentially just a box of optional references to pieces inside the
|
||||||
|
compiler. The lifetime bound on the `CompilerCalls` trait then helps to ensure
|
||||||
|
compiler internals don't "escape" the compiler (e.g. if you tried to keep a
|
||||||
|
reference to the AST after the compiler is finished), while still letting users
|
||||||
|
record *some* state for use after the `run_compiler()` function finishes.
|
||||||
|
|
||||||
|
Thread-local storage and interning are used a lot through the compiler to reduce
|
||||||
|
duplication while also preventing a lot of the ergonomic issues due to many
|
||||||
|
pervasive lifetimes. The `rustc::ty::tls` module is used to access these
|
||||||
|
thread-locals, although you should rarely need to touch it.
|
||||||
|
|
||||||
|
|
||||||
|
[`rustc_driver`]: https://github.com/rust-lang/rust/tree/master/src/librustc_driver
|
||||||
|
[`CompileState`]: https://github.com/rust-lang/rust/blob/master/src/librustc_driver/driver.rs
|
||||||
|
[`Session`]: https://github.com/rust-lang/rust/blob/master/src/librustc/session/mod.rs
|
||||||
|
[`TyCtxt`]: https://github.com/rust-lang/rust/blob/master/src/librustc/ty/context.rs
|
||||||
|
[`CodeMap`]: https://github.com/rust-lang/rust/blob/master/src/libsyntax/codemap.rs
|
||||||
Loading…
Reference in New Issue