Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reintroduces handle types for the windows crate #1423

Merged
merged 3 commits into from Jan 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.toml
Expand Up @@ -11,5 +11,7 @@ members = [
"crates/tests/debug",
"crates/tests/enums",
"crates/tests/sys",
"crates/tests/handles",
"crates/tests/agile",
]
exclude = ["crates/tests/component"]
88 changes: 88 additions & 0 deletions crates/libs/bindgen/src/handles.rs
@@ -0,0 +1,88 @@
use super::*;

pub fn gen(def: &TypeDef, gen: &Gen) -> TokenStream {
if gen.sys {
gen_sys_handle(def, gen)
} else {
gen_win_handle(def, gen)
}
}

pub fn gen_sys_handle(def: &TypeDef, gen: &Gen) -> TokenStream {
let ident = gen_ident(def.name());
let signature = gen_signature(def, gen);

quote! {
pub type #ident = #signature;
}
}

pub fn gen_win_handle(def: &TypeDef, gen: &Gen) -> TokenStream {
let name = def.name();
let ident = gen_ident(def.name());
let signature = gen_signature(def, gen);

let mut tokens = quote! {
#[repr(transparent)]
// Unfortunately, Rust requires these to be derived to allow constant patterns.
#[derive(::core::cmp::PartialEq, ::core::cmp::Eq)]
pub struct #ident(pub #signature);
impl #ident {
pub fn is_invalid(&self) -> bool {
*self == unsafe { ::core::mem::zeroed() }
}

pub fn ok(self) -> ::windows::core::Result<Self> {
if !self.is_invalid() {
Ok(self)
} else {
Err(::windows::core::Error::from_win32())
}
}
}
impl ::core::default::Default for #ident {
fn default() -> Self {
unsafe { ::core::mem::zeroed() }
}
}
impl ::core::clone::Clone for #ident {
fn clone(&self) -> Self {
*self
}
}
impl ::core::marker::Copy for #ident {}
impl ::core::fmt::Debug for #ident {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
f.debug_tuple(#name).field(&self.0).finish()
}
}
unsafe impl ::windows::core::Abi for #ident {
type Abi = Self;
}
};

if let Some(dependency) = def.is_convertible_to() {
let type_name = dependency.type_name();
let mut dependency = gen.namespace(type_name.namespace());
dependency.push_str(type_name.name());

tokens.combine(&quote! {
impl<'a> ::windows::core::IntoParam<'a, #dependency> for #ident {
fn into_param(self) -> ::windows::core::Param<'a, #dependency> {
::windows::core::Param::Owned(#dependency(self.0))
}
}
});
}

tokens
}

fn gen_signature(def: &TypeDef, gen: &Gen) -> TokenStream {
if def.type_name() == TypeName::HANDLE {
quote! { *mut ::core::ffi::c_void }
} else {
let signature = def.fields().next().map(|field| field.signature(Some(def))).unwrap();
gen_sig(&signature, gen)
}
}
7 changes: 4 additions & 3 deletions crates/libs/bindgen/src/interfaces.rs
Expand Up @@ -181,11 +181,12 @@ fn gen_conversions(def: &TypeDef, cfg: &Cfg, gen: &Gen) -> TokenStream {
}

fn gen_agile(def: &TypeDef, gen: &Gen) -> TokenStream {
if def.type_name() == TypeName::IRestrictedErrorInfo {
if def.type_name() == TypeName::IRestrictedErrorInfo || def.async_kind() != AsyncKind::None {
let name = gen_type_ident(def, gen);
let constraints = gen_type_constraints(def, gen);
quote! {
unsafe impl ::core::marker::Send for #name {}
unsafe impl ::core::marker::Sync for #name {}
unsafe impl<#(#constraints)*> ::core::marker::Send for #name {}
unsafe impl<#(#constraints)*> ::core::marker::Sync for #name {}
}
} else {
TokenStream::new()
Expand Down
1 change: 1 addition & 0 deletions crates/libs/bindgen/src/lib.rs
Expand Up @@ -8,6 +8,7 @@ mod enums;
mod extensions;
mod functions;
mod gen;
mod handles;
mod helpers;
mod interfaces;
mod iterator;
Expand Down
23 changes: 7 additions & 16 deletions crates/libs/bindgen/src/structs.rs
Expand Up @@ -5,31 +5,22 @@ pub fn gen(def: &TypeDef, gen: &Gen) -> TokenStream {
return quote! {};
}

gen_struct_with_name(def, def.name(), &Cfg::new(), gen)
}

fn gen_struct_with_name(def: &TypeDef, struct_name: &str, cfg: &Cfg, gen: &Gen) -> TokenStream {
if !gen.sys {
if let Some(replacement) = replacements::gen(def) {
return replacement;
}
}

let name = gen_ident(struct_name);

if def.is_handle() {
let signature = if def.type_name() == TypeName::HANDLE {
quote! { *mut ::core::ffi::c_void }
} else {
let signature = def.fields().next().map(|field| field.signature(Some(def))).unwrap();
gen_sig(&signature, gen)
};

return quote! {
pub type #name = #signature;
};
return handles::gen(def, gen);
}

gen_struct_with_name(def, def.name(), &Cfg::new(), gen)
}

fn gen_struct_with_name(def: &TypeDef, struct_name: &str, cfg: &Cfg, gen: &Gen) -> TokenStream {
let name = gen_ident(struct_name);

if def.fields().next().is_none() {
if let Some(guid) = GUID::from_attributes(def.attributes()) {
let value = gen_guid(&guid, gen);
Expand Down
1 change: 1 addition & 0 deletions crates/libs/quote/src/token_stream.rs
Expand Up @@ -33,6 +33,7 @@ impl TokenStream {
self.0.push_str(&other.0)
}

#[must_use]
pub fn join(&self, value: &str) -> Self {
Self(format!("{}{}", self.0, value))
}
Expand Down
1 change: 1 addition & 0 deletions crates/libs/reader/src/constant_value.rs
Expand Up @@ -45,6 +45,7 @@ impl ConstantValue {
}
}

#[must_use]
pub fn next(&self) -> Self {
match self {
Self::U32(value) => Self::U32(value + 1),
Expand Down
3 changes: 2 additions & 1 deletion crates/libs/reader/src/element_type.rs
Expand Up @@ -232,6 +232,7 @@ impl ElementType {
}
}

#[must_use]
pub fn underlying_type(&self) -> ElementType {
match self {
Self::TypeDef(def) => def.underlying_type(),
Expand All @@ -243,7 +244,7 @@ impl ElementType {
pub fn has_replacement(&self) -> bool {
match self {
Self::HRESULT => true,
Self::TypeDef(def) => matches!(def.type_name(), TypeName::BOOL | TypeName::BSTR | TypeName::HANDLE | TypeName::NTSTATUS | TypeName::PSTR | TypeName::PWSTR),
Self::TypeDef(def) => def.is_handle(),
_ => false,
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/libs/reader/src/tables/type_def.rs
Expand Up @@ -14,6 +14,7 @@ impl From<Row> for TypeDef {
}

impl TypeDef {
#[must_use]
pub fn with_generics(mut self) -> Self {
self.generics = self.generic_params().map(|generic| ElementType::GenericParam(generic.name().to_string())).collect();
self
Expand Down
8 changes: 8 additions & 0 deletions crates/libs/windows/src/Windows/Foundation/mod.rs
Expand Up @@ -1119,6 +1119,8 @@ impl ::std::future::Future for IAsyncAction {
}
}
}
unsafe impl ::core::marker::Send for IAsyncAction {}
unsafe impl ::core::marker::Sync for IAsyncAction {}
unsafe impl ::windows::core::Interface for IAsyncAction {
type Vtable = IAsyncActionVtbl;
const IID: ::windows::core::GUID = ::windows::core::GUID::from_u128(0x5a648006_843a_4da9_865b_9d26e5dfad7b);
Expand Down Expand Up @@ -1320,6 +1322,8 @@ impl<TProgress: ::windows::core::RuntimeType + 'static> ::std::future::Future fo
}
}
}
unsafe impl<TProgress: ::windows::core::RuntimeType + 'static> ::core::marker::Send for IAsyncActionWithProgress<TProgress> {}
unsafe impl<TProgress: ::windows::core::RuntimeType + 'static> ::core::marker::Sync for IAsyncActionWithProgress<TProgress> {}
unsafe impl<TProgress: ::windows::core::RuntimeType + 'static> ::windows::core::Interface for IAsyncActionWithProgress<TProgress> {
type Vtable = IAsyncActionWithProgressVtbl<TProgress>;
const IID: ::windows::core::GUID = ::windows::core::GUID::from_signature(<Self as ::windows::core::RuntimeType>::SIGNATURE);
Expand Down Expand Up @@ -1633,6 +1637,8 @@ impl<TResult: ::windows::core::RuntimeType + 'static> ::std::future::Future for
}
}
}
unsafe impl<TResult: ::windows::core::RuntimeType + 'static> ::core::marker::Send for IAsyncOperation<TResult> {}
unsafe impl<TResult: ::windows::core::RuntimeType + 'static> ::core::marker::Sync for IAsyncOperation<TResult> {}
unsafe impl<TResult: ::windows::core::RuntimeType + 'static> ::windows::core::Interface for IAsyncOperation<TResult> {
type Vtable = IAsyncOperationVtbl<TResult>;
const IID: ::windows::core::GUID = ::windows::core::GUID::from_signature(<Self as ::windows::core::RuntimeType>::SIGNATURE);
Expand Down Expand Up @@ -1841,6 +1847,8 @@ impl<TResult: ::windows::core::RuntimeType + 'static, TProgress: ::windows::core
}
}
}
unsafe impl<TResult: ::windows::core::RuntimeType + 'static, TProgress: ::windows::core::RuntimeType + 'static> ::core::marker::Send for IAsyncOperationWithProgress<TResult, TProgress> {}
unsafe impl<TResult: ::windows::core::RuntimeType + 'static, TProgress: ::windows::core::RuntimeType + 'static> ::core::marker::Sync for IAsyncOperationWithProgress<TResult, TProgress> {}
unsafe impl<TResult: ::windows::core::RuntimeType + 'static, TProgress: ::windows::core::RuntimeType + 'static> ::windows::core::Interface for IAsyncOperationWithProgress<TResult, TProgress> {
type Vtable = IAsyncOperationWithProgressVtbl<TResult, TProgress>;
const IID: ::windows::core::GUID = ::windows::core::GUID::from_signature(<Self as ::windows::core::RuntimeType>::SIGNATURE);
Expand Down