about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMichael Bryan <michaelfbryan@gmail.com>2018-03-07 22:18:05 +0800
committerWho? Me?! <mark-i-m@users.noreply.github.com>2018-03-12 17:41:01 -0500
commitd44bc240a0ef8a75f6e8218cbc931bf2c8fc4bf0 (patch)
tree87f267cc123bc17e191741ef30a9a5fb662c41cd /src
parentb1d34cc27de27624f7cb2dd0d1f9aa61164595e5 (diff)
downloadrust-d44bc240a0ef8a75f6e8218cbc931bf2c8fc4bf0.tar.gz
rust-d44bc240a0ef8a75f6e8218cbc931bf2c8fc4bf0.zip
Added a very rough rustc-driver chapter
Diffstat (limited to 'src')
-rw-r--r--src/doc/rustc-dev-guide/src/SUMMARY.md1
-rw-r--r--src/doc/rustc-dev-guide/src/rustc-driver.md66
2 files changed, 67 insertions, 0 deletions
diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md
index d4ee59abf13..841a9b49196 100644
--- a/src/doc/rustc-dev-guide/src/SUMMARY.md
+++ b/src/doc/rustc-dev-guide/src/SUMMARY.md
@@ -9,6 +9,7 @@
     - [Using `compiletest` + commands to control test execution](./compiletest.md)
 - [Walkthrough: a typical contribution](./walkthrough.md)
 - [High-level overview of the compiler source](./high-level-overview.md)
+- [The Rustc Driver](./rustc-driver.md)
 - [Queries: demand-driven compilation](./query.md)
     - [Incremental compilation](./incremental-compilation.md)
 - [The parser](./the-parser.md)
diff --git a/src/doc/rustc-dev-guide/src/rustc-driver.md b/src/doc/rustc-dev-guide/src/rustc-driver.md
new file mode 100644
index 00000000000..b21cc366227
--- /dev/null
+++ b/src/doc/rustc-dev-guide/src/rustc-driver.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
\ No newline at end of file