Support some edge cases for the next Win32 metadata update (#3109)

This commit is contained in:
Kenny Kerr 2024-06-17 13:24:55 -07:00 коммит произвёл GitHub
Родитель f639d7ea3c
Коммит 139ca3c88f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
7 изменённых файлов: 58 добавлений и 52 удалений

Просмотреть файл

@ -30,7 +30,9 @@ pub fn gen_win_handle(writer: &Writer, def: metadata::TypeDef) -> TokenStream {
let ident = to_ident(name);
let underlying_type = def.underlying_type();
let signature = writer.type_default_name(&underlying_type);
let is_invalid = if underlying_type.is_pointer() {
let invalid = metadata::type_def_invalid_values(def);
let is_invalid = if underlying_type.is_pointer() && (invalid.is_empty() || invalid == [0]) {
quote! {
impl #ident {
pub fn is_invalid(&self) -> bool {
@ -38,28 +40,24 @@ pub fn gen_win_handle(writer: &Writer, def: metadata::TypeDef) -> TokenStream {
}
}
}
} else if invalid.is_empty() {
quote! {}
} else {
let invalid = metadata::type_def_invalid_values(def);
let invalid = invalid.iter().map(|value| {
let literal = Literal::i64_unsuffixed(*value);
if !invalid.is_empty() {
let invalid = invalid.iter().map(|value| {
let literal = Literal::i64_unsuffixed(*value);
if *value < 0 && underlying_type.is_unsigned() {
quote! { self.0 == #literal as _ }
} else {
quote! { self.0 == #literal }
}
});
quote! {
impl #ident {
pub fn is_invalid(&self) -> bool {
#(#invalid)||*
}
if underlying_type.is_pointer() || (*value < 0 && underlying_type.is_unsigned()) {
quote! { self.0 == #literal as _ }
} else {
quote! { self.0 == #literal }
}
});
quote! {
impl #ident {
pub fn is_invalid(&self) -> bool {
#(#invalid)||*
}
}
} else {
quote! {}
}
};

Просмотреть файл

@ -43,34 +43,40 @@ fn gen_struct_with_name(
quote! { #[repr(C)] }
};
let fields = def.fields().map(|f| {
let name = to_ident(f.name());
let ty = f.ty(Some(def));
let fields = if def.fields().next().is_none() {
quote! { (pub u8); }
} else {
let fields = def.fields().map(|f| {
let name = to_ident(f.name());
let ty = f.ty(Some(def));
if f.flags().contains(metadata::FieldAttributes::Literal) {
quote! {}
} else if !writer.sys
&& flags.contains(metadata::TypeAttributes::ExplicitLayout)
&& !metadata::field_is_copyable(f, def)
{
let ty = writer.type_default_name(&ty);
quote! { pub #name: core::mem::ManuallyDrop<#ty>, }
} else if !writer.sys
&& !flags.contains(metadata::TypeAttributes::WindowsRuntime)
&& !metadata::field_is_blittable(f, def)
{
if let metadata::Type::Win32Array(ty, len) = ty {
let ty = writer.type_default_name(&ty);
quote! { pub #name: [core::mem::ManuallyDrop<#ty>; #len], }
} else {
if f.flags().contains(metadata::FieldAttributes::Literal) {
quote! {}
} else if !writer.sys
&& flags.contains(metadata::TypeAttributes::ExplicitLayout)
&& !metadata::field_is_copyable(f, def)
{
let ty = writer.type_default_name(&ty);
quote! { pub #name: core::mem::ManuallyDrop<#ty>, }
} else if !writer.sys
&& !flags.contains(metadata::TypeAttributes::WindowsRuntime)
&& !metadata::field_is_blittable(f, def)
{
if let metadata::Type::Win32Array(ty, len) = ty {
let ty = writer.type_default_name(&ty);
quote! { pub #name: [core::mem::ManuallyDrop<#ty>; #len], }
} else {
let ty = writer.type_default_name(&ty);
quote! { pub #name: core::mem::ManuallyDrop<#ty>, }
}
} else {
let ty = writer.type_default_name(&ty);
quote! { pub #name: #ty, }
}
} else {
let ty = writer.type_default_name(&ty);
quote! { pub #name: #ty, }
}
});
});
quote! { {#(#fields)*} }
};
let struct_or_union = if flags.contains(metadata::TypeAttributes::ExplicitLayout) {
quote! { union }
@ -85,7 +91,7 @@ fn gen_struct_with_name(
#repr
#features
#derive
pub #struct_or_union #name {#(#fields)*}
pub #struct_or_union #name #fields
};
tokens.combine(&gen_struct_constants(writer, def, &name, &cfg));

Просмотреть файл

@ -1,8 +1,10 @@
use super::*;
#[doc(hidden)]
pub struct Waiter(isize);
pub struct WaiterSignaler(isize);
pub struct Waiter(HANDLE);
pub struct WaiterSignaler(HANDLE);
unsafe impl Send for WaiterSignaler {}
impl Waiter {
pub fn new() -> crate::Result<(Waiter, WaiterSignaler)> {

Просмотреть файл

@ -10688,7 +10688,7 @@ impl windows_core::TypeKind for HANDLE_PTR {
pub struct HGLOBAL(pub *mut core::ffi::c_void);
impl HGLOBAL {
pub fn is_invalid(&self) -> bool {
self.0.is_null()
self.0 == -1 as _ || self.0 == 0 as _
}
}
impl windows_core::Free for HGLOBAL {
@ -10740,7 +10740,7 @@ impl From<HINSTANCE> for HMODULE {
pub struct HLOCAL(pub *mut core::ffi::c_void);
impl HLOCAL {
pub fn is_invalid(&self) -> bool {
self.0.is_null()
self.0 == -1 as _ || self.0 == 0 as _
}
}
impl windows_core::Free for HLOCAL {

Просмотреть файл

@ -14306,7 +14306,7 @@ impl windows_core::TypeKind for HCERTCHAINENGINE {
pub struct HCERTSTORE(pub *mut core::ffi::c_void);
impl HCERTSTORE {
pub fn is_invalid(&self) -> bool {
self.0.is_null()
self.0 == -1 as _ || self.0 == 0 as _
}
}
impl Default for HCERTSTORE {
@ -14322,7 +14322,7 @@ impl windows_core::TypeKind for HCERTSTORE {
pub struct HCERTSTOREPROV(pub *mut core::ffi::c_void);
impl HCERTSTOREPROV {
pub fn is_invalid(&self) -> bool {
self.0.is_null()
self.0 == -1 as _ || self.0 == 0 as _
}
}
impl Default for HCERTSTOREPROV {

Просмотреть файл

@ -2671,7 +2671,7 @@ impl Default for PRIVILEGE_SET {
pub struct PSECURITY_DESCRIPTOR(pub *mut core::ffi::c_void);
impl PSECURITY_DESCRIPTOR {
pub fn is_invalid(&self) -> bool {
self.0.is_null()
self.0 == -1 as _ || self.0 == 0 as _
}
}
impl Default for PSECURITY_DESCRIPTOR {

Просмотреть файл

@ -8227,7 +8227,7 @@ impl From<HCURSOR> for HICON {
pub struct HDEVNOTIFY(pub *mut core::ffi::c_void);
impl HDEVNOTIFY {
pub fn is_invalid(&self) -> bool {
self.0.is_null()
self.0 == -1 as _ || self.0 == 0 as _
}
}
impl windows_core::Free for HDEVNOTIFY {