Skip to content
Draft
10 changes: 8 additions & 2 deletions crates/libs/bindgen/src/types/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,11 @@ impl Method {
quote! { core::slice::from_raw_parts(core::mem::transmute_copy(&#name), #abi_size_name as usize) }
} else if param.is_primitive(reader) {
quote! { #name }
} else if param.is_const_ref() || param.is_interface() || matches!(&param.ty, Type::Generic(_)) {
} else if param.is_const_ref() || param.is_interface() {
quote! { core::mem::transmute_copy(&#name) }
} else if let Type::Generic(g) = &param.ty {
let type_name = to_ident(g.name());
quote! { <#type_name as windows_core::Type<#type_name>>::abi_to_param(&#name) }
} else {
quote! { core::mem::transmute(&#name) }
}
Expand Down Expand Up @@ -150,9 +153,12 @@ impl Method {
quote! { &[#default_type] }
} else if p.is_primitive(config.reader) {
quote! { #default_type }
} else if p.is_interface() || matches!(&p.ty, Type::Generic(_)) {
} else if p.is_interface() {
let type_name = p.write_name(config);
quote! { windows_core::Ref<#type_name> }
} else if matches!(&p.ty, Type::Generic(_)) {
let type_name = p.write_name(config);
quote! { windows_core::ImplParam<'_, #type_name> }
} else {
quote! { &#default_type }
}
Expand Down
73 changes: 49 additions & 24 deletions crates/libs/collections/src/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -662,16 +662,16 @@ where
K: windows_core::RuntimeType + 'static,
V: windows_core::RuntimeType + 'static,
{
fn Lookup(&self, key: windows_core::Ref<K>) -> windows_core::Result<V>;
fn Lookup(&self, key: windows_core::ImplParam<'_, K>) -> windows_core::Result<V>;
fn Size(&self) -> windows_core::Result<u32>;
fn HasKey(&self, key: windows_core::Ref<K>) -> windows_core::Result<bool>;
fn HasKey(&self, key: windows_core::ImplParam<'_, K>) -> windows_core::Result<bool>;
fn GetView(&self) -> windows_core::Result<IMapView<K, V>>;
fn Insert(
&self,
key: windows_core::Ref<K>,
value: windows_core::Ref<V>,
key: windows_core::ImplParam<'_, K>,
value: windows_core::ImplParam<'_, V>,
) -> windows_core::Result<bool>;
fn Remove(&self, key: windows_core::Ref<K>) -> windows_core::Result<()>;
fn Remove(&self, key: windows_core::ImplParam<'_, K>) -> windows_core::Result<()>;
fn Clear(&self) -> windows_core::Result<()>;
}
impl<K: windows_core::RuntimeType + 'static, V: windows_core::RuntimeType + 'static>
Expand All @@ -691,7 +691,7 @@ impl<K: windows_core::RuntimeType + 'static, V: windows_core::RuntimeType + 'sta
unsafe {
let this: &Identity =
&*((this as *const *const ()).offset(OFFSET) as *const Identity);
match IMap_Impl::Lookup(this, core::mem::transmute_copy(&key)) {
match IMap_Impl::Lookup(this, <K as windows_core::Type<K>>::abi_to_param(&key)) {
Ok(ok__) => {
result__.write(core::mem::transmute_copy(&ok__));
core::mem::forget(ok__);
Expand Down Expand Up @@ -735,7 +735,7 @@ impl<K: windows_core::RuntimeType + 'static, V: windows_core::RuntimeType + 'sta
unsafe {
let this: &Identity =
&*((this as *const *const ()).offset(OFFSET) as *const Identity);
match IMap_Impl::HasKey(this, core::mem::transmute_copy(&key)) {
match IMap_Impl::HasKey(this, <K as windows_core::Type<K>>::abi_to_param(&key)) {
Ok(ok__) => {
result__.write(core::mem::transmute_copy(&ok__));
windows_core::HRESULT(0)
Expand Down Expand Up @@ -782,8 +782,8 @@ impl<K: windows_core::RuntimeType + 'static, V: windows_core::RuntimeType + 'sta
&*((this as *const *const ()).offset(OFFSET) as *const Identity);
match IMap_Impl::Insert(
this,
core::mem::transmute_copy(&key),
core::mem::transmute_copy(&value),
<K as windows_core::Type<K>>::abi_to_param(&key),
<V as windows_core::Type<V>>::abi_to_param(&value),
) {
Ok(ok__) => {
result__.write(core::mem::transmute_copy(&ok__));
Expand All @@ -805,7 +805,7 @@ impl<K: windows_core::RuntimeType + 'static, V: windows_core::RuntimeType + 'sta
unsafe {
let this: &Identity =
&*((this as *const *const ()).offset(OFFSET) as *const Identity);
IMap_Impl::Remove(this, core::mem::transmute_copy(&key)).into()
IMap_Impl::Remove(this, <K as windows_core::Type<K>>::abi_to_param(&key)).into()
}
}
unsafe extern "system" fn Clear<
Expand Down Expand Up @@ -1016,9 +1016,9 @@ where
K: windows_core::RuntimeType + 'static,
V: windows_core::RuntimeType + 'static,
{
fn Lookup(&self, key: windows_core::Ref<K>) -> windows_core::Result<V>;
fn Lookup(&self, key: windows_core::ImplParam<'_, K>) -> windows_core::Result<V>;
fn Size(&self) -> windows_core::Result<u32>;
fn HasKey(&self, key: windows_core::Ref<K>) -> windows_core::Result<bool>;
fn HasKey(&self, key: windows_core::ImplParam<'_, K>) -> windows_core::Result<bool>;
fn Split(
&self,
first: windows_core::OutRef<IMapView<K, V>>,
Expand All @@ -1042,7 +1042,8 @@ impl<K: windows_core::RuntimeType + 'static, V: windows_core::RuntimeType + 'sta
unsafe {
let this: &Identity =
&*((this as *const *const ()).offset(OFFSET) as *const Identity);
match IMapView_Impl::Lookup(this, core::mem::transmute_copy(&key)) {
match IMapView_Impl::Lookup(this, <K as windows_core::Type<K>>::abi_to_param(&key))
{
Ok(ok__) => {
result__.write(core::mem::transmute_copy(&ok__));
core::mem::forget(ok__);
Expand Down Expand Up @@ -1086,7 +1087,8 @@ impl<K: windows_core::RuntimeType + 'static, V: windows_core::RuntimeType + 'sta
unsafe {
let this: &Identity =
&*((this as *const *const ()).offset(OFFSET) as *const Identity);
match IMapView_Impl::HasKey(this, core::mem::transmute_copy(&key)) {
match IMapView_Impl::HasKey(this, <K as windows_core::Type<K>>::abi_to_param(&key))
{
Ok(ok__) => {
result__.write(core::mem::transmute_copy(&ok__));
windows_core::HRESULT(0)
Expand Down Expand Up @@ -1373,11 +1375,19 @@ where
fn GetAt(&self, index: u32) -> windows_core::Result<T>;
fn Size(&self) -> windows_core::Result<u32>;
fn GetView(&self) -> windows_core::Result<IVectorView<T>>;
fn IndexOf(&self, value: windows_core::Ref<T>, index: &mut u32) -> windows_core::Result<bool>;
fn SetAt(&self, index: u32, value: windows_core::Ref<T>) -> windows_core::Result<()>;
fn InsertAt(&self, index: u32, value: windows_core::Ref<T>) -> windows_core::Result<()>;
fn IndexOf(
&self,
value: windows_core::ImplParam<'_, T>,
index: &mut u32,
) -> windows_core::Result<bool>;
fn SetAt(&self, index: u32, value: windows_core::ImplParam<'_, T>) -> windows_core::Result<()>;
fn InsertAt(
&self,
index: u32,
value: windows_core::ImplParam<'_, T>,
) -> windows_core::Result<()>;
fn RemoveAt(&self, index: u32) -> windows_core::Result<()>;
fn Append(&self, value: windows_core::Ref<T>) -> windows_core::Result<()>;
fn Append(&self, value: windows_core::ImplParam<'_, T>) -> windows_core::Result<()>;
fn RemoveAtEnd(&self) -> windows_core::Result<()>;
fn Clear(&self) -> windows_core::Result<()>;
fn GetMany(
Expand Down Expand Up @@ -1470,7 +1480,7 @@ impl<T: windows_core::RuntimeType + 'static> IVector_Vtbl<T> {
&*((this as *const *const ()).offset(OFFSET) as *const Identity);
match IVector_Impl::IndexOf(
this,
core::mem::transmute_copy(&value),
<T as windows_core::Type<T>>::abi_to_param(&value),
core::mem::transmute_copy(&index),
) {
Ok(ok__) => {
Expand All @@ -1493,7 +1503,12 @@ impl<T: windows_core::RuntimeType + 'static> IVector_Vtbl<T> {
unsafe {
let this: &Identity =
&*((this as *const *const ()).offset(OFFSET) as *const Identity);
IVector_Impl::SetAt(this, index, core::mem::transmute_copy(&value)).into()
IVector_Impl::SetAt(
this,
index,
<T as windows_core::Type<T>>::abi_to_param(&value),
)
.into()
}
}
unsafe extern "system" fn InsertAt<
Expand All @@ -1508,7 +1523,12 @@ impl<T: windows_core::RuntimeType + 'static> IVector_Vtbl<T> {
unsafe {
let this: &Identity =
&*((this as *const *const ()).offset(OFFSET) as *const Identity);
IVector_Impl::InsertAt(this, index, core::mem::transmute_copy(&value)).into()
IVector_Impl::InsertAt(
this,
index,
<T as windows_core::Type<T>>::abi_to_param(&value),
)
.into()
}
}
unsafe extern "system" fn RemoveAt<
Expand Down Expand Up @@ -1536,7 +1556,8 @@ impl<T: windows_core::RuntimeType + 'static> IVector_Vtbl<T> {
unsafe {
let this: &Identity =
&*((this as *const *const ()).offset(OFFSET) as *const Identity);
IVector_Impl::Append(this, core::mem::transmute_copy(&value)).into()
IVector_Impl::Append(this, <T as windows_core::Type<T>>::abi_to_param(&value))
.into()
}
}
unsafe extern "system" fn RemoveAtEnd<
Expand Down Expand Up @@ -1812,7 +1833,11 @@ where
{
fn GetAt(&self, index: u32) -> windows_core::Result<T>;
fn Size(&self) -> windows_core::Result<u32>;
fn IndexOf(&self, value: windows_core::Ref<T>, index: &mut u32) -> windows_core::Result<bool>;
fn IndexOf(
&self,
value: windows_core::ImplParam<'_, T>,
index: &mut u32,
) -> windows_core::Result<bool>;
fn GetMany(
&self,
startIndex: u32,
Expand Down Expand Up @@ -1878,7 +1903,7 @@ impl<T: windows_core::RuntimeType + 'static> IVectorView_Vtbl<T> {
&*((this as *const *const ()).offset(OFFSET) as *const Identity);
match IVectorView_Impl::IndexOf(
this,
core::mem::transmute_copy(&value),
<T as windows_core::Type<T>>::abi_to_param(&value),
core::mem::transmute_copy(&index),
) {
Ok(ok__) => {
Expand Down
11 changes: 7 additions & 4 deletions crates/libs/collections/src/map_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,11 @@ where
K::Default: Clone + Ord,
V::Default: Clone,
{
fn Lookup(&self, key: Ref<K>) -> Result<V> {
let value = self.map.get(&*key).ok_or_else(|| Error::from(E_BOUNDS))?;
fn Lookup(&self, key: ImplParam<'_, K>) -> Result<V> {
let value = self
.map
.get(K::param_as_default(&key))
.ok_or_else(|| Error::from(E_BOUNDS))?;

V::from_default(value)
}
Expand All @@ -45,8 +48,8 @@ where
Ok(self.map.len().try_into()?)
}

fn HasKey(&self, key: Ref<K>) -> Result<bool> {
Ok(self.map.contains_key(&*key))
fn HasKey(&self, key: ImplParam<'_, K>) -> Result<bool> {
Ok(self.map.contains_key(K::param_as_default(&key)))
}

fn Split(&self, first: OutRef<IMapView<K, V>>, second: OutRef<IMapView<K, V>>) -> Result<()> {
Expand Down
8 changes: 6 additions & 2 deletions crates/libs/collections/src/vector_view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,12 @@ where
Ok(self.values.len().try_into()?)
}

fn IndexOf(&self, value: Ref<T>, result: &mut u32) -> Result<bool> {
match self.values.iter().position(|element| element == &*value) {
fn IndexOf(&self, value: ImplParam<'_, T>, result: &mut u32) -> Result<bool> {
match self
.values
.iter()
.position(|element| element == T::param_as_default(&value))
{
Some(index) => {
*result = index as u32;
Ok(true)
Expand Down
69 changes: 69 additions & 0 deletions crates/libs/core/src/type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,20 @@ pub struct CopyType;
pub trait Type<T: TypeKind, C = <T as TypeKind>::TypeKind>: TypeKind + Sized + Clone {
type Abi;
type Default;
type Param<'a>: 'a
where
Self: 'a;

fn is_null(abi: &Self::Abi) -> bool;
unsafe fn assume_init_ref(abi: &Self::Abi) -> &Self;
unsafe fn from_abi(abi: Self::Abi) -> Result<Self>;
fn from_default(default: &Self::Default) -> Result<Self>;
unsafe fn abi_to_param<'a>(abi: &'a Self::Abi) -> Self::Param<'a>
where
Self: 'a;
fn param_as_default<'a, 'b>(param: &'a Self::Param<'b>) -> &'a Self::Default
where
Self: 'b;
}

impl<T> Type<T, InterfaceType> for T
Expand All @@ -31,6 +40,10 @@ where
{
type Abi = *mut core::ffi::c_void;
type Default = Option<Self>;
type Param<'a>
= Ref<'a, Self>
where
Self: 'a;

fn is_null(abi: &Self::Abi) -> bool {
abi.is_null()
Expand All @@ -53,6 +66,20 @@ where
fn from_default(default: &Self::Default) -> Result<Self> {
default.as_ref().cloned().ok_or(Error::empty())
}

unsafe fn abi_to_param<'a>(abi: &'a Self::Abi) -> Ref<'a, Self>
where
Self: 'a,
{
unsafe { core::mem::transmute_copy(abi) }
}

fn param_as_default<'a, 'b>(param: &'a Ref<'b, Self>) -> &'a Option<Self>
where
Self: 'b,
{
param
}
}

impl<T> Type<T, CloneType> for T
Expand All @@ -61,6 +88,10 @@ where
{
type Abi = core::mem::MaybeUninit<Self>;
type Default = Self;
type Param<'a>
= Ref<'a, Self>
where
Self: 'a;

fn is_null(_: &Self::Abi) -> bool {
false
Expand All @@ -77,6 +108,20 @@ where
fn from_default(default: &Self::Default) -> Result<Self> {
Ok(default.clone())
}

unsafe fn abi_to_param<'a>(abi: &'a Self::Abi) -> Ref<'a, Self>
where
Self: 'a,
{
unsafe { core::mem::transmute_copy(abi) }
}

fn param_as_default<'a, 'b>(param: &'a Ref<'b, Self>) -> &'a Self
where
Self: 'b,
{
param
}
}

impl<T> Type<T, CopyType> for T
Expand All @@ -85,6 +130,10 @@ where
{
type Abi = Self;
type Default = Self;
type Param<'a>
= Self
where
Self: 'a;

fn is_null(_: &Self::Abi) -> bool {
false
Expand All @@ -101,6 +150,20 @@ where
fn from_default(default: &Self) -> Result<Self> {
Ok(default.clone())
}

unsafe fn abi_to_param<'a>(abi: &'a Self) -> Self
where
Self: 'a,
{
abi.clone()
}

fn param_as_default<'a, 'b>(param: &'a Self) -> &'a Self
where
Self: 'b,
{
param
}
}

impl<T: Interface> TypeKind for T {
Expand All @@ -125,3 +188,9 @@ primitives!(bool, i8, u8, i16, u16, i32, u32, i64, u64, f32, f64, usize, isize);

#[doc(hidden)]
pub type AbiType<T> = <T as Type<T>>::Abi;

/// The parameter type used in `_Impl` trait methods for a given WinRT type.
///
/// For copy types (primitives), this is the type itself. For other types, this is
/// [`Ref`], which allows borrowing across the ABI boundary without taking ownership.
pub type ImplParam<'a, T> = <T as Type<T>>::Param<'a>;
Loading
Loading