@@ -2,6 +2,7 @@ use proc_macro2::{Span, TokenStream};
22use quote:: ToTokens ;
33use std:: collections:: HashMap ;
44use std:: path:: { Path , PathBuf } ;
5+ use std:: sync:: atomic:: { AtomicUsize , Ordering :: Relaxed } ;
56use syn:: parse:: { Error , Parse , ParseStream , Result } ;
67use syn:: punctuated:: Punctuated ;
78use syn:: { braced, token, Token } ;
@@ -154,7 +155,31 @@ impl Config {
154155 . generate ( & self . resolve , self . world , & mut files)
155156 . map_err ( |e| Error :: new ( Span :: call_site ( ) , e) ) ?;
156157 let ( _, src) = files. iter ( ) . next ( ) . unwrap ( ) ;
157- let src = std:: str:: from_utf8 ( src) . unwrap ( ) ;
158+ let mut src = std:: str:: from_utf8 ( src) . unwrap ( ) . to_string ( ) ;
159+
160+ // If a magical `WIT_BINDGEN_DEBUG` environment variable is set then
161+ // place a formatted version of the expanded code into a file. This file
162+ // will then show up in rustc error messages for any codegen issues and can
163+ // be inspected manually.
164+ if std:: env:: var ( "WIT_BINDGEN_DEBUG" ) . is_ok ( ) {
165+ static INVOCATION : AtomicUsize = AtomicUsize :: new ( 0 ) ;
166+ let root = Path :: new ( env ! ( "DEBUG_OUTPUT_DIR" ) ) ;
167+ let world_name = & self . resolve . worlds [ self . world ] . name ;
168+ let n = INVOCATION . fetch_add ( 1 , Relaxed ) ;
169+ let path = root. join ( format ! ( "{world_name}{n}.rs" ) ) ;
170+
171+ std:: fs:: write ( & path, & src) . unwrap ( ) ;
172+
173+ // optimistically format the code but don't require success
174+ drop (
175+ std:: process:: Command :: new ( "rustfmt" )
176+ . arg ( & path)
177+ . arg ( "--edition=2021" )
178+ . output ( ) ,
179+ ) ;
180+
181+ src = format ! ( "include!({path:?});" ) ;
182+ }
158183 let mut contents = src. parse :: < TokenStream > ( ) . unwrap ( ) ;
159184
160185 // Include a dummy `include_str!` for any files we read so rustc knows that
0 commit comments