Skip to content
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

Rollup of 8 pull requests #108919

Merged
merged 19 commits into from
Mar 9, 2023
Merged
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
40185db
Delete old re-exports from rustc_smir
celinval Mar 4, 2023
af664be
rustdoc: include link on all.html location header
notriddle Mar 3, 2023
b66db7e
Create new rustc_smir struct to map future crates
celinval Mar 4, 2023
775bacd
Simplify `sort_by` calls
WaffleLapkin Mar 7, 2023
5eaeb71
Change item collection to be on demand
celinval Mar 7, 2023
a439c02
may not => cannot
compiler-errors Mar 7, 2023
0f4255e
Dedup copy field errors for identical types
compiler-errors Mar 8, 2023
8a99ffc
Suppress copy impl error when post-normalized type references errors
compiler-errors Mar 7, 2023
be60bcb
Rename `MapInPlace` as `FlatMapInPlace`.
nnethercote Mar 8, 2023
204ba32
fix: evaluate with wrong obligation stack
LYF1999 Mar 8, 2023
1d442af
move clippy tests back to their intended directory
pietroalbini Mar 8, 2023
6c91ce2
Rollup merge of #108686 - notriddle:notriddle/jank-all, r=jsha
matthiaskrgr Mar 8, 2023
9b6b7a3
Rollup merge of #108846 - celinval:smir-poc, r=oli-obk
matthiaskrgr Mar 8, 2023
1a9376d
Rollup merge of #108873 - WaffleLapkin:cmp, r=cjgillot
matthiaskrgr Mar 8, 2023
f6b8a9f
Rollup merge of #108883 - compiler-errors:post-norm-copy-err, r=BoxyUwU
matthiaskrgr Mar 8, 2023
031b528
Rollup merge of #108884 - compiler-errors:tweak-illegal-copy-impl-mes…
matthiaskrgr Mar 8, 2023
a95943b
Rollup merge of #108887 - nnethercote:rename-MapInPlace, r=lqd
matthiaskrgr Mar 8, 2023
33c3036
Rollup merge of #108901 - LYF1999:yf/108897, r=lcnr
matthiaskrgr Mar 8, 2023
7732ccc
Rollup merge of #108903 - rust-lang:pa-fix-clippy-tests, r=flip1995
matthiaskrgr Mar 8, 2023
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
Prev Previous commit
Next Next commit
Create new rustc_smir struct to map future crates
+ Add some information to the README.md
celinval committed Mar 7, 2023
commit b66db7e4e04ba039967b659473595a13409e0b18
10 changes: 2 additions & 8 deletions Cargo.lock
Original file line number Diff line number Diff line change
@@ -4654,15 +4654,9 @@ dependencies = [
name = "rustc_smir"
version = "0.0.0"
dependencies = [
"rustc_borrowck",
"rustc_driver",
"rustc_hir",
"rustc_interface",
"rustc_middle",
"rustc_mir_dataflow",
"rustc_mir_transform",
"rustc_serialize",
"rustc_trait_selection",
"rustc_span",
"tracing",
]

[[package]]
19 changes: 3 additions & 16 deletions compiler/rustc_smir/Cargo.toml
Original file line number Diff line number Diff line change
@@ -4,25 +4,12 @@ version = "0.0.0"
edition = "2021"

[dependencies]
rustc_borrowck = { path = "../rustc_borrowck", optional = true }
rustc_driver = { path = "../rustc_driver", optional = true }
rustc_hir = { path = "../rustc_hir", optional = true }
rustc_interface = { path = "../rustc_interface", optional = true }
rustc_middle = { path = "../rustc_middle", optional = true }
rustc_mir_dataflow = { path = "../rustc_mir_dataflow", optional = true }
rustc_mir_transform = { path = "../rustc_mir_transform", optional = true }
rustc_serialize = { path = "../rustc_serialize", optional = true }
rustc_trait_selection = { path = "../rustc_trait_selection", optional = true }
rustc_span = { path = "../rustc_span", optional = true }
tracing = "0.1"

[features]
default = [
"rustc_borrowck",
"rustc_driver",
"rustc_hir",
"rustc_interface",
"rustc_middle",
"rustc_mir_dataflow",
"rustc_mir_transform",
"rustc_serialize",
"rustc_trait_selection",
"rustc_span",
]
37 changes: 37 additions & 0 deletions compiler/rustc_smir/README.md
Original file line number Diff line number Diff line change
@@ -73,3 +73,40 @@ git subtree pull --prefix=compiler/rustc_smir https://github.com/rust-lang/proje
Note: only ever sync to rustc from the project-stable-mir's `smir` branch. Do not sync with your own forks.

Then open a PR against rustc just like a regular PR.

## Stable MIR Design

The stable-mir will follow a similar approach to proc-macro2. It’s
implementation will eventually be broken down into two main crates:

- `stable_mir`: Public crate, to be published on crates.io, which will contain
the stable data structure as well as proxy APIs to make calls to the
compiler.
- `rustc_smir`: The compiler crate that will translate from internal MIR to
SMIR. This crate will also implement APIs that will be invoked by
stable-mir to query the compiler for more information.

This will help tools to communicate with the rust compiler via stable APIs. Tools will depend on
`stable_mir` crate, which will invoke the compiler using APIs defined in `rustc_smir`. I.e.:

```
┌──────────────────────────────────┐ ┌──────────────────────────────────┐
│ External Tool ┌──────────┐ │ │ ┌──────────┐ Rust Compiler │
│ │ │ │ │ │ │ │
│ │stable_mir| │ │ │rustc_smir│ │
│ │ │ ├──────────►| │ │ │
│ │ │ │◄──────────┤ │ │ │
│ │ │ │ │ │ │ │
│ │ │ │ │ │ │ │
│ └──────────┘ │ │ └──────────┘ │
└──────────────────────────────────┘ └──────────────────────────────────┘
```

More details can be found here:
https://hackmd.io/XhnYHKKuR6-LChhobvlT-g?view

For now, the code for these two crates are in separate modules of this crate.
The modules have the same name for simplicity. We also have a third module,
`rustc_internal` which will expose APIs and definitions that allow users to
gather information from internal MIR constructs that haven't been exposed in
the `stable_mir` module.
2 changes: 1 addition & 1 deletion compiler/rustc_smir/rust-toolchain.toml
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" ]
8 changes: 6 additions & 2 deletions compiler/rustc_smir/src/lib.rs
Original file line number Diff line number Diff line change
@@ -11,5 +11,9 @@
test(attr(allow(unused_variables), deny(warnings)))
)]
#![cfg_attr(not(feature = "default"), feature(rustc_private))]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]

pub mod rustc_internal;
pub mod stable_mir;

// Make this module private for now since external users should not call these directly.
mod rustc_smir;
12 changes: 12 additions & 0 deletions compiler/rustc_smir/src/rustc_internal/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//! 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::CrateItem;

pub type DefId = rustc_span::def_id::DefId;

pub fn item_def_id(item: &CrateItem) -> DefId {
item.0
}
52 changes: 52 additions & 0 deletions compiler/rustc_smir/src/rustc_smir/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//! 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, DefId, CRATE_DEF_INDEX, 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))
}

/// 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))
})
})
}

/// 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;
let mod_id = DefId { index: CRATE_DEF_INDEX, krate: crate_num };
let items = if is_local {
tcx.hir_module_items(mod_id.expect_local())
.items()
.map(|item| {
let def_id = item.owner_id.def_id.to_def_id();
stable_mir::CrateItem(def_id)
})
.collect()
} else {
tcx.module_children(mod_id)
.iter()
.filter_map(|item| item.res.opt_def_id())
.map(stable_mir::CrateItem)
.collect::<Vec<_>>()
};
debug!(?crate_name, ?crate_num, "smir_crate");
stable_mir::Crate { id: crate_num.into(), name: crate_name, is_local, root_items: items }
}
52 changes: 52 additions & 0 deletions compiler/rustc_smir/src/stable_mir/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//! 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,
/// The items defined in the root of this crate.
pub root_items: CrateItems,
}

/// 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)
}
106 changes: 106 additions & 0 deletions tests/ui-fulldeps/stable-mir/crate-info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// 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.
assert!(has_root_item(tcx, &local, (DefKind::Fn, "foo_bar")));
assert!(has_root_item(tcx, &local, (DefKind::Mod, "foo")));
assert!(!has_root_item(tcx, &local, (DefKind::Fn, "foo::bar")));

// Check that we can find items in the `std` crate.
let std_crate = stable_mir::find_crate("std").unwrap();
assert!(has_root_item(tcx, &std_crate, (DefKind::Mod, "std::any")));
assert!(!has_root_item(tcx, &std_crate, (DefKind::Fn, "std::any::type_name")));
}

// Use internal API to find a function in a crate.
fn has_root_item(tcx: TyCtxt, krate: &stable_mir::Crate, item: (DefKind, &str)) -> bool {
krate.root_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(())
}