Skip to content

Commit 4a5fecb

Browse files
committed
Avoid having rustc_smir depend on rustc_interface or rustc_driver
1 parent 6bb4ad6 commit 4a5fecb

File tree

6 files changed

+89
-73
lines changed

6 files changed

+89
-73
lines changed

Cargo.lock

-2
Original file line numberDiff line numberDiff line change
@@ -4520,9 +4520,7 @@ name = "rustc_smir"
45204520
version = "0.0.0"
45214521
dependencies = [
45224522
"rustc_data_structures",
4523-
"rustc_driver",
45244523
"rustc_hir",
4525-
"rustc_interface",
45264524
"rustc_middle",
45274525
"rustc_span",
45284526
"rustc_target",

compiler/rustc_smir/Cargo.toml

-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ edition = "2021"
55

66
[dependencies]
77
rustc_data_structures = { path = "../rustc_data_structures" }
8-
rustc_driver = { path = "../rustc_driver" }
98
rustc_hir = { path = "../rustc_hir" }
10-
rustc_interface = { path = "../rustc_interface" }
119
rustc_middle = { path = "../rustc_middle" }
1210
rustc_span = { path = "../rustc_span" }
1311
rustc_target = { path = "../rustc_target" }

compiler/rustc_smir/src/rustc_internal/mod.rs

+72-58
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,18 @@
33
//! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs
44
//! until stable MIR is complete.
55
6-
use crate::rustc_internal;
76
use crate::rustc_smir::Tables;
87
use rustc_data_structures::fx;
98
use rustc_data_structures::fx::FxIndexMap;
10-
use rustc_driver::{Callbacks, Compilation, RunCompiler};
11-
use rustc_interface::{interface, Queries};
129
use rustc_middle::mir::interpret::AllocId;
1310
use rustc_middle::ty;
1411
use rustc_middle::ty::TyCtxt;
1512
use rustc_span::def_id::{CrateNum, DefId};
1613
use rustc_span::Span;
1714
use stable_mir::ty::IndexedVal;
18-
use stable_mir::CompilerError;
1915
use std::fmt::Debug;
2016
use std::hash::Hash;
21-
use std::ops::{ControlFlow, Index};
17+
use std::ops::Index;
2218

2319
mod internal;
2420

@@ -143,63 +139,81 @@ pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
143139
);
144140
}
145141

146-
pub struct StableMir<B = (), C = ()>
147-
where
148-
B: Send,
149-
C: Send,
150-
{
151-
args: Vec<String>,
152-
callback: fn(TyCtxt<'_>) -> ControlFlow<B, C>,
153-
result: Option<ControlFlow<B, C>>,
154-
}
142+
#[macro_export]
143+
macro_rules! run {
144+
($args:expr, $callback:expr) => {
145+
run!($args, tcx, $callback)
146+
};
147+
($args:expr, $tcx:ident, $callback:expr) => {{
148+
use rustc_driver::{Callbacks, Compilation, RunCompiler};
149+
use rustc_interface::{interface, Queries};
150+
use stable_mir::CompilerError;
151+
use std::ops::ControlFlow;
152+
153+
pub struct StableMir<B = (), C = ()>
154+
where
155+
B: Send,
156+
C: Send,
157+
{
158+
args: Vec<String>,
159+
callback: fn(TyCtxt<'_>) -> ControlFlow<B, C>,
160+
result: Option<ControlFlow<B, C>>,
161+
}
155162

156-
impl<B, C> StableMir<B, C>
157-
where
158-
B: Send,
159-
C: Send,
160-
{
161-
/// Creates a new `StableMir` instance, with given test_function and arguments.
162-
pub fn new(args: Vec<String>, callback: fn(TyCtxt<'_>) -> ControlFlow<B, C>) -> Self {
163-
StableMir { args, callback, result: None }
164-
}
165-
166-
/// Runs the compiler against given target and tests it with `test_function`
167-
pub fn run(&mut self) -> Result<C, CompilerError<B>> {
168-
let compiler_result =
169-
rustc_driver::catch_fatal_errors(|| RunCompiler::new(&self.args.clone(), self).run());
170-
match (compiler_result, self.result.take()) {
171-
(Ok(Ok(())), Some(ControlFlow::Continue(value))) => Ok(value),
172-
(Ok(Ok(())), Some(ControlFlow::Break(value))) => Err(CompilerError::Interrupted(value)),
173-
(Ok(Ok(_)), None) => Err(CompilerError::Skipped),
174-
(Ok(Err(_)), _) => Err(CompilerError::CompilationFailed),
175-
(Err(_), _) => Err(CompilerError::ICE),
163+
impl<B, C> StableMir<B, C>
164+
where
165+
B: Send,
166+
C: Send,
167+
{
168+
/// Creates a new `StableMir` instance, with given test_function and arguments.
169+
pub fn new(args: Vec<String>, callback: fn(TyCtxt<'_>) -> ControlFlow<B, C>) -> Self {
170+
StableMir { args, callback, result: None }
171+
}
172+
173+
/// Runs the compiler against given target and tests it with `test_function`
174+
pub fn run(&mut self) -> Result<C, CompilerError<B>> {
175+
let compiler_result = rustc_driver::catch_fatal_errors(|| {
176+
RunCompiler::new(&self.args.clone(), self).run()
177+
});
178+
match (compiler_result, self.result.take()) {
179+
(Ok(Ok(())), Some(ControlFlow::Continue(value))) => Ok(value),
180+
(Ok(Ok(())), Some(ControlFlow::Break(value))) => {
181+
Err(CompilerError::Interrupted(value))
182+
}
183+
(Ok(Ok(_)), None) => Err(CompilerError::Skipped),
184+
(Ok(Err(_)), _) => Err(CompilerError::CompilationFailed),
185+
(Err(_), _) => Err(CompilerError::ICE),
186+
}
187+
}
176188
}
177-
}
178-
}
179189

180-
impl<B, C> Callbacks for StableMir<B, C>
181-
where
182-
B: Send,
183-
C: Send,
184-
{
185-
/// Called after analysis. Return value instructs the compiler whether to
186-
/// continue the compilation afterwards (defaults to `Compilation::Continue`)
187-
fn after_analysis<'tcx>(
188-
&mut self,
189-
_compiler: &interface::Compiler,
190-
queries: &'tcx Queries<'tcx>,
191-
) -> Compilation {
192-
queries.global_ctxt().unwrap().enter(|tcx| {
193-
rustc_internal::run(tcx, || {
194-
self.result = Some((self.callback)(tcx));
195-
});
196-
if self.result.as_ref().is_some_and(|val| val.is_continue()) {
197-
Compilation::Continue
198-
} else {
199-
Compilation::Stop
190+
impl<B, C> Callbacks for StableMir<B, C>
191+
where
192+
B: Send,
193+
C: Send,
194+
{
195+
/// Called after analysis. Return value instructs the compiler whether to
196+
/// continue the compilation afterwards (defaults to `Compilation::Continue`)
197+
fn after_analysis<'tcx>(
198+
&mut self,
199+
_compiler: &interface::Compiler,
200+
queries: &'tcx Queries<'tcx>,
201+
) -> Compilation {
202+
queries.global_ctxt().unwrap().enter(|tcx| {
203+
rustc_internal::run(tcx, || {
204+
self.result = Some((self.callback)(tcx));
205+
});
206+
if self.result.as_ref().is_some_and(|val| val.is_continue()) {
207+
Compilation::Continue
208+
} else {
209+
Compilation::Stop
210+
}
211+
})
200212
}
201-
})
202-
}
213+
}
214+
215+
StableMir::new($args, |$tcx| $callback).run()
216+
}};
203217
}
204218

205219
/// Simmilar to rustc's `FxIndexMap`, `IndexMap` with extra

tests/ui-fulldeps/stable-mir/check_instance.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@
1111
#![feature(control_flow_enum)]
1212

1313
extern crate rustc_middle;
14+
#[macro_use]
1415
extern crate rustc_smir;
1516
extern crate stable_mir;
17+
extern crate rustc_driver;
18+
extern crate rustc_interface;
1619

1720
use rustc_middle::ty::TyCtxt;
1821
use mir::{mono::Instance, TerminatorKind::*};
@@ -82,7 +85,7 @@ fn main() {
8285
CRATE_NAME.to_string(),
8386
path.to_string(),
8487
];
85-
rustc_internal::StableMir::new(args, test_stable_mir).run().unwrap();
88+
run!(args, tcx, test_stable_mir(tcx)).unwrap();
8689
}
8790

8891
fn generate_input(path: &str) -> std::io::Result<()> {

tests/ui-fulldeps/stable-mir/compilation-result.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@
1010
#![feature(assert_matches)]
1111

1212
extern crate rustc_middle;
13+
#[macro_use]
1314
extern crate rustc_smir;
15+
extern crate rustc_driver;
16+
extern crate rustc_interface;
1417
extern crate stable_mir;
1518

1619
use rustc_middle::ty::TyCtxt;
1720
use rustc_smir::rustc_internal;
1821
use std::io::Write;
19-
use std::ops::ControlFlow;
2022

2123
/// This test will generate and analyze a dummy crate using the stable mir.
2224
/// For that, it will first write the dummy crate into a file.
@@ -33,28 +35,26 @@ fn main() {
3335
}
3436

3537
fn test_continue(args: Vec<String>) {
36-
let continue_fn = |_: TyCtxt| ControlFlow::Continue::<(), bool>(true);
37-
let result = rustc_internal::StableMir::new(args, continue_fn).run();
38+
let result = run!(args, ControlFlow::Continue::<(), bool>(true));
3839
assert_eq!(result, Ok(true));
3940
}
4041

4142
fn test_break(args: Vec<String>) {
42-
let continue_fn = |_: TyCtxt| ControlFlow::Break::<bool, i32>(false);
43-
let result = rustc_internal::StableMir::new(args, continue_fn).run();
43+
let result = run!(args, ControlFlow::Break::<bool, i32>(false));
4444
assert_eq!(result, Err(stable_mir::CompilerError::Interrupted(false)));
4545
}
4646

47+
#[allow(unreachable_code)]
4748
fn test_skipped(mut args: Vec<String>) {
4849
args.push("--version".to_string());
49-
let unreach_fn = |_: TyCtxt| -> ControlFlow<()> { unreachable!() };
50-
let result = rustc_internal::StableMir::new(args, unreach_fn).run();
50+
let result = run!(args, unreachable!() as ControlFlow<()>);
5151
assert_eq!(result, Err(stable_mir::CompilerError::Skipped));
5252
}
5353

54+
#[allow(unreachable_code)]
5455
fn test_failed(mut args: Vec<String>) {
5556
args.push("--cfg=broken".to_string());
56-
let unreach_fn = |_: TyCtxt| -> ControlFlow<()> { unreachable!() };
57-
let result = rustc_internal::StableMir::new(args, unreach_fn).run();
57+
let result = run!(args, unreachable!() as ControlFlow<()>);
5858
assert_eq!(result, Err(stable_mir::CompilerError::CompilationFailed));
5959
}
6060

tests/ui-fulldeps/stable-mir/crate-info.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212

1313
extern crate rustc_hir;
1414
extern crate rustc_middle;
15+
#[macro_use]
1516
extern crate rustc_smir;
17+
extern crate rustc_driver;
18+
extern crate rustc_interface;
1619
extern crate stable_mir;
1720

1821
use rustc_hir::def::DefKind;
@@ -185,7 +188,7 @@ fn main() {
185188
CRATE_NAME.to_string(),
186189
path.to_string(),
187190
];
188-
rustc_internal::StableMir::new(args, test_stable_mir).run().unwrap();
191+
run!(args, tcx, test_stable_mir(tcx)).unwrap();
189192
}
190193

191194
fn generate_input(path: &str) -> std::io::Result<()> {

0 commit comments

Comments
 (0)