Skip to content

Commit 42ebcdc

Browse files
committed
Avoid having rustc_smir depend on rustc_interface or rustc_driver
1 parent b9832e7 commit 42ebcdc

File tree

5 files changed

+85
-71
lines changed

5 files changed

+85
-71
lines changed

Cargo.lock

-2
Original file line numberDiff line numberDiff line change
@@ -4482,9 +4482,7 @@ name = "rustc_smir"
44824482
version = "0.0.0"
44834483
dependencies = [
44844484
"rustc_data_structures",
4485-
"rustc_driver",
44864485
"rustc_hir",
4487-
"rustc_interface",
44884486
"rustc_middle",
44894487
"rustc_span",
44904488
"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-57
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,15 @@ use crate::rustc_internal;
77
use crate::rustc_smir::Tables;
88
use rustc_data_structures::fx;
99
use rustc_data_structures::fx::FxIndexMap;
10-
use rustc_driver::{Callbacks, Compilation, RunCompiler};
11-
use rustc_interface::{interface, Queries};
1210
use rustc_middle::mir::interpret::AllocId;
1311
use rustc_middle::ty;
1412
use rustc_middle::ty::TyCtxt;
1513
use rustc_span::def_id::{CrateNum, DefId};
1614
use rustc_span::Span;
1715
use stable_mir::ty::IndexedVal;
18-
use stable_mir::CompilerError;
1916
use std::fmt::Debug;
2017
use std::hash::Hash;
21-
use std::ops::{ControlFlow, Index};
18+
use std::ops::Index;
2219

2320
impl<'tcx> Index<stable_mir::DefId> for Tables<'tcx> {
2421
type Output = DefId;
@@ -141,63 +138,81 @@ pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
141138
);
142139
}
143140

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

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

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

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

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)