@@ -28,7 +28,7 @@ pub mod pretty;
2828///
2929/// # Warning
3030///
31- /// This function is unstable, and it's behavior may change at any point.
31+ /// This function is unstable, and its behavior may change at any point.
3232/// E.g.: Items that were previously supported, may no longer be supported, or its translation may
3333/// change.
3434///
@@ -50,23 +50,12 @@ pub fn stable<'tcx, S: Stable<'tcx>>(item: S) -> S::T {
5050/// # Panics
5151///
5252/// This function will panic if StableMIR has not been properly initialized.
53- pub fn internal < ' tcx , S : RustcInternal < ' tcx > > ( item : S ) -> S :: T {
53+ pub fn internal < ' tcx , S : RustcInternal < ' tcx > > ( tcx : TyCtxt < ' tcx > , item : S ) -> S :: T {
54+ // The tcx argument ensures that the item won't outlive the type context.
55+ let _ = tcx;
5456 with_tables ( |tables| item. internal ( tables) )
5557}
5658
57- /// Retrieve the internal Rust compiler type context.
58- ///
59- /// # Warning
60- ///
61- /// This function is unstable, and it's behavior may change at any point.
62- ///
63- /// # Panics
64- ///
65- /// This function will panic if StableMIR has not been properly initialized.
66- pub fn tcx < ' tcx > ( ) -> TyCtxt < ' tcx > {
67- with_tables ( |tables| tables. tcx )
68- }
69-
7059impl < ' tcx > Index < stable_mir:: DefId > for Tables < ' tcx > {
7160 type Output = DefId ;
7261
@@ -227,7 +216,7 @@ where
227216
228217/// Instantiate and run the compiler with the provided arguments and callback.
229218///
230- /// The callback will be invoked after the compiler ran all its analysis , but before code generation.
219+ /// The callback will be invoked after the compiler ran all its analyses , but before code generation.
231220/// Note that this macro accepts two different formats for the callback:
232221/// 1. An ident that resolves to a function that accepts no argument and returns `ControlFlow<B, C>`
233222/// ```ignore(needs-extern-crate)
@@ -249,7 +238,7 @@ where
249238/// # assert_eq!(result, Err(CompilerError::Skipped))
250239/// # }
251240/// ```
252- /// 2. An expression that represents the body of a closure:
241+ /// 2. A closure expression :
253242/// ```ignore(needs-extern-crate)
254243/// # extern crate rustc_driver;
255244/// # extern crate rustc_interface;
@@ -267,26 +256,63 @@ where
267256/// }
268257/// # let args = vec!["--verbose".to_string()];
269258/// # let extra_args = vec![];
270- /// let result = run!(args, analyze_code(extra_args));
259+ /// let result = run!(args, || analyze_code(extra_args));
271260/// # assert_eq!(result, Err(CompilerError::Skipped))
272261/// # }
273262/// ```
274263#[ macro_export]
275264macro_rules! run {
276265 ( $args: expr, $callback_fn: ident) => {
277- run!( $args, $callback_fn( ) )
266+ run_driver!( $args, || $callback_fn( ) )
267+ } ;
268+ ( $args: expr, $callback: expr) => {
269+ run_driver!( $args, $callback)
278270 } ;
279- ( $args: expr, $callback: expr) => { {
271+ }
272+
273+ /// Instantiate and run the compiler with the provided arguments and callback.
274+ ///
275+ /// This is similar to `run` but it invokes the callback with the compiler's `TyCtxt`,
276+ /// which can be used to invoke internal APIs.
277+ #[ macro_export]
278+ macro_rules! run_with_tcx {
279+ ( $args: expr, $callback_fn: ident) => {
280+ run_driver!( $args, |tcx| $callback_fn( tcx) , with_tcx)
281+ } ;
282+ ( $args: expr, $callback: expr) => {
283+ run_driver!( $args, $callback, with_tcx)
284+ } ;
285+ }
286+
287+ /// Optionally include an ident. This is needed due to macro hygiene.
288+ #[ macro_export]
289+ #[ doc( hidden) ]
290+ macro_rules! optional {
291+ ( with_tcx $ident: ident) => {
292+ $ident
293+ } ;
294+ }
295+
296+ /// Prefer using [run] and [run_with_tcx] instead.
297+ ///
298+ /// This macro implements the instantiation of a StableMIR driver, and it will invoke
299+ /// the given callback after the compiler analyses.
300+ ///
301+ /// The third argument determines whether the callback requires `tcx` as an argument.
302+ #[ macro_export]
303+ #[ doc( hidden) ]
304+ macro_rules! run_driver {
305+ ( $args: expr, $callback: expr $( , $with_tcx: ident) ?) => { {
280306 use rustc_driver:: { Callbacks , Compilation , RunCompiler } ;
281307 use rustc_interface:: { interface, Queries } ;
282308 use stable_mir:: CompilerError ;
283309 use std:: ops:: ControlFlow ;
284310
285- pub struct StableMir <B = ( ) , C = ( ) , F = fn ( ) -> ControlFlow <B , C >>
311+ pub struct StableMir <B = ( ) , C = ( ) , F = fn ( $ ( optional! ( $with_tcx TyCtxt ) ) ? ) -> ControlFlow <B , C >>
286312 where
287313 B : Send ,
288314 C : Send ,
289- F : FnOnce ( ) -> ControlFlow <B , C > + Send ,
315+ F : FnOnce ( $ ( optional! ( $with_tcx TyCtxt ) ) ? ) -> ControlFlow <B , C > + Send ,
290316 {
291317 args: Vec <String >,
292318 callback: Option <F >,
@@ -297,7 +323,7 @@ macro_rules! run {
297323 where
298324 B : Send ,
299325 C : Send ,
300- F : FnOnce ( ) -> ControlFlow <B , C > + Send ,
326+ F : FnOnce ( $ ( optional! ( $with_tcx TyCtxt ) ) ? ) -> ControlFlow <B , C > + Send ,
301327 {
302328 /// Creates a new `StableMir` instance, with given test_function and arguments.
303329 pub fn new( args: Vec <String >, callback: F ) -> Self {
@@ -325,7 +351,7 @@ macro_rules! run {
325351 where
326352 B : Send ,
327353 C : Send ,
328- F : FnOnce ( ) -> ControlFlow <B , C > + Send ,
354+ F : FnOnce ( $ ( optional! ( $with_tcx TyCtxt ) ) ? ) -> ControlFlow <B , C > + Send ,
329355 {
330356 /// Called after analysis. Return value instructs the compiler whether to
331357 /// continue the compilation afterwards (defaults to `Compilation::Continue`)
@@ -337,7 +363,7 @@ macro_rules! run {
337363 queries. global_ctxt( ) . unwrap( ) . enter( |tcx| {
338364 if let Some ( callback) = self . callback. take( ) {
339365 rustc_internal:: run( tcx, || {
340- self . result = Some ( ( callback) ( ) ) ;
366+ self . result = Some ( callback( $ ( optional! ( $with_tcx tcx ) ) ? ) ) ;
341367 } )
342368 . unwrap( ) ;
343369 if self . result. as_ref( ) . is_some_and( |val| val. is_continue( ) ) {
@@ -352,7 +378,7 @@ macro_rules! run {
352378 }
353379 }
354380
355- StableMir :: new( $args, || $callback) . run( )
381+ StableMir :: new( $args, $callback) . run( )
356382 } } ;
357383}
358384
0 commit comments