-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
StableMIR: Proof-of-concept implementation + test #108846
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
[toolchain] | ||
channel = "nightly-2022-06-01" | ||
channel = "nightly-2023-02-28" | ||
components = [ "rustfmt", "rustc-dev" ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
//! Module that implements the bridge between Stable MIR and internal compiler MIR. | ||
//! | ||
//! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs | ||
//! until stable MIR is complete. | ||
|
||
use crate::stable_mir; | ||
pub use rustc_span::def_id::{CrateNum, DefId}; | ||
|
||
pub fn item_def_id(item: &stable_mir::CrateItem) -> DefId { | ||
item.0 | ||
} | ||
|
||
pub fn crate_num(item: &stable_mir::Crate) -> CrateNum { | ||
item.id.into() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
//! Module that implements what will become the rustc side of Stable MIR. | ||
//! | ||
//! This module is responsible for building Stable MIR components from internal components. | ||
//! | ||
//! This module is not intended to be invoked directly by users. It will eventually | ||
//! become the public API of rustc that will be invoked by the `stable_mir` crate. | ||
//! | ||
//! For now, we are developing everything inside `rustc`, thus, we keep this module private. | ||
|
||
use crate::stable_mir::{self}; | ||
use rustc_middle::ty::{tls::with, TyCtxt}; | ||
use rustc_span::def_id::{CrateNum, LOCAL_CRATE}; | ||
use tracing::debug; | ||
|
||
/// Get information about the local crate. | ||
pub fn local_crate() -> stable_mir::Crate { | ||
with(|tcx| smir_crate(tcx, LOCAL_CRATE)) | ||
} | ||
|
||
/// Retrieve a list of all external crates. | ||
pub fn external_crates() -> Vec<stable_mir::Crate> { | ||
with(|tcx| tcx.crates(()).iter().map(|crate_num| smir_crate(tcx, *crate_num)).collect()) | ||
} | ||
|
||
/// Find a crate with the given name. | ||
pub fn find_crate(name: &str) -> Option<stable_mir::Crate> { | ||
with(|tcx| { | ||
[LOCAL_CRATE].iter().chain(tcx.crates(()).iter()).find_map(|crate_num| { | ||
let crate_name = tcx.crate_name(*crate_num).to_string(); | ||
(name == crate_name).then(|| smir_crate(tcx, *crate_num)) | ||
}) | ||
}) | ||
} | ||
|
||
/// Retrieve all items of the local crate that have a MIR associated with them. | ||
pub fn all_local_items() -> stable_mir::CrateItems { | ||
with(|tcx| { | ||
tcx.mir_keys(()).iter().map(|item| stable_mir::CrateItem(item.to_def_id())).collect() | ||
}) | ||
} | ||
|
||
/// Build a stable mir crate from a given crate number. | ||
fn smir_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> stable_mir::Crate { | ||
let crate_name = tcx.crate_name(crate_num).to_string(); | ||
let is_local = crate_num == LOCAL_CRATE; | ||
debug!(?crate_name, ?crate_num, "smir_crate"); | ||
stable_mir::Crate { id: crate_num.into(), name: crate_name, is_local } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
//! Module that implements the public interface to the Stable MIR. | ||
//! | ||
//! This module shall contain all type definitions and APIs that we expect 3P tools to invoke to | ||
//! interact with the compiler. | ||
//! | ||
//! The goal is to eventually move this module to its own crate which shall be published on | ||
//! [crates.io](https://crates.io). | ||
//! | ||
//! ## Note: | ||
//! | ||
//! There shouldn't be any direct references to internal compiler constructs in this module. | ||
//! If you need an internal construct, consider using `rustc_internal` or `rustc_smir`. | ||
|
||
use crate::rustc_internal; | ||
|
||
/// Use String for now but we should replace it. | ||
pub type Symbol = String; | ||
|
||
/// The number that identifies a crate. | ||
pub type CrateNum = usize; | ||
|
||
/// A unique identification number for each item accessible for the current compilation unit. | ||
pub type DefId = usize; | ||
|
||
/// A list of crate items. | ||
pub type CrateItems = Vec<CrateItem>; | ||
|
||
/// Holds information about a crate. | ||
#[derive(Clone, PartialEq, Eq, Debug)] | ||
pub struct Crate { | ||
pub(crate) id: CrateNum, | ||
pub name: Symbol, | ||
pub is_local: bool, | ||
} | ||
|
||
/// Holds information about an item in the crate. | ||
/// For now, it only stores the item DefId. Use functions inside `rustc_internal` module to | ||
/// use this item. | ||
#[derive(Clone, PartialEq, Eq, Debug)] | ||
pub struct CrateItem(pub(crate) rustc_internal::DefId); | ||
|
||
/// Access to the local crate. | ||
pub fn local_crate() -> Crate { | ||
crate::rustc_smir::local_crate() | ||
} | ||
|
||
/// Try to find a crate with the given name. | ||
pub fn find_crate(name: &str) -> Option<Crate> { | ||
crate::rustc_smir::find_crate(name) | ||
} | ||
|
||
/// Try to find a crate with the given name. | ||
pub fn external_crates() -> Vec<Crate> { | ||
crate::rustc_smir::external_crates() | ||
} | ||
|
||
/// Retrieve all items in the local crate that have a MIR associated with them. | ||
pub fn all_local_items() -> CrateItems { | ||
crate::rustc_smir::all_local_items() | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
// run-pass | ||
// Test that users are able to use stable mir APIs to retrieve information of the current crate | ||
|
||
// ignore-stage-1 | ||
// ignore-cross-compile | ||
// ignore-remote | ||
|
||
#![feature(rustc_private)] | ||
|
||
extern crate rustc_driver; | ||
extern crate rustc_hir; | ||
extern crate rustc_interface; | ||
extern crate rustc_middle; | ||
extern crate rustc_smir; | ||
|
||
use rustc_driver::{Callbacks, Compilation, RunCompiler}; | ||
use rustc_hir::def::DefKind; | ||
use rustc_interface::{interface, Queries}; | ||
use rustc_middle::ty::TyCtxt; | ||
use rustc_smir::{rustc_internal, stable_mir}; | ||
use std::io::Write; | ||
|
||
const CRATE_NAME: &str = "input"; | ||
|
||
/// This function uses the Stable MIR APIs to get information about the test crate. | ||
fn test_stable_mir(tcx: TyCtxt<'_>) { | ||
// Get the local crate using stable_mir API. | ||
let local = stable_mir::local_crate(); | ||
assert_eq!(&local.name, CRATE_NAME); | ||
|
||
// Find items in the local crate. | ||
let items = stable_mir::all_local_items(); | ||
assert!(has_item(tcx, &items, (DefKind::Fn, "foo_bar"))); | ||
assert!(has_item(tcx, &items, (DefKind::Fn, "foo::bar"))); | ||
|
||
// Find the `std` crate. | ||
assert!(stable_mir::find_crate("std").is_some()); | ||
} | ||
|
||
// Use internal API to find a function in a crate. | ||
fn has_item(tcx: TyCtxt, items: &stable_mir::CrateItems, item: (DefKind, &str)) -> bool { | ||
items.iter().any(|crate_item| { | ||
let def_id = rustc_internal::item_def_id(crate_item); | ||
tcx.def_kind(def_id) == item.0 && tcx.def_path_str(def_id) == item.1 | ||
}) | ||
} | ||
|
||
/// This test will generate and analyze a dummy crate using the stable mir. | ||
/// For that, it will first write the dummy crate into a file. | ||
/// It will invoke the compiler using a custom Callback implementation, which will | ||
/// invoke Stable MIR APIs after the compiler has finished its analysis. | ||
fn main() { | ||
let path = "input.rs"; | ||
generate_input(&path).unwrap(); | ||
let args = vec![ | ||
"rustc".to_string(), | ||
"--crate-type=lib".to_string(), | ||
"--crate-name".to_string(), | ||
CRATE_NAME.to_string(), | ||
path.to_string(), | ||
]; | ||
rustc_driver::catch_fatal_errors(|| { | ||
RunCompiler::new(&args, &mut SMirCalls {}).run().unwrap(); | ||
}) | ||
.unwrap(); | ||
} | ||
|
||
struct SMirCalls {} | ||
|
||
impl Callbacks for SMirCalls { | ||
/// Called after analysis. Return value instructs the compiler whether to | ||
/// continue the compilation afterwards (defaults to `Compilation::Continue`) | ||
fn after_analysis<'tcx>( | ||
&mut self, | ||
_compiler: &interface::Compiler, | ||
queries: &'tcx Queries<'tcx>, | ||
) -> Compilation { | ||
queries.global_ctxt().unwrap().enter(|tcx| { | ||
test_stable_mir(tcx); | ||
}); | ||
// No need to keep going. | ||
Compilation::Stop | ||
} | ||
} | ||
|
||
fn generate_input(path: &str) -> std::io::Result<()> { | ||
let mut file = std::fs::File::create(path)?; | ||
write!( | ||
file, | ||
r#" | ||
mod foo {{ | ||
pub fn bar(i: i32) -> i64 {{ | ||
i as i64 | ||
}} | ||
}} | ||
|
||
pub fn foo_bar(x: i32, y: i32) -> i64 {{ | ||
let x_64 = foo::bar(x); | ||
let y_64 = foo::bar(y); | ||
x_64.wrapping_add(y_64) | ||
}}"# | ||
)?; | ||
Ok(()) | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll have to think some more of how to do this crate split in the future. The
rustc_smir
crate will see a different version ofstable_mir
than users who will compilestable_mir
from crates.io.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Totally. I did not incorporate anything related to version yet.