diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml index e2151c4c4b..d1e46bfe62 100644 --- a/.github/workflows/clippy.yml +++ b/.github/workflows/clippy.yml @@ -225,6 +225,8 @@ jobs: run: cargo clippy -p test_query_signature - name: Clippy test_readme run: cargo clippy -p test_readme + - name: Clippy test_reference_float + run: cargo clippy -p test_reference_float - name: Clippy test_registry run: cargo clippy -p test_registry - name: Clippy test_registry_default diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e55d23ab8b..a078f368e1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -251,12 +251,14 @@ jobs: run: cargo test -p test_query_signature --target ${{ matrix.target }} ${{ matrix.etc }} - name: Test test_readme run: cargo test -p test_readme --target ${{ matrix.target }} ${{ matrix.etc }} + - name: Test test_reference_float + run: cargo test -p test_reference_float --target ${{ matrix.target }} ${{ matrix.etc }} - name: Test test_registry run: cargo test -p test_registry --target ${{ matrix.target }} ${{ matrix.etc }} - - name: Test test_registry_default - run: cargo test -p test_registry_default --target ${{ matrix.target }} ${{ matrix.etc }} - name: Clean run: cargo clean + - name: Test test_registry_default + run: cargo test -p test_registry_default --target ${{ matrix.target }} ${{ matrix.etc }} - name: Test test_reserved run: cargo test -p test_reserved --target ${{ matrix.target }} ${{ matrix.etc }} - name: Test test_resources diff --git a/crates/libs/bindgen/src/metadata.rs b/crates/libs/bindgen/src/metadata.rs index 544eebc45e..b22d0d16a3 100644 --- a/crates/libs/bindgen/src/metadata.rs +++ b/crates/libs/bindgen/src/metadata.rs @@ -551,7 +551,9 @@ pub fn type_has_float(ty: &Type) -> bool { match ty { Type::F32 | Type::F64 => true, Type::Win32Array(ty, _) => type_has_float(ty), - Type::TypeDef(def, _) => type_def_has_float(*def), + Type::TypeDef(def, generics) => { + type_def_has_float(*def) || generics.iter().any(type_has_float) + } _ => false, } } diff --git a/crates/tests/winrt/reference_float/Cargo.toml b/crates/tests/winrt/reference_float/Cargo.toml new file mode 100644 index 0000000000..3f8d568b27 --- /dev/null +++ b/crates/tests/winrt/reference_float/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "test_reference_float" +version = "0.0.0" +edition = "2021" +publish = false + +[lib] +crate-type = ["cdylib"] +doc = false +doctest = false + +[build-dependencies.windows-bindgen] +workspace = true + +[dependencies.windows-core] +workspace = true + +[dependencies.windows] +workspace = true +features = [ + "implement", + "Foundation", +] diff --git a/crates/tests/winrt/reference_float/build.rs b/crates/tests/winrt/reference_float/build.rs new file mode 100644 index 0000000000..493a467691 --- /dev/null +++ b/crates/tests/winrt/reference_float/build.rs @@ -0,0 +1,33 @@ +fn main() { + let mut command = std::process::Command::new("midlrt.exe"); + command.args([ + "/winrt", + "/nomidl", + "/h", + "nul", + "/metadata_dir", + "../../../libs/bindgen/default", + "/reference", + "../../../libs/bindgen/default/Windows.winmd", + "/winmd", + "metadata.winmd", + "src/metadata.idl", + ]); + + if !command.status().unwrap().success() { + panic!("Failed to run midlrt"); + } + + windows_bindgen::bindgen([ + "--in", + "metadata.winmd", + "--out", + "src/bindings.rs", + "--filter", + "test_reference_float", + "--config", + "implement", + "no-bindgen-comment", + ]) + .unwrap(); +} diff --git a/crates/tests/winrt/reference_float/src/bindings.rs b/crates/tests/winrt/reference_float/src/bindings.rs new file mode 100644 index 0000000000..39ddc3745c --- /dev/null +++ b/crates/tests/winrt/reference_float/src/bindings.rs @@ -0,0 +1,23 @@ +#![allow( + non_snake_case, + non_upper_case_globals, + non_camel_case_types, + dead_code, + clippy::all +)] +#[repr(C)] +#[derive(Clone, Debug, PartialEq)] +pub struct RefWithFloat { + pub Value: Option>, +} +impl windows_core::TypeKind for RefWithFloat { + type TypeKind = windows_core::CloneType; +} +impl windows_core::RuntimeType for RefWithFloat { + const SIGNATURE :windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice ( b"struct(test_reference_float.RefWithFloat;pinterface({61c17706-2d65-11e0-9ae8-d48564015472};f4))" ) ; +} +impl Default for RefWithFloat { + fn default() -> Self { + unsafe { core::mem::zeroed() } + } +} diff --git a/crates/tests/winrt/reference_float/src/lib.rs b/crates/tests/winrt/reference_float/src/lib.rs new file mode 100644 index 0000000000..3ec53ddfa0 --- /dev/null +++ b/crates/tests/winrt/reference_float/src/lib.rs @@ -0,0 +1,14 @@ +#![cfg(test)] + +mod bindings; +use bindings::*; +use windows::{core::*, Foundation::*}; + +#[test] +fn test() -> Result<()> { + let mut container = RefWithFloat::default(); + container.Value = Some(PropertyValue::CreateSingle(1.23)?.cast()?); + assert_eq!(container.Value.unwrap().Value()?, 1.23); + + Ok(()) +} diff --git a/crates/tests/winrt/reference_float/src/metadata.idl b/crates/tests/winrt/reference_float/src/metadata.idl new file mode 100644 index 0000000000..f2e3ae1f8e --- /dev/null +++ b/crates/tests/winrt/reference_float/src/metadata.idl @@ -0,0 +1,10 @@ +// This tests that windows-bindgen avoids deriving `Eq` for types with floating point fields. +// https://github.com/microsoft/windows-rs/issues/3220 + +namespace test_reference_float +{ + struct RefWithFloat + { + Windows.Foundation.IReference Value; + }; +}