Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 23 additions & 29 deletions book/src/initial.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
# Initial Integration

In order to use `stable_mir` in your crate, you will need to do the following:
For an example of how to use `rustc_public`, see the [`demo/`] directory of the project-stable-mir repo.
For a tutorial, read on!

1. Use a nightly toolchain that includes the `stable_mir` crate.
In order to use `rustc_public` in your crate, you will need to do the following:

1. Use a nightly toolchain that includes the `rustc_public` crate.
2. Install at least the following rustup components: "rustc-dev" and "llvm-tools"
3. Declare `stable_mir` as an external crate at the top of your crate:
3. Declare `rustc_public` as an external crate at the top of your crate:

```rust
extern crate stable_mir;
#![feature(rustc_private)]
extern crate rustc_public;
```

For 1 and 2, we highly recommend adding a "rust-toolchain.toml" file to your project.
We also recommend to pin down a specific nightly version, to ensure all users and tests are using the same compiler
version.
Therefore, the same `stable_mir` crate version. E.g.:
Therefore, the same `rustc_public` crate version. E.g.:

```toml
# Example of a rust-toolchain.toml
[toolchain]
# Update the date to change the toolchain version.
channel = "nightly-2024-06-17"
channel = "nightly-2025-10-27"
components = ["llvm-tools", "rustc-dev", "rust-src"]
```

Expand All @@ -29,28 +33,28 @@ There's currently no stable way to initialize the Rust compiler and StableMIR.
See [#0069](https://github.com/rust-lang/project-stable-mir/issues/69) for more details.

Instead, StableMIR includes two unstable workarounds to give you a quick start.
The `run` and `run_with_tcx` macros, both from present in the `rustc_smir` crate.
The `run` and `run_with_tcx` macros, both from present in the `rustc_public` crate.

In order to use the `run` macro, you first need to declare the following external crates:

```rust
#![feature(rustc_private)]
extern crate rustc_public;

extern crate rustc_driver;
extern crate rustc_interface;
#[macro_use]
extern crate rustc_smir;
// This one you should know already. =)
extern crate stable_mir;
extern crate rustc_middle;
```

Then start the driver using the `run!()` macro:

```rust
let result = run!(rustc_args, callback_fn);
let result = rustc_public::run!(rustc_args, callback_fn);
```

This macro takes two arguments:

1. A vector with the command arguments to the compiler.
1. A `&[String]` with the command line arguments to the compiler.
2. A callback function, which can either be a closure expression or a function ident.
- This callback function shouldn't take any argument, and it should return a `ControlFlow<B,C>`.

Expand All @@ -63,18 +67,6 @@ The second option is the `run_with_tcx!()` macro, which is very similar to the `
The main difference is that this macro passes a copy of the Rust compiler context (`TyCtxt`) to the callback,
which allows the user to also make calls to internal compiler APIs.

Note that this option also requires the declaration of the `rustc_middle` external crate, i.e., you should now have the
following declarations:

```rust
extern crate rustc_driver;
extern crate rustc_interface;
extern crate rustc_middle; // This one is new!
#[macro_use]
extern crate rustc_smir;
extern crate stable_mir;
```

## Scope of StableMIR objects

StableMIR objects should not be used outside the scope of the callback function.
Expand All @@ -86,19 +78,19 @@ is running:
```rust
fn print_items(rustc_args: Vec<String>) {
let _result = run!(rustc_args, || {
for item in stable_mir::all_local_items() {
for item in rustc_public::all_local_items() {
// Using items inside the callback!
println!(" - {}", item.name())
}
});
}
```

However, the following usage isn't valid, and `stable_mir` will panic when we invoke the `name()` function.
However, the following usage isn't valid, and `rustc_public` will panic when we invoke the `name()` function.

```rust
fn broken_print_items(rustc_args: Vec<String>) {
let result = run!(rustc_args, || { ControlFlow::Continue(stable_mir::all_local_items())});
let result = run!(rustc_args, || { ControlFlow::Continue(rustc_public::all_local_items())});
if let ControlFlow::Continue(items) = result {
for item in items {
// Using item outside the callback function is wrong!
Expand All @@ -116,4 +108,6 @@ TODO

## Analyzing monomorphic instances

TODO
TODO

[`demo/`](https://github.com/rust-lang/project-stable-mir/tree/main/demo)
Loading