Skip to content

Commit 6a7c91b

Browse files
committed
Split out the stable part of smir into its own crate to prevent accidental usage of forever unstable things
1 parent 5ea306e commit 6a7c91b

File tree

16 files changed

+205
-92
lines changed

16 files changed

+205
-92
lines changed

Cargo.lock

+10-1
Original file line numberDiff line numberDiff line change
@@ -3194,6 +3194,7 @@ dependencies = [
31943194
"rustc_driver",
31953195
"rustc_driver_impl",
31963196
"rustc_smir",
3197+
"smir",
31973198
]
31983199

31993200
[[package]]
@@ -4358,7 +4359,7 @@ dependencies = [
43584359
"rustc_session",
43594360
"rustc_span",
43604361
"rustc_target",
4361-
"scoped-tls",
4362+
"smir",
43624363
"tracing",
43634364
]
43644365

@@ -4858,6 +4859,14 @@ version = "1.11.0"
48584859
source = "registry+https://github.com/rust-lang/crates.io-index"
48594860
checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
48604861

4862+
[[package]]
4863+
name = "smir"
4864+
version = "0.1.0-preview"
4865+
dependencies = [
4866+
"scoped-tls",
4867+
"tracing",
4868+
]
4869+
48614870
[[package]]
48624871
name = "snap"
48634872
version = "1.1.0"

compiler/rustc/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
1313
# Make sure rustc_smir ends up in the sysroot, because this
1414
# crate is intended to be used by stable MIR consumers, which are not in-tree
1515
rustc_smir = { path = "../rustc_smir" }
16+
smir = { path = "../smir" }
1617

1718
[dependencies.jemalloc-sys]
1819
version = "0.5.0"

compiler/rustc_smir/Cargo.toml

+8-18
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,14 @@ version = "0.0.0"
44
edition = "2021"
55

66
[dependencies]
7-
# Use optional dependencies for rustc_* in order to support building this crate separately.
8-
rustc_hir = { path = "../rustc_hir", optional = true }
9-
rustc_middle = { path = "../rustc_middle", optional = true }
10-
rustc_span = { path = "../rustc_span", optional = true }
11-
rustc_target = { path = "../rustc_target", optional = true }
12-
rustc_driver = { path = "../rustc_driver", optional = true }
13-
rustc_interface = { path = "../rustc_interface", optional = true}
14-
rustc_session = {path = "../rustc_session", optional = true}
7+
rustc_hir = { path = "../rustc_hir" }
8+
rustc_middle = { path = "../rustc_middle" }
9+
rustc_span = { path = "../rustc_span" }
10+
rustc_target = { path = "../rustc_target" }
11+
rustc_driver = { path = "../rustc_driver" }
12+
rustc_interface = { path = "../rustc_interface" }
13+
rustc_session = {path = "../rustc_session" }
1514
tracing = "0.1"
16-
scoped-tls = "1.0"
15+
smir = {path = "../smir" }
1716

1817
[features]
19-
default = [
20-
"rustc_hir",
21-
"rustc_middle",
22-
"rustc_span",
23-
"rustc_target",
24-
"rustc_driver",
25-
"rustc_interface",
26-
"rustc_session",
27-
]

compiler/rustc_smir/src/lib.rs

+2-15
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,13 @@
1010
html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
1111
test(attr(allow(unused_variables), deny(warnings)))
1212
)]
13-
#![cfg_attr(not(feature = "default"), feature(rustc_private))]
13+
#![feature(rustc_private)]
1414
#![feature(ptr_metadata)]
1515
#![feature(type_alias_impl_trait)] // Used to define opaque types.
1616
#![feature(intra_doc_pointers)]
1717

18-
// Declare extern rustc_* crates to enable building this crate separately from the compiler.
19-
#[cfg(not(feature = "default"))]
20-
extern crate rustc_hir;
21-
#[cfg(not(feature = "default"))]
22-
extern crate rustc_middle;
23-
#[cfg(not(feature = "default"))]
24-
extern crate rustc_span;
25-
#[cfg(not(feature = "default"))]
26-
extern crate rustc_target;
27-
2818
pub mod rustc_internal;
29-
pub mod stable_mir;
19+
pub use smir as stable_mir;
3020

3121
// Make this module private for now since external users should not call these directly.
3222
mod rustc_smir;
33-
34-
#[macro_use]
35-
extern crate scoped_tls;

compiler/rustc_smir/src/rustc_smir/mod.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,13 @@ use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx}
1111
use crate::stable_mir::ty::{
1212
FloatTy, GenericParamDef, IntTy, Movability, RigidTy, Span, TyKind, UintTy,
1313
};
14-
use crate::stable_mir::{self, opaque, CompilerError, Context};
14+
use crate::stable_mir::{self, opaque, Context};
1515
use hir::def::DefKind;
1616
use rustc_hir as hir;
1717
use rustc_middle::mir::interpret::{alloc_range, AllocId};
1818
use rustc_middle::mir::{self, ConstantKind};
1919
use rustc_middle::ty::{self, Ty, TyCtxt, Variance};
2020
use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
21-
use rustc_span::ErrorGuaranteed;
2221
use rustc_target::abi::FieldIdx;
2322
use tracing::debug;
2423

@@ -1523,12 +1522,6 @@ impl<'tcx> Stable<'tcx> for rustc_span::Span {
15231522
}
15241523
}
15251524

1526-
impl<T> From<ErrorGuaranteed> for CompilerError<T> {
1527-
fn from(_error: ErrorGuaranteed) -> Self {
1528-
CompilerError::CompilationFailed
1529-
}
1530-
}
1531-
15321525
impl<'tcx> Stable<'tcx> for DefKind {
15331526
type T = stable_mir::DefKind;
15341527

compiler/smir/Cargo.toml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "smir"
3+
version = "0.1.0-preview"
4+
edition = "2021"
5+
6+
[dependencies]
7+
tracing = "0.1"
8+
scoped-tls = "1.0"

compiler/smir/README.md

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
This crate is regularly synced with its mirror in the rustc repo at `compiler/rustc_smir`.
2+
3+
We use `git subtree` for this to preserve commits and allow the rustc repo to
4+
edit these crates without having to touch this repo. This keeps the crates compiling
5+
while allowing us to independently work on them here. The effort of keeping them in
6+
sync is pushed entirely onto us, without affecting rustc workflows negatively.
7+
This may change in the future, but changes to policy should only be done via a
8+
compiler team MCP.
9+
10+
## Instructions for working on this crate locally
11+
12+
Since the crate is the same in the rustc repo and here, the dependencies on rustc_* crates
13+
will only either work here or there, but never in both places at the same time. Thus we use
14+
optional dependencies on the rustc_* crates, requiring local development to use
15+
16+
```
17+
cargo build --no-default-features -Zavoid-dev-deps
18+
```
19+
20+
in order to compile successfully.
21+
22+
## Instructions for syncing
23+
24+
### Updating this repository
25+
26+
In the rustc repo, execute
27+
28+
```
29+
git subtree push --prefix=compiler/rustc_smir url_to_your_fork_of_project_stable_mir some_feature_branch
30+
```
31+
32+
and then open a PR of your `some_feature_branch` against https://github.com/rust-lang/project-stable-mir
33+
34+
### Updating the rustc library
35+
36+
First we need to bump our stack limit, as the rustc repo otherwise quickly hits that:
37+
38+
```
39+
ulimit -s 60000
40+
```
41+
42+
#### Maximum function recursion depth (1000) reached
43+
44+
Then we need to disable `dash` as the default shell for sh scripts, as otherwise we run into a
45+
hard limit of a recursion depth of 1000:
46+
47+
```
48+
sudo dpkg-reconfigure dash
49+
```
50+
51+
and then select `No` to disable dash.
52+
53+
54+
#### Patching your `git worktree`
55+
56+
The regular git worktree does not scale to repos of the size of the rustc repo.
57+
So download the `git-subtree.sh` from https://github.com/gitgitgadget/git/pull/493/files and run
58+
59+
```
60+
sudo cp --backup /path/to/patched/git-subtree.sh /usr/lib/git-core/git-subtree
61+
sudo chmod --reference=/usr/lib/git-core/git-subtree~ /usr/lib/git-core/git-subtree
62+
sudo chown --reference=/usr/lib/git-core/git-subtree~ /usr/lib/git-core/git-subtree
63+
```
64+
65+
#### Actually doing a sync
66+
67+
In the rustc repo, execute
68+
69+
```
70+
git subtree pull --prefix=compiler/rustc_smir https://github.com/rust-lang/project-stable-mir smir
71+
```
72+
73+
Note: only ever sync to rustc from the project-stable-mir's `smir` branch. Do not sync with your own forks.
74+
75+
Then open a PR against rustc just like a regular PR.
76+
77+
## Stable MIR Design
78+
79+
The stable-mir will follow a similar approach to proc-macro2. It’s
80+
implementation will eventually be broken down into two main crates:
81+
82+
- `stable_mir`: Public crate, to be published on crates.io, which will contain
83+
the stable data structure as well as proxy APIs to make calls to the
84+
compiler.
85+
- `rustc_smir`: The compiler crate that will translate from internal MIR to
86+
SMIR. This crate will also implement APIs that will be invoked by
87+
stable-mir to query the compiler for more information.
88+
89+
This will help tools to communicate with the rust compiler via stable APIs. Tools will depend on
90+
`stable_mir` crate, which will invoke the compiler using APIs defined in `rustc_smir`. I.e.:
91+
92+
```
93+
┌──────────────────────────────────┐ ┌──────────────────────────────────┐
94+
│ External Tool ┌──────────┐ │ │ ┌──────────┐ Rust Compiler │
95+
│ │ │ │ │ │ │ │
96+
│ │stable_mir| │ │ │rustc_smir│ │
97+
│ │ │ ├──────────►| │ │ │
98+
│ │ │ │◄──────────┤ │ │ │
99+
│ │ │ │ │ │ │ │
100+
│ │ │ │ │ │ │ │
101+
│ └──────────┘ │ │ └──────────┘ │
102+
└──────────────────────────────────┘ └──────────────────────────────────┘
103+
```
104+
105+
More details can be found here:
106+
https://hackmd.io/XhnYHKKuR6-LChhobvlT-g?view
107+
108+
For now, the code for these two crates are in separate modules of this crate.
109+
The modules have the same name for simplicity. We also have a third module,
110+
`rustc_internal` which will expose APIs and definitions that allow users to
111+
gather information from internal MIR constructs that haven't been exposed in
112+
the `stable_mir` module.

compiler/rustc_smir/src/stable_mir/fold.rs renamed to compiler/smir/src/fold.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
use std::ops::ControlFlow;
22

3-
use super::{
4-
ty::{
5-
Allocation, Binder, Const, ConstDef, ConstantKind, ExistentialPredicate, FnSig,
6-
GenericArgKind, GenericArgs, Promoted, RigidTy, TermKind, Ty, TyKind, UnevaluatedConst,
7-
},
8-
Opaque,
3+
use crate::Opaque;
4+
5+
use super::ty::{
6+
Allocation, Binder, Const, ConstDef, ConstantKind, ExistentialPredicate, FnSig, GenericArgKind,
7+
GenericArgs, Promoted, RigidTy, TermKind, Ty, TyKind, UnevaluatedConst,
98
};
109

1110
pub trait Folder: Sized {

compiler/rustc_smir/src/stable_mir/mod.rs renamed to compiler/smir/src/lib.rs

+27-15
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
1-
//! Module that implements the public interface to the Stable MIR.
1+
//! The WIP stable interface to rustc internals.
22
//!
3-
//! This module shall contain all type definitions and APIs that we expect third-party tools to invoke to
4-
//! interact with the compiler.
3+
//! For more information see <https://github.com/rust-lang/project-stable-mir>
54
//!
6-
//! The goal is to eventually move this module to its own crate which shall be published on
7-
//! [crates.io](https://crates.io).
5+
//! # Note
6+
//!
7+
//! This API is still completely unstable and subject to change.
8+
9+
#![doc(
10+
html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
11+
test(attr(allow(unused_variables), deny(warnings)))
12+
)]
813
//!
9-
//! ## Note:
14+
//! This crate shall contain all type definitions and APIs that we expect third-party tools to invoke to
15+
//! interact with the compiler.
1016
//!
11-
//! There shouldn't be any direct references to internal compiler constructs in this module.
12-
//! If you need an internal construct, consider using `rustc_internal` or `rustc_smir`.
17+
//! The goal is to eventually be published on
18+
//! [crates.io](https://crates.io).
1319
1420
use std::cell::Cell;
1521
use std::fmt;
@@ -19,6 +25,9 @@ use self::ty::{
1925
GenericPredicates, Generics, ImplDef, ImplTrait, Span, TraitDecl, TraitDef, Ty, TyKind,
2026
};
2127

28+
#[macro_use]
29+
extern crate scoped_tls;
30+
2231
pub mod fold;
2332
pub mod mir;
2433
pub mod ty;
@@ -32,11 +41,11 @@ pub type CrateNum = usize;
3241

3342
/// A unique identification number for each item accessible for the current compilation unit.
3443
#[derive(Clone, Copy, PartialEq, Eq)]
35-
pub struct DefId(pub(crate) usize);
44+
pub struct DefId(pub usize);
3645

3746
impl Debug for DefId {
3847
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39-
f.debug_struct("DefId:")
48+
f.debug_struct("DefId")
4049
.field("id", &self.0)
4150
.field("name", &with(|cx| cx.name_of_def_id(*self)))
4251
.finish()
@@ -45,7 +54,7 @@ impl Debug for DefId {
4554

4655
/// A unique identification number for each provenance
4756
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
48-
pub struct AllocId(pub(crate) usize);
57+
pub struct AllocId(pub usize);
4958

5059
/// A list of crate items.
5160
pub type CrateItems = Vec<CrateItem>;
@@ -73,7 +82,7 @@ pub enum CompilerError<T> {
7382
/// Holds information about a crate.
7483
#[derive(Clone, PartialEq, Eq, Debug)]
7584
pub struct Crate {
76-
pub(crate) id: CrateNum,
85+
pub id: CrateNum,
7786
pub name: Symbol,
7887
pub is_local: bool,
7988
}
@@ -84,7 +93,7 @@ pub type DefKind = Opaque;
8493
/// For now, it only stores the item DefId. Use functions inside `rustc_internal` module to
8594
/// use this item.
8695
#[derive(Clone, PartialEq, Eq, Debug)]
87-
pub struct CrateItem(pub(crate) DefId);
96+
pub struct CrateItem(pub DefId);
8897

8998
impl CrateItem {
9099
pub fn body(&self) -> mir::Body {
@@ -170,9 +179,12 @@ pub trait Context {
170179
/// Prints the name of given `DefId`
171180
fn name_of_def_id(&self, def_id: DefId) -> String;
172181

182+
/// Prints a human readable form of `Span`
173183
fn print_span(&self, span: Span) -> String;
174184

185+
/// Prints the kind of given `DefId`
175186
fn def_kind(&mut self, def_id: DefId) -> DefKind;
187+
176188
/// `Span` of an item
177189
fn span_of_an_item(&mut self, def_id: DefId) -> Span;
178190

@@ -200,7 +212,7 @@ pub fn run(mut context: impl Context, f: impl FnOnce()) {
200212

201213
/// Loads the current context and calls a function with it.
202214
/// Do not nest these, as that will ICE.
203-
pub(crate) fn with<R>(f: impl FnOnce(&mut dyn Context) -> R) -> R {
215+
pub fn with<R>(f: impl FnOnce(&mut dyn Context) -> R) -> R {
204216
assert!(TLV.is_set());
205217
TLV.with(|tlv| {
206218
let ptr = tlv.get();
@@ -225,6 +237,6 @@ impl std::fmt::Debug for Opaque {
225237
}
226238
}
227239

228-
pub(crate) fn opaque<T: Debug>(value: &T) -> Opaque {
240+
pub fn opaque<T: Debug>(value: &T) -> Opaque {
229241
Opaque(format!("{value:?}"))
230242
}
File renamed without changes.

0 commit comments

Comments
 (0)