diff --git a/crates/libs/bindgen/src/rust/mod.rs b/crates/libs/bindgen/src/rust/mod.rs index 199ac642dc..4295920e39 100644 --- a/crates/libs/bindgen/src/rust/mod.rs +++ b/crates/libs/bindgen/src/rust/mod.rs @@ -29,6 +29,7 @@ pub fn from_reader(reader: &metadata::Reader, filter: &metadata::Filter, mut con writer.sys = writer.std || config.remove("sys").is_some(); writer.implement = config.remove("implement").is_some(); writer.minimal = config.remove("minimal").is_some(); + writer.no_inner_attributes = config.remove("no-inner-attributes").is_some(); if writer.package && writer.flatten { return Err(Error::new("cannot combine `package` and `flatten` configuration values")); diff --git a/crates/libs/bindgen/src/rust/try_format.rs b/crates/libs/bindgen/src/rust/try_format.rs index c871517b1a..0d7047105f 100644 --- a/crates/libs/bindgen/src/rust/try_format.rs +++ b/crates/libs/bindgen/src/rust/try_format.rs @@ -16,7 +16,7 @@ pub fn try_format(writer: &super::Writer, tokens: &str) -> String { }; // Packaging - e.g. windows/windows-sys crates - assumes the crate will allow whatever warnings it deems fit. - let allow = if writer.package { "" } else { "#![allow(non_snake_case, non_upper_case_globals, non_camel_case_types, dead_code, clippy::all)]\n" }; + let allow = if writer.package || writer.no_inner_attributes { "" } else { "#![allow(non_snake_case, non_upper_case_globals, non_camel_case_types, dead_code, clippy::all)]\n" }; let tokens = format!("{preamble}{allow}{tokens}"); let Ok(mut child) = std::process::Command::new("rustfmt").stdin(std::process::Stdio::piped()).stdout(std::process::Stdio::piped()).stderr(std::process::Stdio::null()).spawn() else { diff --git a/crates/libs/bindgen/src/rust/writer.rs b/crates/libs/bindgen/src/rust/writer.rs index e305b44213..332a8d63bf 100644 --- a/crates/libs/bindgen/src/rust/writer.rs +++ b/crates/libs/bindgen/src/rust/writer.rs @@ -13,16 +13,29 @@ pub struct Writer<'a> { // // Maybe this macro is the embedable version of the IDL format?! like a more intelligient // version of the existing interface macro... - pub std: bool, // tweaks for internal std library support - pub sys: bool, // writer sys-style bindings - pub flatten: bool, // strips out namespaces - implies !package - pub package: bool, // default is single file with no cfg - implies !flatten - pub minimal: bool, // strips out enumerators - in future possibly other helpers as well + pub std: bool, // tweaks for internal std library support + pub sys: bool, // writer sys-style bindings + pub flatten: bool, // strips out namespaces - implies !package + pub package: bool, // default is single file with no cfg - implies !flatten + pub minimal: bool, // strips out enumerators - in future possibly other helpers as well + pub no_inner_attributes: bool, // skips the inner attributes at the start of the file } impl<'a> Writer<'a> { pub fn new(reader: &'a Reader, filter: &'a metadata::Filter, output: &'a str) -> Self { - Self { reader, filter, output, namespace: "", implement: false, std: false, sys: false, flatten: false, package: false, minimal: false } + Self { + reader, + filter, + output, + namespace: "", + implement: false, + std: false, + sys: false, + flatten: false, + package: false, + minimal: false, + no_inner_attributes: false, + } } // diff --git a/crates/tests/standalone/build.rs b/crates/tests/standalone/build.rs index 82dbacf9f4..dd15b53220 100644 --- a/crates/tests/standalone/build.rs +++ b/crates/tests/standalone/build.rs @@ -135,6 +135,13 @@ fn main() { "Windows.Win32.Security.Cryptography.CMC_ADD_ATTRIBUTES", ], ); + + // Ensure that no-inner-attribute works, and the resulting + // file can be `include!` inside a mod{} block. + write_no_inner_attr( + "src/b_include_me.rs", + &["Windows.Win32.System.SystemInformation.GetVersion"], + ); } fn write_sys(output: &str, filter: &[&str]) { @@ -149,6 +156,14 @@ fn write_std(output: &str, filter: &[&str]) { riddle(output, filter, &["flatten", "std", "minimal"]); } +fn write_no_inner_attr(output: &str, filter: &[&str]) { + riddle( + output, + filter, + &["flatten", "no-inner-attributes", "minimal"], + ); +} + fn riddle(output: &str, filter: &[&str], config: &[&str]) { std::fs::remove_file(output).expect("Failed to delete output"); diff --git a/crates/tests/standalone/src/b_include_me.rs b/crates/tests/standalone/src/b_include_me.rs new file mode 100644 index 0000000000..4414d7af42 --- /dev/null +++ b/crates/tests/standalone/src/b_include_me.rs @@ -0,0 +1,7 @@ +// Bindings generated by `windows-bindgen` 0.52.0 + +#[inline] +pub unsafe fn GetVersion() -> u32 { + ::windows_targets::link!("kernel32.dll" "system" fn GetVersion() -> u32); + GetVersion() +} diff --git a/crates/tests/standalone/src/lib.rs b/crates/tests/standalone/src/lib.rs index 90c9d4e1a3..dbe58b79ab 100644 --- a/crates/tests/standalone/src/lib.rs +++ b/crates/tests/standalone/src/lib.rs @@ -26,6 +26,10 @@ mod b_test; mod b_unknown; mod b_uri; mod b_win_enumerator; +#[allow(non_snake_case)] +mod included { + include!("b_include_me.rs"); +} #[test] fn bstr() { @@ -166,3 +170,10 @@ fn calendar() -> windows_core::Result<()> { calendar.SetYear(year)?; Ok(()) } + +#[test] +fn from_included() { + unsafe { + included::GetVersion(); + } +}