Skip to content

Commit 9214a62

Browse files
authored
Add a debugging utility for Rust generate! (#828)
Lift the approach I added in bytecodealliance/wasmtime#7794
1 parent 61229ef commit 9214a62

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

crates/rust-macro/build.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
fn main() {
2+
println!("cargo:rerun-if-changed=build.rs");
3+
let out_dir = std::env::var("OUT_DIR").unwrap();
4+
println!("cargo:rustc-env=DEBUG_OUTPUT_DIR={out_dir}");
5+
}

crates/rust-macro/src/lib.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use proc_macro2::{Span, TokenStream};
22
use quote::ToTokens;
33
use std::collections::HashMap;
44
use std::path::{Path, PathBuf};
5+
use std::sync::atomic::{AtomicUsize, Ordering::Relaxed};
56
use syn::parse::{Error, Parse, ParseStream, Result};
67
use syn::punctuated::Punctuated;
78
use 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

Comments
 (0)