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 ident = to_ident(name);
let underlying_type = def.underlying_type(); let underlying_type = def.underlying_type();
let signature = writer.type_default_name(&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! { quote! {
impl #ident { impl #ident {
pub fn is_invalid(&self) -> bool { 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 { } 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() { if underlying_type.is_pointer() || (*value < 0 && underlying_type.is_unsigned()) {
let invalid = invalid.iter().map(|value| { quote! { self.0 == #literal as _ }
let literal = Literal::i64_unsuffixed(*value); } else {
quote! { self.0 == #literal }
if *value < 0 && underlying_type.is_unsigned() { }
quote! { self.0 == #literal as _ } });
} else { quote! {
quote! { self.0 == #literal } impl #ident {
} pub fn is_invalid(&self) -> bool {
}); #(#invalid)||*
quote! {
impl #ident {
pub fn is_invalid(&self) -> bool {
#(#invalid)||*
}
} }
} }
} else {
quote! {}
} }
}; };

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

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

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

@ -1,8 +1,10 @@
use super::*; use super::*;
#[doc(hidden)] #[doc(hidden)]
pub struct Waiter(isize); pub struct Waiter(HANDLE);
pub struct WaiterSignaler(isize); pub struct WaiterSignaler(HANDLE);
unsafe impl Send for WaiterSignaler {}
impl Waiter { impl Waiter {
pub fn new() -> crate::Result<(Waiter, WaiterSignaler)> { 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); pub struct HGLOBAL(pub *mut core::ffi::c_void);
impl HGLOBAL { impl HGLOBAL {
pub fn is_invalid(&self) -> bool { pub fn is_invalid(&self) -> bool {
self.0.is_null() self.0 == -1 as _ || self.0 == 0 as _
} }
} }
impl windows_core::Free for HGLOBAL { impl windows_core::Free for HGLOBAL {
@ -10740,7 +10740,7 @@ impl From<HINSTANCE> for HMODULE {
pub struct HLOCAL(pub *mut core::ffi::c_void); pub struct HLOCAL(pub *mut core::ffi::c_void);
impl HLOCAL { impl HLOCAL {
pub fn is_invalid(&self) -> bool { pub fn is_invalid(&self) -> bool {
self.0.is_null() self.0 == -1 as _ || self.0 == 0 as _
} }
} }
impl windows_core::Free for HLOCAL { 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); pub struct HCERTSTORE(pub *mut core::ffi::c_void);
impl HCERTSTORE { impl HCERTSTORE {
pub fn is_invalid(&self) -> bool { pub fn is_invalid(&self) -> bool {
self.0.is_null() self.0 == -1 as _ || self.0 == 0 as _
} }
} }
impl Default for HCERTSTORE { impl Default for HCERTSTORE {
@ -14322,7 +14322,7 @@ impl windows_core::TypeKind for HCERTSTORE {
pub struct HCERTSTOREPROV(pub *mut core::ffi::c_void); pub struct HCERTSTOREPROV(pub *mut core::ffi::c_void);
impl HCERTSTOREPROV { impl HCERTSTOREPROV {
pub fn is_invalid(&self) -> bool { pub fn is_invalid(&self) -> bool {
self.0.is_null() self.0 == -1 as _ || self.0 == 0 as _
} }
} }
impl Default for HCERTSTOREPROV { impl Default for HCERTSTOREPROV {

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

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

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

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