From f9ae8a97b0bb82bb5d1d6959438d6ea9d9f6e9ca Mon Sep 17 00:00:00 2001
From: Kenny Kerr <kenny@kennykerr.ca>
Date: Fri, 12 Jan 2024 14:01:05 -0600
Subject: [PATCH] into-param-type

---
 .../rust/extensions/mod/Win32/Foundation/BOOL.rs  |  2 +-
 .../extensions/mod/Win32/Foundation/BOOLEAN.rs    |  2 +-
 crates/libs/core/src/param.rs                     | 14 +++++++-------
 crates/libs/core/src/strings/hstring.rs           |  2 +-
 crates/libs/core/src/type.rs                      |  8 ++------
 .../windows/src/Windows/Win32/Foundation/mod.rs   |  4 ++--
 crates/tests/implement/tests/vector.rs            | 15 +++++++++++++++
 7 files changed, 29 insertions(+), 18 deletions(-)

diff --git a/crates/libs/bindgen/src/rust/extensions/mod/Win32/Foundation/BOOL.rs b/crates/libs/bindgen/src/rust/extensions/mod/Win32/Foundation/BOOL.rs
index 2499fa964d..1fd761fdf7 100644
--- a/crates/libs/bindgen/src/rust/extensions/mod/Win32/Foundation/BOOL.rs
+++ b/crates/libs/bindgen/src/rust/extensions/mod/Win32/Foundation/BOOL.rs
@@ -67,7 +67,7 @@ impl ::core::ops::Not for BOOL {
     }
 }
 impl ::windows_core::IntoParam<BOOL> for bool {
-    fn into_param(self) -> ::windows_core::Param<BOOL> {
+    unsafe fn into_param(self) -> ::windows_core::Param<BOOL> {
         ::windows_core::Param::Owned(self.into())
     }
 }
diff --git a/crates/libs/bindgen/src/rust/extensions/mod/Win32/Foundation/BOOLEAN.rs b/crates/libs/bindgen/src/rust/extensions/mod/Win32/Foundation/BOOLEAN.rs
index 33b32a8d62..b07562a15b 100644
--- a/crates/libs/bindgen/src/rust/extensions/mod/Win32/Foundation/BOOLEAN.rs
+++ b/crates/libs/bindgen/src/rust/extensions/mod/Win32/Foundation/BOOLEAN.rs
@@ -67,7 +67,7 @@ impl ::core::ops::Not for BOOLEAN {
     }
 }
 impl ::windows_core::IntoParam<BOOLEAN> for bool {
-    fn into_param(self) -> ::windows_core::Param<BOOLEAN> {
+    unsafe fn into_param(self) -> ::windows_core::Param<BOOLEAN> {
         ::windows_core::Param::Owned(self.into())
     }
 }
diff --git a/crates/libs/core/src/param.rs b/crates/libs/core/src/param.rs
index d90acbe38a..e617dea7c2 100644
--- a/crates/libs/core/src/param.rs
+++ b/crates/libs/core/src/param.rs
@@ -28,16 +28,16 @@ pub trait IntoParam<T: TypeKind, C = <T as TypeKind>::TypeKind>: Sized
 where
     T: Type<T>,
 {
-    fn into_param(self) -> Param<T>;
+    unsafe fn into_param(self) -> Param<T>;
 }
 
 impl<T> IntoParam<T> for Option<&T>
 where
     T: Type<T>,
 {
-    fn into_param(self) -> Param<T> {
+    unsafe fn into_param(self) -> Param<T> {
         Param::Borrowed(match self {
-            Some(item) => item.abi(),
+            Some(item) => std::mem::transmute_copy(item),
             None => unsafe { std::mem::zeroed() },
         })
     }
@@ -50,7 +50,7 @@ where
     U: Interface,
     U: CanInto<T>,
 {
-    fn into_param(self) -> Param<T> {
+    unsafe fn into_param(self) -> Param<T> {
         unsafe {
             if U::QUERY {
                 self.cast().map_or(Param::Borrowed(std::mem::zeroed()), |ok| Param::Owned(ok))
@@ -65,8 +65,8 @@ impl<T> IntoParam<T, ValueType> for &T
 where
     T: TypeKind<TypeKind = ValueType> + Clone,
 {
-    fn into_param(self) -> Param<T> {
-        Param::Borrowed(self.abi())
+    unsafe fn into_param(self) -> Param<T> {
+        Param::Borrowed(std::mem::transmute_copy(self))
     }
 }
 
@@ -76,7 +76,7 @@ where
     U: TypeKind<TypeKind = CopyType> + Clone,
     U: CanInto<T>,
 {
-    fn into_param(self) -> Param<T> {
+    unsafe fn into_param(self) -> Param<T> {
         Param::Owned(unsafe { std::mem::transmute_copy(&self) })
     }
 }
diff --git a/crates/libs/core/src/strings/hstring.rs b/crates/libs/core/src/strings/hstring.rs
index 5eac52fd33..3082189353 100644
--- a/crates/libs/core/src/strings/hstring.rs
+++ b/crates/libs/core/src/strings/hstring.rs
@@ -398,7 +398,7 @@ impl From<HSTRING> for std::ffi::OsString {
 }
 
 impl IntoParam<PCWSTR> for &HSTRING {
-    fn into_param(self) -> Param<PCWSTR> {
+    unsafe fn into_param(self) -> Param<PCWSTR> {
         Param::Owned(PCWSTR(self.as_ptr()))
     }
 }
diff --git a/crates/libs/core/src/type.rs b/crates/libs/core/src/type.rs
index c0d5aa5d61..3f4cd06ac5 100644
--- a/crates/libs/core/src/type.rs
+++ b/crates/libs/core/src/type.rs
@@ -19,10 +19,6 @@ pub trait Type<T: TypeKind, C = <T as TypeKind>::TypeKind>: TypeKind + Sized + C
     type Abi;
     type Default;
 
-    fn abi(&self) -> Self::Abi {
-        unsafe { std::mem::transmute_copy(self) }
-    }
-
     /// # Safety
     unsafe fn from_abi(abi: Self::Abi) -> Result<Self>;
     fn from_default(default: &Self::Default) -> Result<Self>;
@@ -55,7 +51,7 @@ where
     type Abi = std::mem::MaybeUninit<Self>;
     type Default = Self;
 
-    unsafe fn from_abi(abi: std::mem::MaybeUninit<Self>) -> Result<Self> {
+    unsafe fn from_abi(abi: Self::Abi) -> Result<Self> {
         Ok(abi.assume_init())
     }
 
@@ -71,7 +67,7 @@ where
     type Abi = Self;
     type Default = Self;
 
-    unsafe fn from_abi(abi: Self) -> Result<Self> {
+    unsafe fn from_abi(abi: Self::Abi) -> Result<Self> {
         Ok(abi)
     }
 
diff --git a/crates/libs/windows/src/Windows/Win32/Foundation/mod.rs b/crates/libs/windows/src/Windows/Win32/Foundation/mod.rs
index edcbdf804e..fc54b6c8f9 100644
--- a/crates/libs/windows/src/Windows/Win32/Foundation/mod.rs
+++ b/crates/libs/windows/src/Windows/Win32/Foundation/mod.rs
@@ -11572,7 +11572,7 @@ impl ::core::ops::Not for BOOL {
     }
 }
 impl ::windows_core::IntoParam<BOOL> for bool {
-    fn into_param(self) -> ::windows_core::Param<BOOL> {
+    unsafe fn into_param(self) -> ::windows_core::Param<BOOL> {
         ::windows_core::Param::Owned(self.into())
     }
 }
@@ -11645,7 +11645,7 @@ impl ::core::ops::Not for BOOLEAN {
     }
 }
 impl ::windows_core::IntoParam<BOOLEAN> for bool {
-    fn into_param(self) -> ::windows_core::Param<BOOLEAN> {
+    unsafe fn into_param(self) -> ::windows_core::Param<BOOLEAN> {
         ::windows_core::Param::Owned(self.into())
     }
 }
diff --git a/crates/tests/implement/tests/vector.rs b/crates/tests/implement/tests/vector.rs
index 3a175b1b2e..c799d3e88c 100644
--- a/crates/tests/implement/tests/vector.rs
+++ b/crates/tests/implement/tests/vector.rs
@@ -284,9 +284,24 @@ fn test_2759() -> Result<()> {
     v.Append(&uri)?;
     let uri = Uri::CreateUri(h!("https://microsoft.com/"))?;
     v.Append(&uri)?;
+    v.Append(&uri.cast::<IStringable>()?)?;
 
     assert_eq!(&v.GetAt(0)?.ToString()?, h!("https://github.com/"));
     assert_eq!(&v.GetAt(1)?.ToString()?, h!("https://microsoft.com/"));
 
     Ok(())
 }
+
+#[test]
+fn test_into_param() -> Result<()> {
+    let v: IVector<i32> = Vector::new(vec![]).into();
+    v.Append(1)?;
+    v.Append(Some(&2))?;
+    v.Append(None)?;
+
+    assert_eq!(v.GetAt(0)?, 1);
+    assert_eq!(v.GetAt(1)?, 2);
+    assert_eq!(v.GetAt(2)?, 0);
+
+    Ok(())
+}