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

Support functions that don't return #1485

Merged
merged 7 commits into from Feb 1, 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 .github/workflows/test.yml
Expand Up @@ -78,6 +78,7 @@ jobs:
cargo test --target ${{ matrix.target }} -p test_core &&
cargo test --target ${{ matrix.target }} -p test_debug &&
cargo test --target ${{ matrix.target }} -p test_deprecated &&
cargo test --target ${{ matrix.target }} -p test_does_not_return &&
cargo test --target ${{ matrix.target }} -p test_enums &&
cargo test --target ${{ matrix.target }} -p test_handles &&
cargo test --target ${{ matrix.target }} -p test_helpers &&
Expand Down Expand Up @@ -176,6 +177,7 @@ jobs:
cargo clippy -p test_core &&
cargo clippy -p test_debug &&
cargo clippy -p test_deprecated &&
cargo clippy -p test_does_not_return &&
cargo clippy -p test_enums &&
cargo clippy -p test_handles &&
cargo clippy -p test_helpers &&
Expand Down
19 changes: 16 additions & 3 deletions crates/libs/bindgen/src/functions.rs
Expand Up @@ -53,8 +53,12 @@ fn gen_function_if(entry: &[ElementType], gen: &Gen) -> TokenStream {
fn gen_sys_function(def: &MethodDef, gen: &Gen) -> TokenStream {
let name = gen_ident(def.name());
let signature = def.signature(&[]);
let return_type = gen_return_sig(&signature, gen);
let cfg = gen.function_cfg(def).gen_with_doc(gen);
let mut return_type = gen_return_sig(&signature, gen);

if return_type.is_empty() {
return_type = does_not_return(def);
}

let params = signature.params.iter().map(|p| {
let name = gen_param_name(&p.param);
Expand Down Expand Up @@ -214,16 +218,17 @@ fn gen_win_function(def: &MethodDef, gen: &Gen) -> TokenStream {
SignatureKind::ReturnVoid => {
let params = gen_win32_params(&signature.params, gen);
let args = signature.params.iter().map(gen_win32_abi_arg);
let does_not_return = does_not_return(def);

quote! {
#cfg
#[inline]
pub unsafe fn #name<#constraints>(#params) {
pub unsafe fn #name<#constraints>(#params) #does_not_return {
#[cfg(windows)]
{
#link_attr
extern "system" {
fn #name(#(#abi_params),*);
fn #name(#(#abi_params),*) #does_not_return;
}
#name(#(#args),*)
}
Expand All @@ -234,3 +239,11 @@ fn gen_win_function(def: &MethodDef, gen: &Gen) -> TokenStream {
}
}
}

fn does_not_return(def: &MethodDef) -> TokenStream {
if def.does_not_return() {
quote! { -> ! }
} else {
quote! {}
}
}
4 changes: 4 additions & 0 deletions crates/libs/metadata/src/tables/method_def.rs
Expand Up @@ -69,6 +69,10 @@ impl MethodDef {
self.has_attribute("DeprecatedAttribute")
}

pub fn does_not_return(&self) -> bool {
self.has_attribute("DoesNotReturnAttribute")
}

pub fn static_lib(&self) -> Option<String> {
self.attributes()
.filter_map(|attribute| match attribute.name() {
Expand Down
Expand Up @@ -110,7 +110,7 @@ extern "system" {
#[cfg(feature = "Win32_Foundation")]
pub fn FatalAppExitW(uaction: u32, lpmessagetext: super::super::super::Foundation::PWSTR);
#[doc = "*Required features: 'Win32_System_Diagnostics_Debug'*"]
pub fn FatalExit(exitcode: i32);
pub fn FatalExit(exitcode: i32) -> !;
#[doc = "*Required features: 'Win32_System_Diagnostics_Debug', 'Win32_Foundation'*"]
#[cfg(feature = "Win32_Foundation")]
pub fn FindDebugInfoFile(filename: super::super::super::Foundation::PSTR, symbolpath: super::super::super::Foundation::PSTR, debugfilepath: super::super::super::Foundation::PSTR) -> super::super::super::Foundation::HANDLE;
Expand Down Expand Up @@ -276,7 +276,7 @@ extern "system" {
#[cfg(feature = "Win32_Foundation")]
pub fn OutputDebugStringW(lpoutputstring: super::super::super::Foundation::PWSTR);
#[doc = "*Required features: 'Win32_System_Diagnostics_Debug'*"]
pub fn RaiseException(dwexceptioncode: u32, dwexceptionflags: u32, nnumberofarguments: u32, lparguments: *const usize);
pub fn RaiseException(dwexceptioncode: u32, dwexceptionflags: u32, nnumberofarguments: u32, lparguments: *const usize) -> !;
#[doc = "*Required features: 'Win32_System_Diagnostics_Debug', 'Win32_Foundation', 'Win32_System_Kernel'*"]
#[cfg(all(feature = "Win32_Foundation", feature = "Win32_System_Kernel"))]
pub fn RaiseFailFastException(pexceptionrecord: *const EXCEPTION_RECORD, pcontextrecord: *const CONTEXT, dwflags: u32);
Expand Down Expand Up @@ -368,7 +368,7 @@ extern "system" {
pub fn RtlPcToFileHeader(pcvalue: *const ::core::ffi::c_void, baseofimage: *mut *mut ::core::ffi::c_void) -> *mut ::core::ffi::c_void;
#[doc = "*Required features: 'Win32_System_Diagnostics_Debug', 'Win32_Foundation'*"]
#[cfg(feature = "Win32_Foundation")]
pub fn RtlRaiseException(exceptionrecord: *const EXCEPTION_RECORD);
pub fn RtlRaiseException(exceptionrecord: *const EXCEPTION_RECORD) -> !;
#[doc = "*Required features: 'Win32_System_Diagnostics_Debug', 'Win32_Foundation', 'Win32_System_Kernel'*"]
#[cfg(all(feature = "Win32_Foundation", feature = "Win32_System_Kernel"))]
pub fn RtlRestoreContext(contextrecord: *const CONTEXT, exceptionrecord: *const EXCEPTION_RECORD);
Expand Down
Expand Up @@ -72,7 +72,7 @@ extern "system" {
pub fn FreeLibrary(hlibmodule: super::super::Foundation::HINSTANCE) -> super::super::Foundation::BOOL;
#[doc = "*Required features: 'Win32_System_LibraryLoader', 'Win32_Foundation'*"]
#[cfg(feature = "Win32_Foundation")]
pub fn FreeLibraryAndExitThread(hlibmodule: super::super::Foundation::HINSTANCE, dwexitcode: u32);
pub fn FreeLibraryAndExitThread(hlibmodule: super::super::Foundation::HINSTANCE, dwexitcode: u32) -> !;
#[doc = "*Required features: 'Win32_System_LibraryLoader', 'Win32_Foundation'*"]
#[cfg(feature = "Win32_Foundation")]
pub fn FreeResource(hresdata: isize) -> super::super::Foundation::BOOL;
Expand Down
4 changes: 2 additions & 2 deletions crates/libs/sys/src/Windows/Win32/System/Threading/mod.rs
Expand Up @@ -247,9 +247,9 @@ extern "system" {
#[cfg(feature = "Win32_Foundation")]
pub fn ExecuteUmsThread(umsthread: *mut ::core::ffi::c_void) -> super::super::Foundation::BOOL;
#[doc = "*Required features: 'Win32_System_Threading'*"]
pub fn ExitProcess(uexitcode: u32);
pub fn ExitProcess(uexitcode: u32) -> !;
#[doc = "*Required features: 'Win32_System_Threading'*"]
pub fn ExitThread(dwexitcode: u32);
pub fn ExitThread(dwexitcode: u32) -> !;
#[doc = "*Required features: 'Win32_System_Threading'*"]
pub fn FlsAlloc(lpcallback: PFLS_CALLBACK_FUNCTION) -> u32;
#[doc = "*Required features: 'Win32_System_Threading', 'Win32_Foundation'*"]
Expand Down
Expand Up @@ -9147,12 +9147,12 @@ pub unsafe fn FatalAppExitW<'a, Param1: ::windows::core::IntoParam<'a, super::su
}
#[doc = "*Required features: 'Win32_System_Diagnostics_Debug'*"]
#[inline]
pub unsafe fn FatalExit(exitcode: i32) {
pub unsafe fn FatalExit(exitcode: i32) -> ! {
#[cfg(windows)]
{
#[link(name = "windows")]
extern "system" {
fn FatalExit(exitcode: i32);
fn FatalExit(exitcode: i32) -> !;
}
FatalExit(::core::mem::transmute(exitcode))
}
Expand Down Expand Up @@ -59972,12 +59972,12 @@ impl ::core::fmt::Debug for RTL_VIRTUAL_UNWIND_HANDLER_TYPE {
}
#[doc = "*Required features: 'Win32_System_Diagnostics_Debug'*"]
#[inline]
pub unsafe fn RaiseException(dwexceptioncode: u32, dwexceptionflags: u32, nnumberofarguments: u32, lparguments: *const usize) {
pub unsafe fn RaiseException(dwexceptioncode: u32, dwexceptionflags: u32, nnumberofarguments: u32, lparguments: *const usize) -> ! {
#[cfg(windows)]
{
#[link(name = "windows")]
extern "system" {
fn RaiseException(dwexceptioncode: u32, dwexceptionflags: u32, nnumberofarguments: u32, lparguments: *const usize);
fn RaiseException(dwexceptioncode: u32, dwexceptionflags: u32, nnumberofarguments: u32, lparguments: *const usize) -> !;
}
RaiseException(::core::mem::transmute(dwexceptioncode), ::core::mem::transmute(dwexceptionflags), ::core::mem::transmute(nnumberofarguments), ::core::mem::transmute(lparguments))
}
Expand Down Expand Up @@ -60463,12 +60463,12 @@ pub unsafe fn RtlPcToFileHeader(pcvalue: *const ::core::ffi::c_void, baseofimage
#[doc = "*Required features: 'Win32_System_Diagnostics_Debug', 'Win32_Foundation'*"]
#[cfg(feature = "Win32_Foundation")]
#[inline]
pub unsafe fn RtlRaiseException(exceptionrecord: *const EXCEPTION_RECORD) {
pub unsafe fn RtlRaiseException(exceptionrecord: *const EXCEPTION_RECORD) -> ! {
#[cfg(windows)]
{
#[link(name = "windows")]
extern "system" {
fn RtlRaiseException(exceptionrecord: *const EXCEPTION_RECORD);
fn RtlRaiseException(exceptionrecord: *const EXCEPTION_RECORD) -> !;
}
RtlRaiseException(::core::mem::transmute(exceptionrecord))
}
Expand Down
Expand Up @@ -405,12 +405,12 @@ pub unsafe fn FreeLibrary<'a, Param0: ::windows::core::IntoParam<'a, super::supe
#[doc = "*Required features: 'Win32_System_LibraryLoader', 'Win32_Foundation'*"]
#[cfg(feature = "Win32_Foundation")]
#[inline]
pub unsafe fn FreeLibraryAndExitThread<'a, Param0: ::windows::core::IntoParam<'a, super::super::Foundation::HINSTANCE>>(hlibmodule: Param0, dwexitcode: u32) {
pub unsafe fn FreeLibraryAndExitThread<'a, Param0: ::windows::core::IntoParam<'a, super::super::Foundation::HINSTANCE>>(hlibmodule: Param0, dwexitcode: u32) -> ! {
#[cfg(windows)]
{
#[link(name = "windows")]
extern "system" {
fn FreeLibraryAndExitThread(hlibmodule: super::super::Foundation::HINSTANCE, dwexitcode: u32);
fn FreeLibraryAndExitThread(hlibmodule: super::super::Foundation::HINSTANCE, dwexitcode: u32) -> !;
}
FreeLibraryAndExitThread(hlibmodule.into_param().abi(), ::core::mem::transmute(dwexitcode))
}
Expand Down
8 changes: 4 additions & 4 deletions crates/libs/windows/src/Windows/Win32/System/Threading/mod.rs
Expand Up @@ -1540,12 +1540,12 @@ pub unsafe fn ExecuteUmsThread(umsthread: *mut ::core::ffi::c_void) -> super::su
}
#[doc = "*Required features: 'Win32_System_Threading'*"]
#[inline]
pub unsafe fn ExitProcess(uexitcode: u32) {
pub unsafe fn ExitProcess(uexitcode: u32) -> ! {
#[cfg(windows)]
{
#[link(name = "windows")]
extern "system" {
fn ExitProcess(uexitcode: u32);
fn ExitProcess(uexitcode: u32) -> !;
}
ExitProcess(::core::mem::transmute(uexitcode))
}
Expand All @@ -1554,12 +1554,12 @@ pub unsafe fn ExitProcess(uexitcode: u32) {
}
#[doc = "*Required features: 'Win32_System_Threading'*"]
#[inline]
pub unsafe fn ExitThread(dwexitcode: u32) {
pub unsafe fn ExitThread(dwexitcode: u32) -> ! {
#[cfg(windows)]
{
#[link(name = "windows")]
extern "system" {
fn ExitThread(dwexitcode: u32);
fn ExitThread(dwexitcode: u32) -> !;
}
ExitThread(::core::mem::transmute(dwexitcode))
}
Expand Down
17 changes: 17 additions & 0 deletions crates/tests/does_not_return/Cargo.toml
@@ -0,0 +1,17 @@
[package]
name = "test_does_not_return"
version = "0.0.0"
authors = ["Microsoft"]
edition = "2018"

[dependencies.windows]
path = "../../libs/windows"
features = [
"Win32_System_Diagnostics_Debug",
]

[dependencies.windows-sys]
path = "../../libs/sys"
features = [
"Win32_System_Diagnostics_Debug",
]
1 change: 1 addition & 0 deletions crates/tests/does_not_return/src/lib.rs
@@ -0,0 +1 @@

10 changes: 10 additions & 0 deletions crates/tests/does_not_return/tests/sys.rs
@@ -0,0 +1,10 @@
use windows_sys::Win32::System::Diagnostics::Debug::FatalExit;

// Compile-only test to check that FatalExit returns `-> !`

#[allow(dead_code)]
fn test() -> i32 {
unsafe {
FatalExit(123);
}
}
10 changes: 10 additions & 0 deletions crates/tests/does_not_return/tests/win.rs
@@ -0,0 +1,10 @@
use windows::Win32::System::Diagnostics::Debug::FatalExit;

// Compile-only test to check that FatalExit returns `-> !`

#[allow(dead_code)]
fn test() -> i32 {
unsafe {
FatalExit(123);
}
}