From a18b0586713da7bd6d841402f330d1f6d0752019 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Wed, 16 Sep 2026 13:40:44 +0100 Subject: [PATCH 1/9] Add Callable trait --- libcc2rs/src/callable.rs | 52 ++++++++++++++++++++++++++++++++++++++++ libcc2rs/src/lib.rs | 3 +++ 2 files changed, 55 insertions(+) create mode 100644 libcc2rs/src/callable.rs diff --git a/libcc2rs/src/callable.rs b/libcc2rs/src/callable.rs new file mode 100644 index 00000000..747277d0 --- /dev/null +++ b/libcc2rs/src/callable.rs @@ -0,0 +1,52 @@ +// Copyright (c) 2022-present INESC-ID. +// Distributed under the MIT license that can be found in the LICENSE file. + +macro_rules! callable { + ($name:ident; $($a:ident: $A:ident),*) => { + pub trait $name<$($A,)* R> { + fn call(&self, $($a: $A),*) -> R; + } + + impl $name<$($A,)* R> for F + where + F: Fn($($A),*) -> R, + { + #[inline] + fn call(&self, $($a: $A),*) -> R { + self($($a),*) + } + } + + impl $name<$($A,)* R> for Option + where + F: Fn($($A),*) -> R, + { + #[inline] + fn call(&self, $($a: $A),*) -> R { + self.as_ref().unwrap()($($a),*) + } + } + + impl<$($A,)* R> $name<$($A,)* R> for Option R> { + #[inline] + fn call(&self, $($a: $A),*) -> R { + unsafe { self.unwrap()($($a),*) } + } + } + + impl $name<$($A,)* R> for crate::fn_ptr::FnPtr + where + F: Fn($($A),*) -> R + 'static, + { + #[inline] + fn call(&self, $($a: $A),*) -> R { + (**self)($($a),*) + } + } + }; +} + +callable!(Callable0;); +callable!(Callable1; a1: A1); +callable!(Callable2; a1: A1, a2: A2); +callable!(Callable3; a1: A1, a2: A2, a3: A3); diff --git a/libcc2rs/src/lib.rs b/libcc2rs/src/lib.rs index fb1f9be0..06b1e779 100644 --- a/libcc2rs/src/lib.rs +++ b/libcc2rs/src/lib.rs @@ -21,6 +21,9 @@ pub use libc_shims::*; mod fn_ptr; pub use fn_ptr::FnPtr; +mod callable; +pub use callable::*; + mod inc; pub use inc::*; From f9f5fd75eef9a9b0f21424eb709c6f3b92afd11f Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Wed, 16 Sep 2026 13:42:43 +0100 Subject: [PATCH 2/9] Deduplicate rules using the Callable trait --- rules/algorithm/src.cpp | 19 ++----------- rules/algorithm/tgt_refcount.rs | 23 +++------------- rules/algorithm/tgt_unsafe.rs | 49 ++++++--------------------------- rules/cstdlib/tgt_refcount.rs | 14 +++++++--- rules/cstdlib/tgt_unsafe.rs | 24 +++++++++------- rules/rustls/tgt_unsafe.rs | 34 ++++++++++++++--------- 6 files changed, 61 insertions(+), 102 deletions(-) diff --git a/rules/algorithm/src.cpp b/rules/algorithm/src.cpp index 097b05cb..0d2946cd 100644 --- a/rules/algorithm/src.cpp +++ b/rules/algorithm/src.cpp @@ -9,6 +9,7 @@ struct T2 { friend bool operator<(T2 a, T2 b) { return false; } + bool operator()(const T2 &, const T2 &) const; }; struct T1 { @@ -91,14 +92,7 @@ template T1 f3(T1 first, T1 last, const T2 &value) { return std::find(first, last, value); } -// TODO -auto lambda = [](const T2 &a, const T2 &b) { return false; }; -void f6(T1 first, T1 last, decltype(lambda) comp) { - return std::stable_sort(first, last, comp); -} - -template -void f7(T1 first, T1 last, bool (*comp)(const T2 &, const T2 &)) { +void f6(T1 first, T1 last, T2 comp) { return std::stable_sort(first, last, comp); } @@ -126,14 +120,7 @@ std::ostream_iterator f13(std::string::iterator a0, return std::copy(a0, a1, a2); } -// TODO -auto lambda_nref = [](T2 a, T2 b) { return false; }; -void f14(T1 *first, T1 *last, decltype(lambda_nref) comp) { - return std::stable_sort(first, last, comp); -} - -template -void f15(T1 *first, T1 *last, bool (*comp)(T2, T2)) { +void f14(T1 *first, T1 *last, T2 comp) { return std::stable_sort(first, last, comp); } diff --git a/rules/algorithm/tgt_refcount.rs b/rules/algorithm/tgt_refcount.rs index 74866b39..66b8a801 100644 --- a/rules/algorithm/tgt_refcount.rs +++ b/rules/algorithm/tgt_refcount.rs @@ -38,16 +38,9 @@ fn f3(a0: Ptr, a1: Ptr, a2: T1) -> Ptr fn f6(a0: Ptr, a1: Ptr, a2: T2) where - T2: FnMut(Ptr, Ptr) -> bool, + T2: Callable2, Ptr, bool>, { - a0.sort_with_cmp(a1.get_offset(), a2) -} - -fn f7(a0: Ptr, a1: Ptr, a2: T2) -where - T2: FnMut(Ptr, Ptr) -> bool, -{ - a0.sort_with_cmp(a1.get_offset(), a2) + a0.sort_with_cmp(a1.get_offset(), |x, y| a2.call(x, y)) } fn f8(a0: Ptr, a1: Ptr) -> Ptr { @@ -109,17 +102,9 @@ fn f13(a0: Ptr, a1: Ptr, a2: &mut ::std::fs::File) -> ::std::fs::File { fn f14(a0: Ptr, a1: Ptr, a2: T2) where - T2: Fn(T1, T1) -> bool, -{ - let fun = |x: Ptr, y: Ptr| a2((x.read()).clone(), (y.read()).clone()); - a0.sort_with_cmp(a1.get_offset(), fun) -} - -fn f15(a0: Ptr, a1: Ptr, a2: T2) -where - T2: Fn(T1, T1) -> bool, + T2: Callable2, { - let fun = |x: Ptr, y: Ptr| a2((x.read()).clone(), (y.read()).clone()); + let fun = |x: Ptr, y: Ptr| a2.call((x.read()).clone(), (y.read()).clone()); a0.sort_with_cmp(a1.get_offset(), fun) } diff --git a/rules/algorithm/tgt_unsafe.rs b/rules/algorithm/tgt_unsafe.rs index 101a2060..dbf6650e 100644 --- a/rules/algorithm/tgt_unsafe.rs +++ b/rules/algorithm/tgt_unsafe.rs @@ -1,6 +1,7 @@ // Copyright (c) 2022-present INESC-ID. // Distributed under the MIT license that can be found in the LICENSE file. +use libcc2rs::*; use std::io::{Seek, Write}; unsafe fn f1(a0: *mut T1, a1: *mut T1) { @@ -27,31 +28,15 @@ unsafe fn f3(a0: *mut T1, a1: *mut T1, a2: T1) -> *mut T1 { it } -unsafe fn f6(a0: *mut T1, a1: *mut T1, a2: &mut T2) +unsafe fn f6(a0: *mut T1, a1: *mut T1, a2: T2) where - T2: FnMut(&T1, &T1) -> bool, + T2: Callable2<*const T1, *const T1, bool>, { let len = a1.offset_from(a0) as usize; ::std::slice::from_raw_parts_mut(a0, len).sort_by(|x, y| { - if (a2)(x, y) { + if a2.call(x as *const _, y as *const _) { std::cmp::Ordering::Less - } else if (a2)(y, x) { - std::cmp::Ordering::Greater - } else { - std::cmp::Ordering::Equal - } - }) -} - -unsafe fn f7(a0: *mut T1, a1: *mut T1, a2: &mut T2) -where - T2: FnMut(&T1, &T1) -> bool, -{ - let len = a1.offset_from(a0) as usize; - ::std::slice::from_raw_parts_mut(a0, len).sort_by(|x, y| { - if (a2)(x, y) { - std::cmp::Ordering::Less - } else if (a2)(y, x) { + } else if a2.call(y as *const _, x as *const _) { std::cmp::Ordering::Greater } else { std::cmp::Ordering::Equal @@ -113,31 +98,15 @@ unsafe fn f13( a2.try_clone().unwrap() } -unsafe fn f14(a0: *mut T1, a1: *mut T1, a2: &mut T2) -where - T2: FnMut(T1, T1) -> bool, -{ - let len = a1.offset_from(a0) as usize; - ::std::slice::from_raw_parts_mut(a0, len).sort_by(|x, y| { - if (a2)(*x, *y) { - std::cmp::Ordering::Less - } else if (a2)(*y, *x) { - std::cmp::Ordering::Greater - } else { - std::cmp::Ordering::Equal - } - }) -} - -unsafe fn f15(a0: *mut T1, a1: *mut T1, a2: &mut T2) +unsafe fn f14(a0: *mut T1, a1: *mut T1, a2: T2) where - T2: FnMut(T1, T1) -> bool, + T2: Callable2, { let len = a1.offset_from(a0) as usize; ::std::slice::from_raw_parts_mut(a0, len).sort_by(|x, y| { - if (a2)(*x, *y) { + if a2.call(*x, *y) { std::cmp::Ordering::Less - } else if (a2)(*y, *x) { + } else if a2.call(*y, *x) { std::cmp::Ordering::Greater } else { std::cmp::Ordering::Equal diff --git a/rules/cstdlib/tgt_refcount.rs b/rules/cstdlib/tgt_refcount.rs index 534d4472..db6d8d7d 100644 --- a/rules/cstdlib/tgt_refcount.rs +++ b/rules/cstdlib/tgt_refcount.rs @@ -50,7 +50,13 @@ fn f10(a0: Ptr, a1: Ptr) -> Ptr { } } -fn f8(a0: AnyPtr, a1: AnyPtr, a2: usize, a3: usize, a4: fn(AnyPtr, AnyPtr) -> i32) -> AnyPtr { +fn f8( + a0: AnyPtr, + a1: AnyPtr, + a2: usize, + a3: usize, + a4: FnPtr i32>, +) -> AnyPtr { let __base = a1.reinterpret_cast::(); let mut __lo: isize = 0; let mut __hi: isize = a2 as isize - 1; @@ -58,7 +64,7 @@ fn f8(a0: AnyPtr, a1: AnyPtr, a2: usize, a3: usize, a4: fn(AnyPtr, AnyPtr) -> i3 while __lo <= __hi && __found.is_null() { let __mid = __lo + (__hi - __lo) / 2; let __elem = __base.offset(__mid as usize * a3); - let __r = a4(a0.clone(), __elem.to_any()); + let __r = a4.call(a0.clone(), __elem.to_any()); if __r == 0 { __found = __elem.to_any(); } else if __r < 0 { @@ -70,12 +76,12 @@ fn f8(a0: AnyPtr, a1: AnyPtr, a2: usize, a3: usize, a4: fn(AnyPtr, AnyPtr) -> i3 __found } -fn f9(a0: AnyPtr, a1: usize, a2: usize, a3: fn(AnyPtr, AnyPtr) -> i32) { +fn f9(a0: AnyPtr, a1: usize, a2: usize, a3: FnPtr i32>) { let __base = a0.reinterpret_cast::(); for __i in 0..a1 { let mut __min = __i; for __j in (__i + 1)..a1 { - if a3( + if a3.call( __base.offset(__j * a2).to_any(), __base.offset(__min * a2).to_any(), ) < 0 diff --git a/rules/cstdlib/tgt_unsafe.rs b/rules/cstdlib/tgt_unsafe.rs index 5b983c43..9d0d0327 100644 --- a/rules/cstdlib/tgt_unsafe.rs +++ b/rules/cstdlib/tgt_unsafe.rs @@ -34,17 +34,19 @@ unsafe fn f8( a1: *const ::libc::c_void, a2: usize, a3: usize, - a4: unsafe fn(*const ::libc::c_void, *const ::libc::c_void) -> i32, + a4: Option i32>, ) -> *mut ::libc::c_void { libc::bsearch( a0, a1, a2, a3, - Some(std::mem::transmute::< - *const (), - unsafe extern "C" fn(*const ::libc::c_void, *const ::libc::c_void) -> i32, - >(a4 as *const ())), + a4.map(|__f| { + std::mem::transmute::< + *const (), + unsafe extern "C" fn(*const ::libc::c_void, *const ::libc::c_void) -> i32, + >(__f as *const ()) + }), ) } @@ -52,16 +54,18 @@ unsafe fn f9( a0: *mut ::libc::c_void, a1: usize, a2: usize, - a3: unsafe fn(*const ::libc::c_void, *const ::libc::c_void) -> i32, + a3: Option i32>, ) { libc::qsort( a0, a1, a2, - Some(std::mem::transmute::< - *const (), - unsafe extern "C" fn(*const ::libc::c_void, *const ::libc::c_void) -> i32, - >(a3 as *const ())), + a3.map(|__f| { + std::mem::transmute::< + *const (), + unsafe extern "C" fn(*const ::libc::c_void, *const ::libc::c_void) -> i32, + >(__f as *const ()) + }), ) } diff --git a/rules/rustls/tgt_unsafe.rs b/rules/rustls/tgt_unsafe.rs index db78cc47..59c3d3f1 100644 --- a/rules/rustls/tgt_unsafe.rs +++ b/rules/rustls/tgt_unsafe.rs @@ -433,13 +433,15 @@ unsafe fn f57(a0: u32) -> bool { unsafe fn f58( a0: *mut ::rustls_ffi::connection::rustls_connection, - a1: unsafe fn(*mut ::libc::c_void, *mut u8, u64, *mut u64) -> i32, + a1: Option i32>, a2: *mut ::libc::c_void, a3: *mut u64, ) -> i32 { ::rustls_ffi::connection::rustls_connection::rustls_connection_read_tls( a0, - std::mem::transmute::<*const (), ::rustls_ffi::io::rustls_read_callback>(a1 as *const ()), + std::mem::transmute::( + a1.map_or(0_usize, |__f| __f as usize), + ), a2, a3 as *mut usize, ) @@ -447,13 +449,15 @@ unsafe fn f58( } unsafe fn f59( a0: *mut ::rustls_ffi::connection::rustls_connection, - a1: unsafe fn(*mut ::libc::c_void, *const u8, u64, *mut u64) -> i32, + a1: Option i32>, a2: *mut ::libc::c_void, a3: *mut u64, ) -> i32 { ::rustls_ffi::connection::rustls_connection::rustls_connection_write_tls( a0, - std::mem::transmute::<*const (), ::rustls_ffi::io::rustls_write_callback>(a1 as *const ()), + std::mem::transmute::( + a1.map_or(0_usize, |__f| __f as usize), + ), a2, a3 as *mut usize, ) @@ -461,13 +465,15 @@ unsafe fn f59( } unsafe fn f60( a0: *mut ::rustls_ffi::client::rustls_client_config_builder, - a1: unsafe fn(::rustls_ffi::rslice::rustls_str<'static>, *const u8, u64, *const u8, u64), + a1: Option< + unsafe fn(::rustls_ffi::rslice::rustls_str<'static>, *const u8, u64, *const u8, u64), + >, a2: Option) -> i32>, ) -> ::rustls_ffi::rustls_result { ::rustls_ffi::client::rustls_client_config_builder::rustls_client_config_builder_set_key_log( a0, - std::mem::transmute::<*const (), ::rustls_ffi::keylog::rustls_keylog_log_callback>( - a1 as *const (), + std::mem::transmute::( + a1.map_or(0_usize, |__f| __f as usize), ), std::mem::transmute::< Option) -> i32>, @@ -477,15 +483,17 @@ unsafe fn f60( } unsafe fn f61( a0: *mut ::rustls_ffi::client::rustls_client_config_builder, - a1: unsafe fn( - *mut ::libc::c_void, - *const ::rustls_ffi::client::rustls_verify_server_cert_params<'static>, - ) -> ::rustls_ffi::rustls_result, + a1: Option< + unsafe fn( + *mut ::libc::c_void, + *const ::rustls_ffi::client::rustls_verify_server_cert_params<'static>, + ) -> ::rustls_ffi::rustls_result, + >, ) -> ::rustls_ffi::rustls_result { ::rustls_ffi::client::rustls_client_config_builder::rustls_client_config_builder_dangerous_set_certificate_verifier( a0, - std::mem::transmute::<*const (), ::rustls_ffi::client::rustls_verify_server_cert_callback>( - a1 as *const (), + std::mem::transmute::( + a1.map_or(0_usize, |__f| __f as usize), ), ) } From 3a7cbc4ea48f364b4826062c9c487449cb79d8dc Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Wed, 16 Sep 2026 13:44:15 +0100 Subject: [PATCH 3/9] Use fully qualified syntax for FnPtr::new --- cpp2rust/converter/models/converter_refcount.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index 8b6b7a19..e63e34be 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -2085,9 +2085,13 @@ std::string ConverterRefCount::ConvertVarInitValue(clang::QualType qual_type, Buffer buf(*this); PushConversionKind push(*this, ConversionKind::Unboxed); if (qual_type->isFunctionPointerType() && lambda->capture_size() == 0) { - StrCat("FnPtr::new("); + auto proto = lambda->getCallOperator() + ->getType() + ->getAs(); + StrCat( + std::format("FnPtr::<{}>::new", ConvertFunctionPointerType(proto))); + PushParen paren(*this); VisitLambdaExpr(lambda); - StrCat(')'); } else { VisitLambdaExpr(lambda); } From 8d5f2d12247f076745915055c4f93a6bbc0463b6 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Wed, 16 Sep 2026 13:44:42 +0100 Subject: [PATCH 4/9] Map types lazily --- cpp2rust/converter/mapper.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/cpp2rust/converter/mapper.cpp b/cpp2rust/converter/mapper.cpp index 4def2784..b5ad34e4 100644 --- a/cpp2rust/converter/mapper.cpp +++ b/cpp2rust/converter/mapper.cpp @@ -682,10 +682,9 @@ std::string InstantiateTemplate(const clang::Expr *expr, unsigned n) { if (!rule) { return text; } - for (auto &ty : subs) { - if (ty) { - ty = mapTypeStringRecursive(*ty); - } + auto &ty = subs.at(n - 1); + if (ty) { + ty = mapTypeStringRecursive(*ty); } return instantiateTgt(subs, text); } From 6eeeeb71ff7367ca6c34a3c8bbfbc27f60573801 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Wed, 16 Sep 2026 13:45:22 +0100 Subject: [PATCH 5/9] Convert casted type lazily --- cpp2rust/converter/converter.cpp | 14 ++++++++------ cpp2rust/converter/converter.h | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 99d7b036..a4aaa2ba 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -4607,7 +4607,7 @@ void Converter::PlaceholderCtx::dump() const { << ", declared_in_rule_as_rust_ptr: " << declared_in_rule_as_rust_ptr << ", access: " << static_cast(access) - << ", param_type: " << param_type + << ", arg_idx: " << arg_idx << ", materialize_idx: " << materialize_idx << '\n'; } @@ -4621,8 +4621,9 @@ std::string Converter::ConvertPlaceholder(clang::Expr *expr, clang::Expr *arg, } if (ph_ctx.declared_in_rule_as_rust_ptr && arg->getType()->isArrayType()) { - return std::format("({} as {})", ConvertFreshPointer(arg), - ph_ctx.param_type); + return std::format( + "({} as {})", ConvertFreshPointer(arg), + Mapper::GetParamType(GetCalleeOrExpr(expr), ph_ctx.arg_idx)); } if (ph_ctx.needs_materialization()) { @@ -4637,8 +4638,9 @@ std::string Converter::ConvertPlaceholder(clang::Expr *expr, clang::Expr *arg, } if (ph_ctx.needs_pointer_receiver()) { - return std::format("({} as {})", ConvertFreshObject(arg), - ph_ctx.param_type); + return std::format( + "({} as {})", ConvertFreshObject(arg), + Mapper::GetParamType(GetCalleeOrExpr(expr), ph_ctx.arg_idx)); } if (ph_ctx.needs_object_receiver()) { @@ -4717,7 +4719,7 @@ std::string Converter::ConvertIRFragment( bool is_receiver = HasReceiver(expr) && arg_idx == 0; PlaceholderCtx ph_ctx{ - .param_type = Mapper::GetParamType(GetCalleeOrExpr(expr), arg_idx), + .arg_idx = arg_idx, .implicit_convert_to = GetParamImplicitConvertTarget(expr, arg_idx), .materialize_ctx = ctx, .materialize_idx = diff --git a/cpp2rust/converter/converter.h b/cpp2rust/converter/converter.h index 6a4996cf..d735f75f 100644 --- a/cpp2rust/converter/converter.h +++ b/cpp2rust/converter/converter.h @@ -221,7 +221,7 @@ class Converter : public clang::RecursiveASTVisitor { }; struct PlaceholderCtx { - std::string param_type; + unsigned arg_idx; std::optional implicit_convert_to; TempMaterializationCtx *materialize_ctx; int materialize_idx; // <0 = no idx, >=0 idx valid From 2b7394a67559f78c2c4cb134097f5c06e68620d3 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Wed, 16 Sep 2026 13:48:51 +0100 Subject: [PATCH 6/9] Pass nullable function to rules --- cpp2rust/converter/converter.cpp | 55 +++++++++++++++++++------------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index a4aaa2ba..e9559524 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -1812,7 +1812,9 @@ void Converter::EmitFnPtrCall(clang::Expr *callee) { void Converter::ConvertFunctionToFunctionPointer( const clang::FunctionDecl *fn_decl) { - StrCat(std::format("Some({})", Mapper::MapFunctionName(fn_decl))); + auto proto = fn_decl->getType()->getAs(); + StrCat(std::format("Some({} as {} {})", Mapper::MapFunctionName(fn_decl), + keyword_unsafe_, ConvertFunctionPointerType(proto))); computed_expr_type_ = ComputedExprType::FreshPointer; } @@ -2407,6 +2409,12 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) { computed_expr_type_ = ComputedExprType::FreshPointer; break; default: + if (type->isFunctionPointerType() && + clang::isa( + sub_expr->IgnoreUnlessSpelledInSource())) { + ConvertVarInit(type, sub_expr); + break; + } if (auto *literal = clang::dyn_cast(sub_expr)) { auto type = expr->getType(); StrCat(getIntegerLiteral(literal, true, &type)); @@ -3589,21 +3597,31 @@ bool Converter::VisitConstantExpr(clang::ConstantExpr *expr) { } bool Converter::VisitLambdaExpr(clang::LambdaExpr *expr) { - if (isAddrOf() && expr->capture_size() == 0) { - StrCat("Some"); + bool to_fn_ptr = isAddrOf() && expr->capture_size() == 0; + if (to_fn_ptr) { + StrCat("Some("); + } + { + PushParen paren(*this); + StrCat('|'); + for (auto p : + expr->getLambdaClass()->getLambdaCallOperator()->parameters()) { + StrCat(GetNamedDeclAsString(p), token::kColon, ToString(p->getType()), + token::kComma); + } + StrCat("| {"); + EmitFunctionPreamble(expr->getLambdaClass()->getLambdaCallOperator()); + PushCurrFunction push_fn(*this, + expr->getLambdaClass()->getLambdaCallOperator()); + ConvertFunctionBody(curr_function_); + StrCat('}'); + } + if (to_fn_ptr) { + auto proto = + expr->getCallOperator()->getType()->getAs(); + StrCat(std::format(" as {} {})", keyword_unsafe_, + ConvertFunctionPointerType(proto))); } - PushParen paren(*this); - StrCat('|'); - for (auto p : expr->getLambdaClass()->getLambdaCallOperator()->parameters()) { - StrCat(GetNamedDeclAsString(p), token::kColon, ToString(p->getType()), - token::kComma); - } - StrCat("| {"); - EmitFunctionPreamble(expr->getLambdaClass()->getLambdaCallOperator()); - PushCurrFunction push_fn(*this, - expr->getLambdaClass()->getLambdaCallOperator()); - ConvertFunctionBody(curr_function_); - StrCat('}'); return false; } @@ -4613,13 +4631,6 @@ void Converter::PlaceholderCtx::dump() const { std::string Converter::ConvertPlaceholder(clang::Expr *expr, clang::Expr *arg, const PlaceholderCtx &ph_ctx) { - if (arg->getType()->isFunctionPointerType()) { - PushExprKind push(*this, ExprKind::Callee); - Buffer buf(*this); - Convert(arg); - return std::move(buf).str(); - } - if (ph_ctx.declared_in_rule_as_rust_ptr && arg->getType()->isArrayType()) { return std::format( "({} as {})", ConvertFreshPointer(arg), From 2bc199ea4cedd2a3d916e468bfa192512130c220 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Wed, 16 Sep 2026 14:09:53 +0100 Subject: [PATCH 7/9] Update tests --- tests/unit/out/refcount/fn_ptr_default_arg.rs | 2 +- tests/unit/out/refcount/fn_ptr_stable_sort.rs | 2 +- tests/unit/out/refcount/qsort_bsearch.rs | 6 +-- tests/unit/out/refcount/stable_sort.rs | 3 +- tests/unit/out/unsafe/fn_ptr.rs | 6 +-- tests/unit/out/unsafe/fn_ptr_arity.rs | 20 +++++++- tests/unit/out/unsafe/fn_ptr_array.rs | 10 ++-- tests/unit/out/unsafe/fn_ptr_as_condition.rs | 9 +++- tests/unit/out/unsafe/fn_ptr_cast.rs | 15 +++--- tests/unit/out/unsafe/fn_ptr_conditional.rs | 10 ++-- tests/unit/out/unsafe/fn_ptr_default_arg.rs | 10 ++-- tests/unit/out/unsafe/fn_ptr_global.rs | 8 ++-- tests/unit/out/unsafe/fn_ptr_reassign.rs | 8 ++-- tests/unit/out/unsafe/fn_ptr_return.rs | 8 ++-- tests/unit/out/unsafe/fn_ptr_stable_sort.rs | 8 +++- .../unit/out/unsafe/fn_ptr_stdlib_compare.rs | 46 +++++++++++++++---- tests/unit/out/unsafe/fn_ptr_struct.rs | 6 +-- tests/unit/out/unsafe/fn_ptr_void_return.rs | 11 +++-- tests/unit/out/unsafe/fn_ptr_vtable.rs | 6 +-- tests/unit/out/unsafe/malloc_realloc_free.rs | 12 +++-- tests/unit/out/unsafe/no_direct_callee.rs | 2 +- tests/unit/out/unsafe/qsort_bsearch.rs | 36 ++++++++++----- tests/unit/out/unsafe/stable_sort.rs | 6 ++- .../out/unsafe/string_literal_ptr_init.rs | 2 +- tests/unit/out/unsafe/va_arg_fn_ptr.rs | 23 ++++------ tests/unit/out/unsafe/void_cast.rs | 4 +- 26 files changed, 181 insertions(+), 98 deletions(-) diff --git a/tests/unit/out/refcount/fn_ptr_default_arg.rs b/tests/unit/out/refcount/fn_ptr_default_arg.rs index 0348fc82..4a0d282c 100644 --- a/tests/unit/out/refcount/fn_ptr_default_arg.rs +++ b/tests/unit/out/refcount/fn_ptr_default_arg.rs @@ -26,7 +26,7 @@ fn main_0() -> i32 { assert!((({ apply_1(5, None,) }) == 5)); assert!((({ apply_1(5, Some(FnPtr:: i32>::null()),) }) == 5)); assert!((({ apply_1(5, Some(FnPtr:: i32>::new(identity_0)),) }) == 5)); - let negate: Value i32>> = Rc::new(RefCell::new(FnPtr::new( + let negate: Value i32>> = Rc::new(RefCell::new(FnPtr:: i32>::new( (|x: i32| { let x: Value = Rc::new(RefCell::new(x)); return -(*x.borrow()); diff --git a/tests/unit/out/refcount/fn_ptr_stable_sort.rs b/tests/unit/out/refcount/fn_ptr_stable_sort.rs index be45ffe6..d294121b 100644 --- a/tests/unit/out/refcount/fn_ptr_stable_sort.rs +++ b/tests/unit/out/refcount/fn_ptr_stable_sort.rs @@ -61,7 +61,7 @@ fn main_0() -> i32 { }); (v.as_pointer() as Ptr).sort_with_cmp( (v.as_pointer() as Ptr).to_end().get_offset(), - Compare_0, + |x, y| FnPtr::, Ptr) -> bool>::new(Compare_0).call(x, y), ); assert!( ((*(*(v.as_pointer() as Ptr) diff --git a/tests/unit/out/refcount/qsort_bsearch.rs b/tests/unit/out/refcount/qsort_bsearch.rs index d53ecb1d..c200ac0c 100644 --- a/tests/unit/out/refcount/qsort_bsearch.rs +++ b/tests/unit/out/refcount/qsort_bsearch.rs @@ -29,7 +29,7 @@ fn main_0() -> i32 { for __i in 0..8_usize { let mut __min = __i; for __j in (__i + 1)..8_usize { - if cmp_int_0( + if FnPtr:: i32>::new(cmp_int_0).call( __base.offset(__j * ::std::mem::size_of::()).to_any(), __base.offset(__min * ::std::mem::size_of::()).to_any(), ) < 0 @@ -76,7 +76,7 @@ fn main_0() -> i32 { while __lo <= __hi && __found.is_null() { let __mid = __lo + (__hi - __lo) / 2; let __elem = __base.offset(__mid as usize * ::std::mem::size_of::()); - let __r = cmp_int_0( + let __r = FnPtr:: i32>::new(cmp_int_0).call( ((key.as_pointer()) as Ptr).to_any().clone(), __elem.to_any(), ); @@ -106,7 +106,7 @@ fn main_0() -> i32 { while __lo <= __hi && __found.is_null() { let __mid = __lo + (__hi - __lo) / 2; let __elem = __base.offset(__mid as usize * ::std::mem::size_of::()); - let __r = cmp_int_0( + let __r = FnPtr:: i32>::new(cmp_int_0).call( ((miss_key.as_pointer()) as Ptr).to_any().clone(), __elem.to_any(), ); diff --git a/tests/unit/out/refcount/stable_sort.rs b/tests/unit/out/refcount/stable_sort.rs index 5da4a391..784fbf00 100644 --- a/tests/unit/out/refcount/stable_sort.rs +++ b/tests/unit/out/refcount/stable_sort.rs @@ -17,7 +17,8 @@ fn main_0() -> i32 { let x: Value = Rc::new(RefCell::new(x)); let y: Value = Rc::new(RefCell::new(y)); return ((*x.borrow()) < (*y.borrow())); - })((x.read()).clone(), (y.read()).clone()) + }) + .call((x.read()).clone(), (y.read()).clone()) }; (arr1.as_pointer() as Ptr).sort_with_cmp( (arr1.as_pointer() as Ptr) diff --git a/tests/unit/out/unsafe/fn_ptr.rs b/tests/unit/out/unsafe/fn_ptr.rs index dcaacdaf..6faa1392 100644 --- a/tests/unit/out/unsafe/fn_ptr.rs +++ b/tests/unit/out/unsafe/fn_ptr.rs @@ -23,10 +23,10 @@ pub fn main() { unsafe fn main_0() -> i32 { let mut fn_: Option i32> = None; assert!((fn_).is_none()); - assert!(((fn_) != (Some(my_foo_0)))); - fn_ = Some(my_foo_0); + assert!(((fn_) != (Some(my_foo_0 as unsafe fn(*mut ::libc::c_void) -> i32)))); + fn_ = Some(my_foo_0 as unsafe fn(*mut ::libc::c_void) -> i32); assert!(!((fn_).is_none())); - assert!(((fn_) == (Some(my_foo_0)))); + assert!(((fn_) == (Some(my_foo_0 as unsafe fn(*mut ::libc::c_void) -> i32)))); let mut a: i32 = 10; assert!(((unsafe { foo_1(fn_, (&mut a as *mut i32),) }) == (a))); return 0; diff --git a/tests/unit/out/unsafe/fn_ptr_arity.rs b/tests/unit/out/unsafe/fn_ptr_arity.rs index 912c17c4..d92ca088 100644 --- a/tests/unit/out/unsafe/fn_ptr_arity.rs +++ b/tests/unit/out/unsafe/fn_ptr_arity.rs @@ -32,7 +32,25 @@ pub fn main() { unsafe fn main_0() -> i32 { let mut f: Option< unsafe fn(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) -> i32, - > = (Some(foo_0)); + > = (Some( + foo_0 + as unsafe fn( + i32, + i32, + i32, + i32, + i32, + i32, + i32, + i32, + i32, + i32, + i32, + i32, + i32, + i32, + ) -> i32, + )); assert!(((unsafe { (f).unwrap()(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,) }) == (22))); return 0; } diff --git a/tests/unit/out/unsafe/fn_ptr_array.rs b/tests/unit/out/unsafe/fn_ptr_array.rs index c41968b9..6f37ac66 100644 --- a/tests/unit/out/unsafe/fn_ptr_array.rs +++ b/tests/unit/out/unsafe/fn_ptr_array.rs @@ -21,12 +21,16 @@ pub fn main() { } } unsafe fn main_0() -> i32 { - let mut ops: [Option i32>; 3] = [Some(add_0), Some(sub_1), Some(mul_2)]; + let mut ops: [Option i32>; 3] = [ + Some(add_0 as unsafe fn(i32, i32) -> i32), + Some(sub_1 as unsafe fn(i32, i32) -> i32), + Some(mul_2 as unsafe fn(i32, i32) -> i32), + ]; assert!(((unsafe { (ops[(0) as usize]).unwrap()(2, 3,) }) == (5))); assert!(((unsafe { (ops[(1) as usize]).unwrap()(7, 4,) }) == (3))); assert!(((unsafe { (ops[(2) as usize]).unwrap()(6, 5,) }) == (30))); assert!(!((ops[(0) as usize]).is_none())); - assert!(((ops[(0) as usize]) == (Some(add_0)))); - assert!(((ops[(0) as usize]) != (Some(sub_1)))); + assert!(((ops[(0) as usize]) == (Some(add_0 as unsafe fn(i32, i32) -> i32)))); + assert!(((ops[(0) as usize]) != (Some(sub_1 as unsafe fn(i32, i32) -> i32)))); return 0; } diff --git a/tests/unit/out/unsafe/fn_ptr_as_condition.rs b/tests/unit/out/unsafe/fn_ptr_as_condition.rs index e4d6574c..8ca0d487 100644 --- a/tests/unit/out/unsafe/fn_ptr_as_condition.rs +++ b/tests/unit/out/unsafe/fn_ptr_as_condition.rs @@ -21,14 +21,19 @@ pub fn main() { } unsafe fn main_0() -> i32 { let mut a: i32 = 5; - (unsafe { maybe_call_1(Some(double_it_0), (&mut a as *mut i32)) }); + (unsafe { + maybe_call_1( + Some(double_it_0 as unsafe fn(*mut i32)), + (&mut a as *mut i32), + ) + }); assert!(((a) == (10))); let mut b: i32 = 5; (unsafe { maybe_call_1(None, (&mut b as *mut i32)) }); assert!(((b) == (5))); let mut fn_: Option = None; if !(!(fn_).is_none()) { - fn_ = Some(double_it_0); + fn_ = Some(double_it_0 as unsafe fn(*mut i32)); } let mut c: i32 = 3; if !(fn_).is_none() { diff --git a/tests/unit/out/unsafe/fn_ptr_cast.rs b/tests/unit/out/unsafe/fn_ptr_cast.rs index 014c5387..64aafc26 100644 --- a/tests/unit/out/unsafe/fn_ptr_cast.rs +++ b/tests/unit/out/unsafe/fn_ptr_cast.rs @@ -10,7 +10,7 @@ pub unsafe fn double_it_0(mut x: i32) -> i32 { return ((x) * (2)); } pub unsafe fn test_roundtrip_1() { - let mut fn_: Option i32> = Some(double_it_0); + let mut fn_: Option i32> = Some(double_it_0 as unsafe fn(i32) -> i32); assert!(((unsafe { (fn_).unwrap()(5,) }) == (10))); let mut gfn: Option = std::mem::transmute:: i32>, Option>(fn_); @@ -21,7 +21,7 @@ pub unsafe fn test_roundtrip_1() { assert!(((fn2) == (fn_))); } pub unsafe fn test_double_cast_2() { - let mut fn_: Option i32> = Some(double_it_0); + let mut fn_: Option i32> = Some(double_it_0 as unsafe fn(i32) -> i32); let mut fn2: Option i32> = std::mem::transmute::, Option i32>>( std::mem::transmute:: i32>, Option>(fn_), @@ -37,7 +37,7 @@ pub struct Command { pub unsafe fn test_void_ptr_to_fn_3() { let mut cmd: Command = ::default(); cmd.data = std::mem::transmute:: i32>, *mut ::libc::c_void>(Some( - double_it_0, + double_it_0 as unsafe fn(i32) -> i32, )); let mut fn_: Option i32> = std::mem::transmute::<*mut ::libc::c_void, Option i32>>(cmd.data); @@ -47,10 +47,11 @@ pub unsafe fn add_offset_4(mut base: *mut i32, mut offset: i32) -> i32 { return ((*base) + (offset)); } pub unsafe fn test_call_through_cast_5() { - let mut gfn: Option i32> = std::mem::transmute::< - Option i32>, - Option i32>, - >(Some(add_offset_4)); + let mut gfn: Option i32> = + std::mem::transmute::< + Option i32>, + Option i32>, + >(Some(add_offset_4 as unsafe fn(*mut i32, i32) -> i32)); let mut val: i32 = 100; let mut result: i32 = (unsafe { (gfn).unwrap()( diff --git a/tests/unit/out/unsafe/fn_ptr_conditional.rs b/tests/unit/out/unsafe/fn_ptr_conditional.rs index 1e8d5e9f..d8927b07 100644 --- a/tests/unit/out/unsafe/fn_ptr_conditional.rs +++ b/tests/unit/out/unsafe/fn_ptr_conditional.rs @@ -17,12 +17,12 @@ pub unsafe fn identity_2(mut x: i32) -> i32 { } pub unsafe fn pick_3(mut mode: i32) -> Option i32> { return if ((mode) > (0)) { - Some(inc_0) + Some(inc_0 as unsafe fn(i32) -> i32) } else { if ((mode) < (0)) { - Some(dec_1) + Some(dec_1 as unsafe fn(i32) -> i32) } else { - Some(identity_2) + Some(identity_2 as unsafe fn(i32) -> i32) } }; } @@ -30,7 +30,7 @@ pub unsafe fn apply_4(mut fn_: Option i32>, mut x: i32) -> i32 let mut actual: Option i32> = if !(fn_).is_none() { fn_ } else { - Some(identity_2) + Some(identity_2 as unsafe fn(i32) -> i32) }; return (unsafe { (actual).unwrap()(x) }); } @@ -43,7 +43,7 @@ unsafe fn main_0() -> i32 { assert!(((unsafe { (unsafe { pick_3(1,) }).unwrap()(10,) }) == (11))); assert!(((unsafe { (unsafe { pick_3(-1_i32,) }).unwrap()(10,) }) == (9))); assert!(((unsafe { (unsafe { pick_3(0,) }).unwrap()(10,) }) == (10))); - assert!(((unsafe { apply_4(Some(inc_0), 5,) }) == (6))); + assert!(((unsafe { apply_4(Some(inc_0 as unsafe fn(i32) -> i32), 5,) }) == (6))); assert!(((unsafe { apply_4(None, 5,) }) == (5))); return 0; } diff --git a/tests/unit/out/unsafe/fn_ptr_default_arg.rs b/tests/unit/out/unsafe/fn_ptr_default_arg.rs index 43d6ddab..0ff33bdb 100644 --- a/tests/unit/out/unsafe/fn_ptr_default_arg.rs +++ b/tests/unit/out/unsafe/fn_ptr_default_arg.rs @@ -24,10 +24,12 @@ pub fn main() { unsafe fn main_0() -> i32 { assert!(((unsafe { apply_1(5, None,) }) == (5))); assert!(((unsafe { apply_1(5, Some(None),) }) == (5))); - assert!(((unsafe { apply_1(5, Some(Some(identity_0)),) }) == (5))); - let mut negate: Option i32> = Some(|x: i32| { - return -x; - }); + assert!(((unsafe { apply_1(5, Some(Some(identity_0 as unsafe fn(i32) -> i32)),) }) == (5))); + let mut negate: Option i32> = Some( + (|x: i32| { + return -x; + }) as unsafe fn(i32) -> i32, + ); assert!(((unsafe { apply_1(5, Some(negate),) }) == (-5_i32))); return 0; } diff --git a/tests/unit/out/unsafe/fn_ptr_global.rs b/tests/unit/out/unsafe/fn_ptr_global.rs index 5cca8fd5..bfb228f0 100644 --- a/tests/unit/out/unsafe/fn_ptr_global.rs +++ b/tests/unit/out/unsafe/fn_ptr_global.rs @@ -29,12 +29,12 @@ pub fn main() { } unsafe fn main_0() -> i32 { assert!(((unsafe { call_op_4(5,) }) == (5))); - (unsafe { set_op_3(Some(double_it_0)) }); + (unsafe { set_op_3(Some(double_it_0 as unsafe fn(i32) -> i32)) }); assert!(!((g_op_2).is_none())); - assert!(((g_op_2) == (Some(double_it_0)))); + assert!(((g_op_2) == (Some(double_it_0 as unsafe fn(i32) -> i32)))); assert!(((unsafe { call_op_4(5,) }) == (10))); - (unsafe { set_op_3(Some(triple_it_1)) }); - assert!(((g_op_2) == (Some(triple_it_1)))); + (unsafe { set_op_3(Some(triple_it_1 as unsafe fn(i32) -> i32)) }); + assert!(((g_op_2) == (Some(triple_it_1 as unsafe fn(i32) -> i32)))); assert!(((unsafe { call_op_4(5,) }) == (15))); (unsafe { set_op_3(None) }); assert!((g_op_2).is_none()); diff --git a/tests/unit/out/unsafe/fn_ptr_reassign.rs b/tests/unit/out/unsafe/fn_ptr_reassign.rs index 4c8b0e3f..0fa0ce9b 100644 --- a/tests/unit/out/unsafe/fn_ptr_reassign.rs +++ b/tests/unit/out/unsafe/fn_ptr_reassign.rs @@ -21,15 +21,15 @@ pub fn main() { } } unsafe fn main_0() -> i32 { - let mut fn_: Option i32> = Some(add_0); + let mut fn_: Option i32> = Some(add_0 as unsafe fn(i32, i32) -> i32); assert!(((unsafe { (fn_).unwrap()(3, 4,) }) == (7))); - fn_ = Some(sub_1); + fn_ = Some(sub_1 as unsafe fn(i32, i32) -> i32); assert!(((unsafe { (fn_).unwrap()(10, 3,) }) == (7))); - fn_ = Some(mul_2); + fn_ = Some(mul_2 as unsafe fn(i32, i32) -> i32); assert!(((unsafe { (fn_).unwrap()(6, 7,) }) == (42))); fn_ = None; assert!((fn_).is_none()); - fn_ = Some(add_0); + fn_ = Some(add_0 as unsafe fn(i32, i32) -> i32); assert!(!((fn_).is_none())); assert!(((unsafe { (fn_).unwrap()(1, 1,) }) == (2))); return 0; diff --git a/tests/unit/out/unsafe/fn_ptr_return.rs b/tests/unit/out/unsafe/fn_ptr_return.rs index 5f3b8ec7..f2114159 100644 --- a/tests/unit/out/unsafe/fn_ptr_return.rs +++ b/tests/unit/out/unsafe/fn_ptr_return.rs @@ -14,9 +14,9 @@ pub unsafe fn dec_1(mut x: i32) -> i32 { } pub unsafe fn pick_2(mut choose_inc: i32) -> Option i32> { if (choose_inc != 0) { - return Some(inc_0); + return Some(inc_0 as unsafe fn(i32) -> i32); } - return Some(dec_1); + return Some(dec_1 as unsafe fn(i32) -> i32); } pub fn main() { unsafe { @@ -26,10 +26,10 @@ pub fn main() { unsafe fn main_0() -> i32 { let mut f: Option i32> = (unsafe { pick_2(1) }); assert!(!((f).is_none())); - assert!(((f) == (Some(inc_0)))); + assert!(((f) == (Some(inc_0 as unsafe fn(i32) -> i32)))); assert!(((unsafe { (f).unwrap()(10,) }) == (11))); let mut g: Option i32> = (unsafe { pick_2(0) }); - assert!(((g) == (Some(dec_1)))); + assert!(((g) == (Some(dec_1 as unsafe fn(i32) -> i32)))); assert!(((unsafe { (g).unwrap()(10,) }) == (9))); assert!(((f) != (g))); return 0; diff --git a/tests/unit/out/unsafe/fn_ptr_stable_sort.rs b/tests/unit/out/unsafe/fn_ptr_stable_sort.rs index a0fd886a..b466017a 100644 --- a/tests/unit/out/unsafe/fn_ptr_stable_sort.rs +++ b/tests/unit/out/unsafe/fn_ptr_stable_sort.rs @@ -28,9 +28,13 @@ unsafe fn main_0() -> i32 { { let len = v.as_mut_ptr().add(v.len()).offset_from(v.as_mut_ptr()) as usize; ::std::slice::from_raw_parts_mut(v.as_mut_ptr(), len).sort_by(|x, y| { - if (Compare_0)(x, y) { + if Some(Compare_0 as unsafe fn(*const Item, *const Item) -> bool) + .call(x as *const _, y as *const _) + { std::cmp::Ordering::Less - } else if (Compare_0)(y, x) { + } else if Some(Compare_0 as unsafe fn(*const Item, *const Item) -> bool) + .call(y as *const _, x as *const _) + { std::cmp::Ordering::Greater } else { std::cmp::Ordering::Equal diff --git a/tests/unit/out/unsafe/fn_ptr_stdlib_compare.rs b/tests/unit/out/unsafe/fn_ptr_stdlib_compare.rs index f4601563..dbe1e1d0 100644 --- a/tests/unit/out/unsafe/fn_ptr_stdlib_compare.rs +++ b/tests/unit/out/unsafe/fn_ptr_stdlib_compare.rs @@ -29,14 +29,26 @@ pub fn main() { } unsafe fn main_0() -> i32 { let mut fn1: Option usize> = - Some(libcc2rs::fread_unsafe); - assert!(((fn1) == (Some(libcc2rs::fread_unsafe)))); + Some( + libcc2rs::fread_unsafe + as unsafe fn(*mut ::libc::c_void, usize, usize, *mut ::libc::FILE) -> usize, + ); + assert!( + ((fn1) + == (Some( + libcc2rs::fread_unsafe + as unsafe fn(*mut ::libc::c_void, usize, usize, *mut ::libc::FILE) -> usize + ))) + ); assert!(!((fn1).is_none())); let mut fn2: Option usize> = std::mem::transmute::< Option usize>, Option usize>, - >(Some(libcc2rs::fread_unsafe)); + >(Some( + libcc2rs::fread_unsafe + as unsafe fn(*mut ::libc::c_void, usize, usize, *mut ::libc::FILE) -> usize, + )); assert!( ((fn1) == (std::mem::transmute::< @@ -48,7 +60,10 @@ unsafe fn main_0() -> i32 { std::mem::transmute::< Option usize>, Option usize>, - >(Some(my_alternative_fread_0)); + >(Some( + my_alternative_fread_0 + as unsafe fn(*mut libc::c_char, usize, usize, *mut ::libc::c_void) -> usize, + )); assert!( ((unsafe { (f3).unwrap()(std::ptr::null_mut(), 0_usize, 0_usize, std::ptr::null_mut(),) }) == (22_usize)) @@ -121,15 +136,27 @@ unsafe fn main_0() -> i32 { } let mut gn1: Option< unsafe fn(*const ::libc::c_void, usize, usize, *mut ::libc::FILE) -> usize, - > = Some(libcc2rs::fwrite_unsafe); - assert!(((gn1) == (Some(libcc2rs::fwrite_unsafe)))); + > = Some( + libcc2rs::fwrite_unsafe + as unsafe fn(*const ::libc::c_void, usize, usize, *mut ::libc::FILE) -> usize, + ); + assert!( + ((gn1) + == (Some( + libcc2rs::fwrite_unsafe + as unsafe fn(*const ::libc::c_void, usize, usize, *mut ::libc::FILE) -> usize + ))) + ); assert!(!((gn1).is_none())); let mut gn2: Option< unsafe fn(*const libc::c_char, usize, usize, *mut ::libc::c_void) -> usize, > = std::mem::transmute::< Option usize>, Option usize>, - >(Some(libcc2rs::fwrite_unsafe)); + >(Some( + libcc2rs::fwrite_unsafe + as unsafe fn(*const ::libc::c_void, usize, usize, *mut ::libc::FILE) -> usize, + )); assert!( ((gn1) == (std::mem::transmute::< @@ -141,7 +168,10 @@ unsafe fn main_0() -> i32 { std::mem::transmute::< Option usize>, Option usize>, - >(Some(my_alternative_fwrite_1)); + >(Some( + my_alternative_fwrite_1 + as unsafe fn(*const libc::c_char, usize, usize, *mut ::libc::c_void) -> usize, + )); assert!( ((unsafe { (g3).unwrap()(std::ptr::null(), 0_usize, 0_usize, std::ptr::null_mut(),) }) == (33_usize)) diff --git a/tests/unit/out/unsafe/fn_ptr_struct.rs b/tests/unit/out/unsafe/fn_ptr_struct.rs index c8480075..26d4b33d 100644 --- a/tests/unit/out/unsafe/fn_ptr_struct.rs +++ b/tests/unit/out/unsafe/fn_ptr_struct.rs @@ -34,16 +34,16 @@ pub fn main() { unsafe fn main_0() -> i32 { let mut h1: Handler = Handler { tag: 1, - cb: Some(double_it_0), + cb: Some(double_it_0 as unsafe fn(i32) -> i32), }; let mut h2: Handler = Handler { tag: 2, - cb: Some(negate_1), + cb: Some(negate_1 as unsafe fn(i32) -> i32), }; assert!(!((h1.cb).is_none())); assert!(((unsafe { (h1.cb).unwrap()(5,) }) == (10))); assert!(((unsafe { (h2.cb).unwrap()(7,) }) == (-7_i32))); - (h1.cb) = Some(negate_1); + (h1.cb) = Some(negate_1 as unsafe fn(i32) -> i32); assert!(((unsafe { (h1.cb).unwrap()(3,) }) == (-3_i32))); assert!(((h1.cb) == (h2.cb))); return 0; diff --git a/tests/unit/out/unsafe/fn_ptr_void_return.rs b/tests/unit/out/unsafe/fn_ptr_void_return.rs index 4a98d7f1..83f75ce1 100644 --- a/tests/unit/out/unsafe/fn_ptr_void_return.rs +++ b/tests/unit/out/unsafe/fn_ptr_void_return.rs @@ -22,11 +22,16 @@ pub fn main() { } unsafe fn main_0() -> i32 { let mut a: i32 = 42; - (unsafe { run_2(Some(negate_0), (&mut a as *mut i32)) }); + (unsafe { run_2(Some(negate_0 as unsafe fn(*mut i32)), (&mut a as *mut i32)) }); assert!(((a) == (-42_i32))); - (unsafe { run_2(Some(zero_out_1), (&mut a as *mut i32)) }); + (unsafe { + run_2( + Some(zero_out_1 as unsafe fn(*mut i32)), + (&mut a as *mut i32), + ) + }); assert!(((a) == (0))); - let mut fn_: Option = Some(negate_0); + let mut fn_: Option = Some(negate_0 as unsafe fn(*mut i32)); assert!(!((fn_).is_none())); let mut b: i32 = 10; (unsafe { (fn_).unwrap()((&mut b as *mut i32)) }); diff --git a/tests/unit/out/unsafe/fn_ptr_vtable.rs b/tests/unit/out/unsafe/fn_ptr_vtable.rs index 5eff7364..97fcb1e6 100644 --- a/tests/unit/out/unsafe/fn_ptr_vtable.rs +++ b/tests/unit/out/unsafe/fn_ptr_vtable.rs @@ -40,9 +40,9 @@ pub fn main() { } unsafe fn main_0() -> i32 { let mut vt: Vtable = Vtable { - create: Some(int_create_1), - get: Some(int_get_2), - destroy: Some(int_destroy_3), + create: Some(int_create_1 as unsafe fn(i32) -> *mut ::libc::c_void), + get: Some(int_get_2 as unsafe fn(*mut ::libc::c_void) -> i32), + destroy: Some(int_destroy_3 as unsafe fn(*mut ::libc::c_void)), }; assert!(!((vt.create).is_none())); assert!(!((vt.get).is_none())); diff --git a/tests/unit/out/unsafe/malloc_realloc_free.rs b/tests/unit/out/unsafe/malloc_realloc_free.rs index 588a7219..ec25809c 100644 --- a/tests/unit/out/unsafe/malloc_realloc_free.rs +++ b/tests/unit/out/unsafe/malloc_realloc_free.rs @@ -56,12 +56,14 @@ unsafe fn main_0() -> i32 { libcc2rs::free_unsafe((zeros as *mut i32 as *mut ::libc::c_void)); } let mut pmalloc: Option *mut ::libc::c_void> = - Some(libcc2rs::malloc_unsafe); - let mut pfree: Option = Some(libcc2rs::free_unsafe); - let mut prealloc: Option *mut ::libc::c_void> = - Some(libcc2rs::realloc_unsafe); + Some(libcc2rs::malloc_unsafe as unsafe fn(usize) -> *mut ::libc::c_void); + let mut pfree: Option = + Some(libcc2rs::free_unsafe as unsafe fn(*mut ::libc::c_void)); + let mut prealloc: Option *mut ::libc::c_void> = Some( + libcc2rs::realloc_unsafe as unsafe fn(*mut ::libc::c_void, usize) -> *mut ::libc::c_void, + ); let mut pcalloc: Option *mut ::libc::c_void> = - Some(libcc2rs::calloc_unsafe); + Some(libcc2rs::calloc_unsafe as unsafe fn(usize, usize) -> *mut ::libc::c_void); let mut __do_while = true; 'loop_: while __do_while || (0 != 0) { __do_while = false; diff --git a/tests/unit/out/unsafe/no_direct_callee.rs b/tests/unit/out/unsafe/no_direct_callee.rs index 311d4c17..143e065e 100644 --- a/tests/unit/out/unsafe/no_direct_callee.rs +++ b/tests/unit/out/unsafe/no_direct_callee.rs @@ -21,6 +21,6 @@ pub fn main() { } } unsafe fn main_0() -> i32 { - assert!(((unsafe { test_1(Some(test1_0),) }) == (1))); + assert!(((unsafe { test_1(Some(test1_0 as unsafe fn() -> bool),) }) == (1))); return 0; } diff --git a/tests/unit/out/unsafe/qsort_bsearch.rs b/tests/unit/out/unsafe/qsort_bsearch.rs index 2a1ff8a6..d1c9ea7b 100644 --- a/tests/unit/out/unsafe/qsort_bsearch.rs +++ b/tests/unit/out/unsafe/qsort_bsearch.rs @@ -22,10 +22,14 @@ unsafe fn main_0() -> i32 { (arr.as_mut_ptr() as *mut i32 as *mut ::libc::c_void), 8_usize, ::std::mem::size_of::(), - Some(std::mem::transmute::< - *const (), - unsafe extern "C" fn(*const ::libc::c_void, *const ::libc::c_void) -> i32, - >(cmp_int_0 as *const ())), + Some(cmp_int_0 as unsafe fn(*const ::libc::c_void, *const ::libc::c_void) -> i32).map( + |__f| { + std::mem::transmute::< + *const (), + unsafe extern "C" fn(*const ::libc::c_void, *const ::libc::c_void) -> i32, + >(__f as *const ()) + }, + ), ); let mut i: i32 = 0; 'loop_: while ((((i) < (7)) as i32) != 0) { @@ -38,10 +42,14 @@ unsafe fn main_0() -> i32 { (arr.as_mut_ptr() as *const i32 as *const ::libc::c_void), 8_usize, ::std::mem::size_of::(), - Some(std::mem::transmute::< - *const (), - unsafe extern "C" fn(*const ::libc::c_void, *const ::libc::c_void) -> i32, - >(cmp_int_0 as *const ())), + Some(cmp_int_0 as unsafe fn(*const ::libc::c_void, *const ::libc::c_void) -> i32).map( + |__f| { + std::mem::transmute::< + *const (), + unsafe extern "C" fn(*const ::libc::c_void, *const ::libc::c_void) -> i32, + >(__f as *const ()) + }, + ), ) as *mut i32); assert!((((!((hit).is_null())) as i32) != 0)); assert!(((((*hit) == (7)) as i32) != 0)); @@ -51,10 +59,14 @@ unsafe fn main_0() -> i32 { (arr.as_mut_ptr() as *const i32 as *const ::libc::c_void), 8_usize, ::std::mem::size_of::(), - Some(std::mem::transmute::< - *const (), - unsafe extern "C" fn(*const ::libc::c_void, *const ::libc::c_void) -> i32, - >(cmp_int_0 as *const ())), + Some(cmp_int_0 as unsafe fn(*const ::libc::c_void, *const ::libc::c_void) -> i32).map( + |__f| { + std::mem::transmute::< + *const (), + unsafe extern "C" fn(*const ::libc::c_void, *const ::libc::c_void) -> i32, + >(__f as *const ()) + }, + ), ) as *mut i32); assert!(((((miss).is_null()) as i32) != 0)); return 0; diff --git a/tests/unit/out/unsafe/stable_sort.rs b/tests/unit/out/unsafe/stable_sort.rs index 7427395a..da3cd9de 100644 --- a/tests/unit/out/unsafe/stable_sort.rs +++ b/tests/unit/out/unsafe/stable_sort.rs @@ -21,12 +21,14 @@ unsafe fn main_0() -> i32 { ::std::slice::from_raw_parts_mut(arr1.as_mut_ptr(), len).sort_by(|x, y| { if (|x: i32, y: i32| { return ((x) < (y)); - })(*x, *y) + }) + .call(*x, *y) { std::cmp::Ordering::Less } else if (|x: i32, y: i32| { return ((x) < (y)); - })(*y, *x) + }) + .call(*y, *x) { std::cmp::Ordering::Greater } else { diff --git a/tests/unit/out/unsafe/string_literal_ptr_init.rs b/tests/unit/out/unsafe/string_literal_ptr_init.rs index c6395ccf..ab58d771 100644 --- a/tests/unit/out/unsafe/string_literal_ptr_init.rs +++ b/tests/unit/out/unsafe/string_literal_ptr_init.rs @@ -34,7 +34,7 @@ pub static mut table_1: [label; 2] = unsafe { }, label { name: ((c"second").as_ptr().cast_mut()).cast_const(), - probe: (Some(probe_two_0)), + probe: (Some(probe_two_0 as unsafe fn() -> i32)), mask: ((1) << (5)), }, ] diff --git a/tests/unit/out/unsafe/va_arg_fn_ptr.rs b/tests/unit/out/unsafe/va_arg_fn_ptr.rs index a02eea3d..f6b375d2 100644 --- a/tests/unit/out/unsafe/va_arg_fn_ptr.rs +++ b/tests/unit/out/unsafe/va_arg_fn_ptr.rs @@ -55,10 +55,9 @@ unsafe fn main_0() -> i32 { ((((unsafe { apply_unary_3( 5, - &[ - (Some(square_0).map_or(::std::ptr::null_mut(), |f| f as *mut ::libc::c_void)) - .into(), - ], + &[(Some(square_0 as unsafe fn(i32) -> i32) + .map_or(::std::ptr::null_mut(), |f| f as *mut ::libc::c_void)) + .into()], ) }) == (25)) as i32) != 0) @@ -67,10 +66,9 @@ unsafe fn main_0() -> i32 { ((((unsafe { apply_unary_3( 7, - &[ - (Some(negate_1).map_or(::std::ptr::null_mut(), |f| f as *mut ::libc::c_void)) - .into(), - ], + &[(Some(negate_1 as unsafe fn(i32) -> i32) + .map_or(::std::ptr::null_mut(), |f| f as *mut ::libc::c_void)) + .into()], ) }) == (-7_i32)) as i32) != 0) @@ -80,10 +78,9 @@ unsafe fn main_0() -> i32 { apply_binary_4( 3, 4, - &[ - (Some(add_2).map_or(::std::ptr::null_mut(), |f| f as *mut ::libc::c_void)) - .into(), - ], + &[(Some(add_2 as unsafe fn(i32, i32) -> i32) + .map_or(::std::ptr::null_mut(), |f| f as *mut ::libc::c_void)) + .into()], ) }) == (7)) as i32) != 0) @@ -95,7 +92,7 @@ unsafe fn main_0() -> i32 { ((&mut dummy as *mut i32) as *mut i32 as *mut ::libc::c_void); let _extra: *mut ::libc::c_void = ((&mut dummy as *mut i32) as *mut i32 as *mut ::libc::c_void); - not_supported_5(_ctx, Some(square_0), _extra) + not_supported_5(_ctx, Some(square_0 as unsafe fn(i32) -> i32), _extra) }) == (-3_i32)) as i32) != 0) ); diff --git a/tests/unit/out/unsafe/void_cast.rs b/tests/unit/out/unsafe/void_cast.rs index aea1827d..0d6b373e 100644 --- a/tests/unit/out/unsafe/void_cast.rs +++ b/tests/unit/out/unsafe/void_cast.rs @@ -84,10 +84,10 @@ unsafe fn main_0() -> i32 { assert!(((chosen) == (123))); &(bump_and_return_4); assert!(((side_effect_counter_3) == (2))); - &(Some(bump_and_return_4)); + &(Some(bump_and_return_4 as unsafe fn() -> i32)); assert!(((side_effect_counter_3) == (2))); &(std::mem::transmute:: i32>, Option i32>>( - (Some(bump_and_return_4)), + (Some(bump_and_return_4 as unsafe fn() -> i32)), )); assert!(((side_effect_counter_3) == (2))); let mut storage: i32 = 11; From fd22c476202972a551c7d2968da57a169c7f764a Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Wed, 16 Sep 2026 14:14:26 +0100 Subject: [PATCH 8/9] Remove nullability of arguments --- cpp2rust/converter/converter.cpp | 66 +++++++++---------- cpp2rust/converter/converter.h | 3 + .../converter/models/converter_refcount.cpp | 4 ++ .../converter/models/converter_refcount.h | 2 + libcc2rs/src/callable.rs | 24 +------ rules/cstdlib/tgt_refcount.rs | 14 ++-- rules/cstdlib/tgt_unsafe.rs | 24 +++---- rules/rustls/tgt_unsafe.rs | 34 ++++------ 8 files changed, 71 insertions(+), 100 deletions(-) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index e9559524..a5c0a469 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -1812,12 +1812,24 @@ void Converter::EmitFnPtrCall(clang::Expr *callee) { void Converter::ConvertFunctionToFunctionPointer( const clang::FunctionDecl *fn_decl) { - auto proto = fn_decl->getType()->getAs(); - StrCat(std::format("Some({} as {} {})", Mapper::MapFunctionName(fn_decl), - keyword_unsafe_, ConvertFunctionPointerType(proto))); + StrCat(std::format("Some({})", Mapper::MapFunctionName(fn_decl))); computed_expr_type_ = ComputedExprType::FreshPointer; } +std::string Converter::ConvertFnPtrCallee(clang::Expr *arg) { + PushExprKind push(*this, ExprKind::Callee); + Buffer buf(*this); + Convert(arg); + return std::move(buf).str(); +} + +std::string Converter::ConvertFnPtrPlaceholder(clang::Expr *arg) { + auto proto = + arg->getType()->getPointeeType()->getAs(); + return std::format("({} as {} {})", ConvertFnPtrCallee(arg), keyword_unsafe_, + ConvertFunctionPointerType(proto)); +} + Converter::CallInfo Converter::CollectCallInfo(clang::CallExpr *expr) { using Kind = CallArg::Kind; @@ -2409,12 +2421,6 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) { computed_expr_type_ = ComputedExprType::FreshPointer; break; default: - if (type->isFunctionPointerType() && - clang::isa( - sub_expr->IgnoreUnlessSpelledInSource())) { - ConvertVarInit(type, sub_expr); - break; - } if (auto *literal = clang::dyn_cast(sub_expr)) { auto type = expr->getType(); StrCat(getIntegerLiteral(literal, true, &type)); @@ -3597,31 +3603,21 @@ bool Converter::VisitConstantExpr(clang::ConstantExpr *expr) { } bool Converter::VisitLambdaExpr(clang::LambdaExpr *expr) { - bool to_fn_ptr = isAddrOf() && expr->capture_size() == 0; - if (to_fn_ptr) { - StrCat("Some("); - } - { - PushParen paren(*this); - StrCat('|'); - for (auto p : - expr->getLambdaClass()->getLambdaCallOperator()->parameters()) { - StrCat(GetNamedDeclAsString(p), token::kColon, ToString(p->getType()), - token::kComma); - } - StrCat("| {"); - EmitFunctionPreamble(expr->getLambdaClass()->getLambdaCallOperator()); - PushCurrFunction push_fn(*this, - expr->getLambdaClass()->getLambdaCallOperator()); - ConvertFunctionBody(curr_function_); - StrCat('}'); - } - if (to_fn_ptr) { - auto proto = - expr->getCallOperator()->getType()->getAs(); - StrCat(std::format(" as {} {})", keyword_unsafe_, - ConvertFunctionPointerType(proto))); + if (isAddrOf() && expr->capture_size() == 0) { + StrCat("Some"); } + PushParen paren(*this); + StrCat('|'); + for (auto p : expr->getLambdaClass()->getLambdaCallOperator()->parameters()) { + StrCat(GetNamedDeclAsString(p), token::kColon, ToString(p->getType()), + token::kComma); + } + StrCat("| {"); + EmitFunctionPreamble(expr->getLambdaClass()->getLambdaCallOperator()); + PushCurrFunction push_fn(*this, + expr->getLambdaClass()->getLambdaCallOperator()); + ConvertFunctionBody(curr_function_); + StrCat('}'); return false; } @@ -4631,6 +4627,10 @@ void Converter::PlaceholderCtx::dump() const { std::string Converter::ConvertPlaceholder(clang::Expr *expr, clang::Expr *arg, const PlaceholderCtx &ph_ctx) { + if (arg->getType()->isFunctionPointerType()) { + return ConvertFnPtrPlaceholder(arg); + } + if (ph_ctx.declared_in_rule_as_rust_ptr && arg->getType()->isArrayType()) { return std::format( "({} as {})", ConvertFreshPointer(arg), diff --git a/cpp2rust/converter/converter.h b/cpp2rust/converter/converter.h index d735f75f..f2cb8c7b 100644 --- a/cpp2rust/converter/converter.h +++ b/cpp2rust/converter/converter.h @@ -309,6 +309,9 @@ class Converter : public clang::RecursiveASTVisitor { virtual void ConvertFunctionToFunctionPointer(const clang::FunctionDecl *fn_decl); + std::string ConvertFnPtrCallee(clang::Expr *arg); + virtual std::string ConvertFnPtrPlaceholder(clang::Expr *arg); + // Option implements Copy virtual bool FunctionPointerImplementsCopy() const { return true; } diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index e63e34be..bda2078c 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -1287,6 +1287,10 @@ void ConverterRefCount::ConvertFunctionToFunctionPointer( computed_expr_type_ = ComputedExprType::FreshPointer; } +std::string ConverterRefCount::ConvertFnPtrPlaceholder(clang::Expr *arg) { + return ConvertFnPtrCallee(arg); +} + void ConverterRefCount::ConvertEqualsNullPtr(clang::Expr *expr) { StrCat('('); Convert(expr); diff --git a/cpp2rust/converter/models/converter_refcount.h b/cpp2rust/converter/models/converter_refcount.h index f588f6d1..790f7530 100644 --- a/cpp2rust/converter/models/converter_refcount.h +++ b/cpp2rust/converter/models/converter_refcount.h @@ -103,6 +103,8 @@ class ConverterRefCount final : public Converter { void ConvertFunctionToFunctionPointer(const clang::FunctionDecl *fn_decl) override; + std::string ConvertFnPtrPlaceholder(clang::Expr *arg) override; + // FnPtr does not implement Copy bool FunctionPointerImplementsCopy() const override { return false; } diff --git a/libcc2rs/src/callable.rs b/libcc2rs/src/callable.rs index 747277d0..f35dcfdc 100644 --- a/libcc2rs/src/callable.rs +++ b/libcc2rs/src/callable.rs @@ -17,30 +17,10 @@ macro_rules! callable { } } - impl $name<$($A,)* R> for Option - where - F: Fn($($A),*) -> R, - { - #[inline] - fn call(&self, $($a: $A),*) -> R { - self.as_ref().unwrap()($($a),*) - } - } - - impl<$($A,)* R> $name<$($A,)* R> for Option R> { - #[inline] - fn call(&self, $($a: $A),*) -> R { - unsafe { self.unwrap()($($a),*) } - } - } - - impl $name<$($A,)* R> for crate::fn_ptr::FnPtr - where - F: Fn($($A),*) -> R + 'static, - { + impl<$($A,)* R> $name<$($A,)* R> for unsafe fn($($A),*) -> R { #[inline] fn call(&self, $($a: $A),*) -> R { - (**self)($($a),*) + unsafe { self($($a),*) } } } }; diff --git a/rules/cstdlib/tgt_refcount.rs b/rules/cstdlib/tgt_refcount.rs index db6d8d7d..534d4472 100644 --- a/rules/cstdlib/tgt_refcount.rs +++ b/rules/cstdlib/tgt_refcount.rs @@ -50,13 +50,7 @@ fn f10(a0: Ptr, a1: Ptr) -> Ptr { } } -fn f8( - a0: AnyPtr, - a1: AnyPtr, - a2: usize, - a3: usize, - a4: FnPtr i32>, -) -> AnyPtr { +fn f8(a0: AnyPtr, a1: AnyPtr, a2: usize, a3: usize, a4: fn(AnyPtr, AnyPtr) -> i32) -> AnyPtr { let __base = a1.reinterpret_cast::(); let mut __lo: isize = 0; let mut __hi: isize = a2 as isize - 1; @@ -64,7 +58,7 @@ fn f8( while __lo <= __hi && __found.is_null() { let __mid = __lo + (__hi - __lo) / 2; let __elem = __base.offset(__mid as usize * a3); - let __r = a4.call(a0.clone(), __elem.to_any()); + let __r = a4(a0.clone(), __elem.to_any()); if __r == 0 { __found = __elem.to_any(); } else if __r < 0 { @@ -76,12 +70,12 @@ fn f8( __found } -fn f9(a0: AnyPtr, a1: usize, a2: usize, a3: FnPtr i32>) { +fn f9(a0: AnyPtr, a1: usize, a2: usize, a3: fn(AnyPtr, AnyPtr) -> i32) { let __base = a0.reinterpret_cast::(); for __i in 0..a1 { let mut __min = __i; for __j in (__i + 1)..a1 { - if a3.call( + if a3( __base.offset(__j * a2).to_any(), __base.offset(__min * a2).to_any(), ) < 0 diff --git a/rules/cstdlib/tgt_unsafe.rs b/rules/cstdlib/tgt_unsafe.rs index 9d0d0327..5b983c43 100644 --- a/rules/cstdlib/tgt_unsafe.rs +++ b/rules/cstdlib/tgt_unsafe.rs @@ -34,19 +34,17 @@ unsafe fn f8( a1: *const ::libc::c_void, a2: usize, a3: usize, - a4: Option i32>, + a4: unsafe fn(*const ::libc::c_void, *const ::libc::c_void) -> i32, ) -> *mut ::libc::c_void { libc::bsearch( a0, a1, a2, a3, - a4.map(|__f| { - std::mem::transmute::< - *const (), - unsafe extern "C" fn(*const ::libc::c_void, *const ::libc::c_void) -> i32, - >(__f as *const ()) - }), + Some(std::mem::transmute::< + *const (), + unsafe extern "C" fn(*const ::libc::c_void, *const ::libc::c_void) -> i32, + >(a4 as *const ())), ) } @@ -54,18 +52,16 @@ unsafe fn f9( a0: *mut ::libc::c_void, a1: usize, a2: usize, - a3: Option i32>, + a3: unsafe fn(*const ::libc::c_void, *const ::libc::c_void) -> i32, ) { libc::qsort( a0, a1, a2, - a3.map(|__f| { - std::mem::transmute::< - *const (), - unsafe extern "C" fn(*const ::libc::c_void, *const ::libc::c_void) -> i32, - >(__f as *const ()) - }), + Some(std::mem::transmute::< + *const (), + unsafe extern "C" fn(*const ::libc::c_void, *const ::libc::c_void) -> i32, + >(a3 as *const ())), ) } diff --git a/rules/rustls/tgt_unsafe.rs b/rules/rustls/tgt_unsafe.rs index 59c3d3f1..db78cc47 100644 --- a/rules/rustls/tgt_unsafe.rs +++ b/rules/rustls/tgt_unsafe.rs @@ -433,15 +433,13 @@ unsafe fn f57(a0: u32) -> bool { unsafe fn f58( a0: *mut ::rustls_ffi::connection::rustls_connection, - a1: Option i32>, + a1: unsafe fn(*mut ::libc::c_void, *mut u8, u64, *mut u64) -> i32, a2: *mut ::libc::c_void, a3: *mut u64, ) -> i32 { ::rustls_ffi::connection::rustls_connection::rustls_connection_read_tls( a0, - std::mem::transmute::( - a1.map_or(0_usize, |__f| __f as usize), - ), + std::mem::transmute::<*const (), ::rustls_ffi::io::rustls_read_callback>(a1 as *const ()), a2, a3 as *mut usize, ) @@ -449,15 +447,13 @@ unsafe fn f58( } unsafe fn f59( a0: *mut ::rustls_ffi::connection::rustls_connection, - a1: Option i32>, + a1: unsafe fn(*mut ::libc::c_void, *const u8, u64, *mut u64) -> i32, a2: *mut ::libc::c_void, a3: *mut u64, ) -> i32 { ::rustls_ffi::connection::rustls_connection::rustls_connection_write_tls( a0, - std::mem::transmute::( - a1.map_or(0_usize, |__f| __f as usize), - ), + std::mem::transmute::<*const (), ::rustls_ffi::io::rustls_write_callback>(a1 as *const ()), a2, a3 as *mut usize, ) @@ -465,15 +461,13 @@ unsafe fn f59( } unsafe fn f60( a0: *mut ::rustls_ffi::client::rustls_client_config_builder, - a1: Option< - unsafe fn(::rustls_ffi::rslice::rustls_str<'static>, *const u8, u64, *const u8, u64), - >, + a1: unsafe fn(::rustls_ffi::rslice::rustls_str<'static>, *const u8, u64, *const u8, u64), a2: Option) -> i32>, ) -> ::rustls_ffi::rustls_result { ::rustls_ffi::client::rustls_client_config_builder::rustls_client_config_builder_set_key_log( a0, - std::mem::transmute::( - a1.map_or(0_usize, |__f| __f as usize), + std::mem::transmute::<*const (), ::rustls_ffi::keylog::rustls_keylog_log_callback>( + a1 as *const (), ), std::mem::transmute::< Option) -> i32>, @@ -483,17 +477,15 @@ unsafe fn f60( } unsafe fn f61( a0: *mut ::rustls_ffi::client::rustls_client_config_builder, - a1: Option< - unsafe fn( - *mut ::libc::c_void, - *const ::rustls_ffi::client::rustls_verify_server_cert_params<'static>, - ) -> ::rustls_ffi::rustls_result, - >, + a1: unsafe fn( + *mut ::libc::c_void, + *const ::rustls_ffi::client::rustls_verify_server_cert_params<'static>, + ) -> ::rustls_ffi::rustls_result, ) -> ::rustls_ffi::rustls_result { ::rustls_ffi::client::rustls_client_config_builder::rustls_client_config_builder_dangerous_set_certificate_verifier( a0, - std::mem::transmute::( - a1.map_or(0_usize, |__f| __f as usize), + std::mem::transmute::<*const (), ::rustls_ffi::client::rustls_verify_server_cert_callback>( + a1 as *const (), ), ) } From 028e45d7e4488da57397a5a539cdf340c43f16a7 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Wed, 16 Sep 2026 14:17:26 +0100 Subject: [PATCH 9/9] Update tests --- .../converter/models/converter_refcount.cpp | 8 +--- tests/unit/out/refcount/fn_ptr_default_arg.rs | 2 +- tests/unit/out/refcount/fn_ptr_stable_sort.rs | 2 +- tests/unit/out/refcount/qsort_bsearch.rs | 6 +-- tests/unit/out/unsafe/fn_ptr.rs | 6 +-- tests/unit/out/unsafe/fn_ptr_arity.rs | 20 +------- tests/unit/out/unsafe/fn_ptr_array.rs | 10 ++-- tests/unit/out/unsafe/fn_ptr_as_condition.rs | 9 +--- tests/unit/out/unsafe/fn_ptr_cast.rs | 15 +++--- tests/unit/out/unsafe/fn_ptr_conditional.rs | 10 ++-- tests/unit/out/unsafe/fn_ptr_default_arg.rs | 10 ++-- tests/unit/out/unsafe/fn_ptr_global.rs | 8 ++-- tests/unit/out/unsafe/fn_ptr_reassign.rs | 8 ++-- tests/unit/out/unsafe/fn_ptr_return.rs | 8 ++-- tests/unit/out/unsafe/fn_ptr_stable_sort.rs | 4 +- .../unit/out/unsafe/fn_ptr_stdlib_compare.rs | 46 ++++--------------- tests/unit/out/unsafe/fn_ptr_struct.rs | 6 +-- tests/unit/out/unsafe/fn_ptr_void_return.rs | 11 ++--- tests/unit/out/unsafe/fn_ptr_vtable.rs | 6 +-- tests/unit/out/unsafe/malloc_realloc_free.rs | 12 ++--- tests/unit/out/unsafe/no_direct_callee.rs | 2 +- tests/unit/out/unsafe/qsort_bsearch.rs | 45 +++++++++--------- .../out/unsafe/string_literal_ptr_init.rs | 2 +- tests/unit/out/unsafe/va_arg_fn_ptr.rs | 23 ++++++---- tests/unit/out/unsafe/void_cast.rs | 4 +- 25 files changed, 106 insertions(+), 177 deletions(-) diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index bda2078c..625e62fc 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -2089,13 +2089,9 @@ std::string ConverterRefCount::ConvertVarInitValue(clang::QualType qual_type, Buffer buf(*this); PushConversionKind push(*this, ConversionKind::Unboxed); if (qual_type->isFunctionPointerType() && lambda->capture_size() == 0) { - auto proto = lambda->getCallOperator() - ->getType() - ->getAs(); - StrCat( - std::format("FnPtr::<{}>::new", ConvertFunctionPointerType(proto))); - PushParen paren(*this); + StrCat("FnPtr::new("); VisitLambdaExpr(lambda); + StrCat(')'); } else { VisitLambdaExpr(lambda); } diff --git a/tests/unit/out/refcount/fn_ptr_default_arg.rs b/tests/unit/out/refcount/fn_ptr_default_arg.rs index 4a0d282c..0348fc82 100644 --- a/tests/unit/out/refcount/fn_ptr_default_arg.rs +++ b/tests/unit/out/refcount/fn_ptr_default_arg.rs @@ -26,7 +26,7 @@ fn main_0() -> i32 { assert!((({ apply_1(5, None,) }) == 5)); assert!((({ apply_1(5, Some(FnPtr:: i32>::null()),) }) == 5)); assert!((({ apply_1(5, Some(FnPtr:: i32>::new(identity_0)),) }) == 5)); - let negate: Value i32>> = Rc::new(RefCell::new(FnPtr:: i32>::new( + let negate: Value i32>> = Rc::new(RefCell::new(FnPtr::new( (|x: i32| { let x: Value = Rc::new(RefCell::new(x)); return -(*x.borrow()); diff --git a/tests/unit/out/refcount/fn_ptr_stable_sort.rs b/tests/unit/out/refcount/fn_ptr_stable_sort.rs index d294121b..6ca928be 100644 --- a/tests/unit/out/refcount/fn_ptr_stable_sort.rs +++ b/tests/unit/out/refcount/fn_ptr_stable_sort.rs @@ -61,7 +61,7 @@ fn main_0() -> i32 { }); (v.as_pointer() as Ptr).sort_with_cmp( (v.as_pointer() as Ptr).to_end().get_offset(), - |x, y| FnPtr::, Ptr) -> bool>::new(Compare_0).call(x, y), + |x, y| Compare_0.call(x, y), ); assert!( ((*(*(v.as_pointer() as Ptr) diff --git a/tests/unit/out/refcount/qsort_bsearch.rs b/tests/unit/out/refcount/qsort_bsearch.rs index c200ac0c..d53ecb1d 100644 --- a/tests/unit/out/refcount/qsort_bsearch.rs +++ b/tests/unit/out/refcount/qsort_bsearch.rs @@ -29,7 +29,7 @@ fn main_0() -> i32 { for __i in 0..8_usize { let mut __min = __i; for __j in (__i + 1)..8_usize { - if FnPtr:: i32>::new(cmp_int_0).call( + if cmp_int_0( __base.offset(__j * ::std::mem::size_of::()).to_any(), __base.offset(__min * ::std::mem::size_of::()).to_any(), ) < 0 @@ -76,7 +76,7 @@ fn main_0() -> i32 { while __lo <= __hi && __found.is_null() { let __mid = __lo + (__hi - __lo) / 2; let __elem = __base.offset(__mid as usize * ::std::mem::size_of::()); - let __r = FnPtr:: i32>::new(cmp_int_0).call( + let __r = cmp_int_0( ((key.as_pointer()) as Ptr).to_any().clone(), __elem.to_any(), ); @@ -106,7 +106,7 @@ fn main_0() -> i32 { while __lo <= __hi && __found.is_null() { let __mid = __lo + (__hi - __lo) / 2; let __elem = __base.offset(__mid as usize * ::std::mem::size_of::()); - let __r = FnPtr:: i32>::new(cmp_int_0).call( + let __r = cmp_int_0( ((miss_key.as_pointer()) as Ptr).to_any().clone(), __elem.to_any(), ); diff --git a/tests/unit/out/unsafe/fn_ptr.rs b/tests/unit/out/unsafe/fn_ptr.rs index 6faa1392..dcaacdaf 100644 --- a/tests/unit/out/unsafe/fn_ptr.rs +++ b/tests/unit/out/unsafe/fn_ptr.rs @@ -23,10 +23,10 @@ pub fn main() { unsafe fn main_0() -> i32 { let mut fn_: Option i32> = None; assert!((fn_).is_none()); - assert!(((fn_) != (Some(my_foo_0 as unsafe fn(*mut ::libc::c_void) -> i32)))); - fn_ = Some(my_foo_0 as unsafe fn(*mut ::libc::c_void) -> i32); + assert!(((fn_) != (Some(my_foo_0)))); + fn_ = Some(my_foo_0); assert!(!((fn_).is_none())); - assert!(((fn_) == (Some(my_foo_0 as unsafe fn(*mut ::libc::c_void) -> i32)))); + assert!(((fn_) == (Some(my_foo_0)))); let mut a: i32 = 10; assert!(((unsafe { foo_1(fn_, (&mut a as *mut i32),) }) == (a))); return 0; diff --git a/tests/unit/out/unsafe/fn_ptr_arity.rs b/tests/unit/out/unsafe/fn_ptr_arity.rs index d92ca088..912c17c4 100644 --- a/tests/unit/out/unsafe/fn_ptr_arity.rs +++ b/tests/unit/out/unsafe/fn_ptr_arity.rs @@ -32,25 +32,7 @@ pub fn main() { unsafe fn main_0() -> i32 { let mut f: Option< unsafe fn(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) -> i32, - > = (Some( - foo_0 - as unsafe fn( - i32, - i32, - i32, - i32, - i32, - i32, - i32, - i32, - i32, - i32, - i32, - i32, - i32, - i32, - ) -> i32, - )); + > = (Some(foo_0)); assert!(((unsafe { (f).unwrap()(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,) }) == (22))); return 0; } diff --git a/tests/unit/out/unsafe/fn_ptr_array.rs b/tests/unit/out/unsafe/fn_ptr_array.rs index 6f37ac66..c41968b9 100644 --- a/tests/unit/out/unsafe/fn_ptr_array.rs +++ b/tests/unit/out/unsafe/fn_ptr_array.rs @@ -21,16 +21,12 @@ pub fn main() { } } unsafe fn main_0() -> i32 { - let mut ops: [Option i32>; 3] = [ - Some(add_0 as unsafe fn(i32, i32) -> i32), - Some(sub_1 as unsafe fn(i32, i32) -> i32), - Some(mul_2 as unsafe fn(i32, i32) -> i32), - ]; + let mut ops: [Option i32>; 3] = [Some(add_0), Some(sub_1), Some(mul_2)]; assert!(((unsafe { (ops[(0) as usize]).unwrap()(2, 3,) }) == (5))); assert!(((unsafe { (ops[(1) as usize]).unwrap()(7, 4,) }) == (3))); assert!(((unsafe { (ops[(2) as usize]).unwrap()(6, 5,) }) == (30))); assert!(!((ops[(0) as usize]).is_none())); - assert!(((ops[(0) as usize]) == (Some(add_0 as unsafe fn(i32, i32) -> i32)))); - assert!(((ops[(0) as usize]) != (Some(sub_1 as unsafe fn(i32, i32) -> i32)))); + assert!(((ops[(0) as usize]) == (Some(add_0)))); + assert!(((ops[(0) as usize]) != (Some(sub_1)))); return 0; } diff --git a/tests/unit/out/unsafe/fn_ptr_as_condition.rs b/tests/unit/out/unsafe/fn_ptr_as_condition.rs index 8ca0d487..e4d6574c 100644 --- a/tests/unit/out/unsafe/fn_ptr_as_condition.rs +++ b/tests/unit/out/unsafe/fn_ptr_as_condition.rs @@ -21,19 +21,14 @@ pub fn main() { } unsafe fn main_0() -> i32 { let mut a: i32 = 5; - (unsafe { - maybe_call_1( - Some(double_it_0 as unsafe fn(*mut i32)), - (&mut a as *mut i32), - ) - }); + (unsafe { maybe_call_1(Some(double_it_0), (&mut a as *mut i32)) }); assert!(((a) == (10))); let mut b: i32 = 5; (unsafe { maybe_call_1(None, (&mut b as *mut i32)) }); assert!(((b) == (5))); let mut fn_: Option = None; if !(!(fn_).is_none()) { - fn_ = Some(double_it_0 as unsafe fn(*mut i32)); + fn_ = Some(double_it_0); } let mut c: i32 = 3; if !(fn_).is_none() { diff --git a/tests/unit/out/unsafe/fn_ptr_cast.rs b/tests/unit/out/unsafe/fn_ptr_cast.rs index 64aafc26..014c5387 100644 --- a/tests/unit/out/unsafe/fn_ptr_cast.rs +++ b/tests/unit/out/unsafe/fn_ptr_cast.rs @@ -10,7 +10,7 @@ pub unsafe fn double_it_0(mut x: i32) -> i32 { return ((x) * (2)); } pub unsafe fn test_roundtrip_1() { - let mut fn_: Option i32> = Some(double_it_0 as unsafe fn(i32) -> i32); + let mut fn_: Option i32> = Some(double_it_0); assert!(((unsafe { (fn_).unwrap()(5,) }) == (10))); let mut gfn: Option = std::mem::transmute:: i32>, Option>(fn_); @@ -21,7 +21,7 @@ pub unsafe fn test_roundtrip_1() { assert!(((fn2) == (fn_))); } pub unsafe fn test_double_cast_2() { - let mut fn_: Option i32> = Some(double_it_0 as unsafe fn(i32) -> i32); + let mut fn_: Option i32> = Some(double_it_0); let mut fn2: Option i32> = std::mem::transmute::, Option i32>>( std::mem::transmute:: i32>, Option>(fn_), @@ -37,7 +37,7 @@ pub struct Command { pub unsafe fn test_void_ptr_to_fn_3() { let mut cmd: Command = ::default(); cmd.data = std::mem::transmute:: i32>, *mut ::libc::c_void>(Some( - double_it_0 as unsafe fn(i32) -> i32, + double_it_0, )); let mut fn_: Option i32> = std::mem::transmute::<*mut ::libc::c_void, Option i32>>(cmd.data); @@ -47,11 +47,10 @@ pub unsafe fn add_offset_4(mut base: *mut i32, mut offset: i32) -> i32 { return ((*base) + (offset)); } pub unsafe fn test_call_through_cast_5() { - let mut gfn: Option i32> = - std::mem::transmute::< - Option i32>, - Option i32>, - >(Some(add_offset_4 as unsafe fn(*mut i32, i32) -> i32)); + let mut gfn: Option i32> = std::mem::transmute::< + Option i32>, + Option i32>, + >(Some(add_offset_4)); let mut val: i32 = 100; let mut result: i32 = (unsafe { (gfn).unwrap()( diff --git a/tests/unit/out/unsafe/fn_ptr_conditional.rs b/tests/unit/out/unsafe/fn_ptr_conditional.rs index d8927b07..1e8d5e9f 100644 --- a/tests/unit/out/unsafe/fn_ptr_conditional.rs +++ b/tests/unit/out/unsafe/fn_ptr_conditional.rs @@ -17,12 +17,12 @@ pub unsafe fn identity_2(mut x: i32) -> i32 { } pub unsafe fn pick_3(mut mode: i32) -> Option i32> { return if ((mode) > (0)) { - Some(inc_0 as unsafe fn(i32) -> i32) + Some(inc_0) } else { if ((mode) < (0)) { - Some(dec_1 as unsafe fn(i32) -> i32) + Some(dec_1) } else { - Some(identity_2 as unsafe fn(i32) -> i32) + Some(identity_2) } }; } @@ -30,7 +30,7 @@ pub unsafe fn apply_4(mut fn_: Option i32>, mut x: i32) -> i32 let mut actual: Option i32> = if !(fn_).is_none() { fn_ } else { - Some(identity_2 as unsafe fn(i32) -> i32) + Some(identity_2) }; return (unsafe { (actual).unwrap()(x) }); } @@ -43,7 +43,7 @@ unsafe fn main_0() -> i32 { assert!(((unsafe { (unsafe { pick_3(1,) }).unwrap()(10,) }) == (11))); assert!(((unsafe { (unsafe { pick_3(-1_i32,) }).unwrap()(10,) }) == (9))); assert!(((unsafe { (unsafe { pick_3(0,) }).unwrap()(10,) }) == (10))); - assert!(((unsafe { apply_4(Some(inc_0 as unsafe fn(i32) -> i32), 5,) }) == (6))); + assert!(((unsafe { apply_4(Some(inc_0), 5,) }) == (6))); assert!(((unsafe { apply_4(None, 5,) }) == (5))); return 0; } diff --git a/tests/unit/out/unsafe/fn_ptr_default_arg.rs b/tests/unit/out/unsafe/fn_ptr_default_arg.rs index 0ff33bdb..43d6ddab 100644 --- a/tests/unit/out/unsafe/fn_ptr_default_arg.rs +++ b/tests/unit/out/unsafe/fn_ptr_default_arg.rs @@ -24,12 +24,10 @@ pub fn main() { unsafe fn main_0() -> i32 { assert!(((unsafe { apply_1(5, None,) }) == (5))); assert!(((unsafe { apply_1(5, Some(None),) }) == (5))); - assert!(((unsafe { apply_1(5, Some(Some(identity_0 as unsafe fn(i32) -> i32)),) }) == (5))); - let mut negate: Option i32> = Some( - (|x: i32| { - return -x; - }) as unsafe fn(i32) -> i32, - ); + assert!(((unsafe { apply_1(5, Some(Some(identity_0)),) }) == (5))); + let mut negate: Option i32> = Some(|x: i32| { + return -x; + }); assert!(((unsafe { apply_1(5, Some(negate),) }) == (-5_i32))); return 0; } diff --git a/tests/unit/out/unsafe/fn_ptr_global.rs b/tests/unit/out/unsafe/fn_ptr_global.rs index bfb228f0..5cca8fd5 100644 --- a/tests/unit/out/unsafe/fn_ptr_global.rs +++ b/tests/unit/out/unsafe/fn_ptr_global.rs @@ -29,12 +29,12 @@ pub fn main() { } unsafe fn main_0() -> i32 { assert!(((unsafe { call_op_4(5,) }) == (5))); - (unsafe { set_op_3(Some(double_it_0 as unsafe fn(i32) -> i32)) }); + (unsafe { set_op_3(Some(double_it_0)) }); assert!(!((g_op_2).is_none())); - assert!(((g_op_2) == (Some(double_it_0 as unsafe fn(i32) -> i32)))); + assert!(((g_op_2) == (Some(double_it_0)))); assert!(((unsafe { call_op_4(5,) }) == (10))); - (unsafe { set_op_3(Some(triple_it_1 as unsafe fn(i32) -> i32)) }); - assert!(((g_op_2) == (Some(triple_it_1 as unsafe fn(i32) -> i32)))); + (unsafe { set_op_3(Some(triple_it_1)) }); + assert!(((g_op_2) == (Some(triple_it_1)))); assert!(((unsafe { call_op_4(5,) }) == (15))); (unsafe { set_op_3(None) }); assert!((g_op_2).is_none()); diff --git a/tests/unit/out/unsafe/fn_ptr_reassign.rs b/tests/unit/out/unsafe/fn_ptr_reassign.rs index 0fa0ce9b..4c8b0e3f 100644 --- a/tests/unit/out/unsafe/fn_ptr_reassign.rs +++ b/tests/unit/out/unsafe/fn_ptr_reassign.rs @@ -21,15 +21,15 @@ pub fn main() { } } unsafe fn main_0() -> i32 { - let mut fn_: Option i32> = Some(add_0 as unsafe fn(i32, i32) -> i32); + let mut fn_: Option i32> = Some(add_0); assert!(((unsafe { (fn_).unwrap()(3, 4,) }) == (7))); - fn_ = Some(sub_1 as unsafe fn(i32, i32) -> i32); + fn_ = Some(sub_1); assert!(((unsafe { (fn_).unwrap()(10, 3,) }) == (7))); - fn_ = Some(mul_2 as unsafe fn(i32, i32) -> i32); + fn_ = Some(mul_2); assert!(((unsafe { (fn_).unwrap()(6, 7,) }) == (42))); fn_ = None; assert!((fn_).is_none()); - fn_ = Some(add_0 as unsafe fn(i32, i32) -> i32); + fn_ = Some(add_0); assert!(!((fn_).is_none())); assert!(((unsafe { (fn_).unwrap()(1, 1,) }) == (2))); return 0; diff --git a/tests/unit/out/unsafe/fn_ptr_return.rs b/tests/unit/out/unsafe/fn_ptr_return.rs index f2114159..5f3b8ec7 100644 --- a/tests/unit/out/unsafe/fn_ptr_return.rs +++ b/tests/unit/out/unsafe/fn_ptr_return.rs @@ -14,9 +14,9 @@ pub unsafe fn dec_1(mut x: i32) -> i32 { } pub unsafe fn pick_2(mut choose_inc: i32) -> Option i32> { if (choose_inc != 0) { - return Some(inc_0 as unsafe fn(i32) -> i32); + return Some(inc_0); } - return Some(dec_1 as unsafe fn(i32) -> i32); + return Some(dec_1); } pub fn main() { unsafe { @@ -26,10 +26,10 @@ pub fn main() { unsafe fn main_0() -> i32 { let mut f: Option i32> = (unsafe { pick_2(1) }); assert!(!((f).is_none())); - assert!(((f) == (Some(inc_0 as unsafe fn(i32) -> i32)))); + assert!(((f) == (Some(inc_0)))); assert!(((unsafe { (f).unwrap()(10,) }) == (11))); let mut g: Option i32> = (unsafe { pick_2(0) }); - assert!(((g) == (Some(dec_1 as unsafe fn(i32) -> i32)))); + assert!(((g) == (Some(dec_1)))); assert!(((unsafe { (g).unwrap()(10,) }) == (9))); assert!(((f) != (g))); return 0; diff --git a/tests/unit/out/unsafe/fn_ptr_stable_sort.rs b/tests/unit/out/unsafe/fn_ptr_stable_sort.rs index b466017a..2165c81e 100644 --- a/tests/unit/out/unsafe/fn_ptr_stable_sort.rs +++ b/tests/unit/out/unsafe/fn_ptr_stable_sort.rs @@ -28,11 +28,11 @@ unsafe fn main_0() -> i32 { { let len = v.as_mut_ptr().add(v.len()).offset_from(v.as_mut_ptr()) as usize; ::std::slice::from_raw_parts_mut(v.as_mut_ptr(), len).sort_by(|x, y| { - if Some(Compare_0 as unsafe fn(*const Item, *const Item) -> bool) + if (Compare_0 as unsafe fn(*const Item, *const Item) -> bool) .call(x as *const _, y as *const _) { std::cmp::Ordering::Less - } else if Some(Compare_0 as unsafe fn(*const Item, *const Item) -> bool) + } else if (Compare_0 as unsafe fn(*const Item, *const Item) -> bool) .call(y as *const _, x as *const _) { std::cmp::Ordering::Greater diff --git a/tests/unit/out/unsafe/fn_ptr_stdlib_compare.rs b/tests/unit/out/unsafe/fn_ptr_stdlib_compare.rs index dbe1e1d0..f4601563 100644 --- a/tests/unit/out/unsafe/fn_ptr_stdlib_compare.rs +++ b/tests/unit/out/unsafe/fn_ptr_stdlib_compare.rs @@ -29,26 +29,14 @@ pub fn main() { } unsafe fn main_0() -> i32 { let mut fn1: Option usize> = - Some( - libcc2rs::fread_unsafe - as unsafe fn(*mut ::libc::c_void, usize, usize, *mut ::libc::FILE) -> usize, - ); - assert!( - ((fn1) - == (Some( - libcc2rs::fread_unsafe - as unsafe fn(*mut ::libc::c_void, usize, usize, *mut ::libc::FILE) -> usize - ))) - ); + Some(libcc2rs::fread_unsafe); + assert!(((fn1) == (Some(libcc2rs::fread_unsafe)))); assert!(!((fn1).is_none())); let mut fn2: Option usize> = std::mem::transmute::< Option usize>, Option usize>, - >(Some( - libcc2rs::fread_unsafe - as unsafe fn(*mut ::libc::c_void, usize, usize, *mut ::libc::FILE) -> usize, - )); + >(Some(libcc2rs::fread_unsafe)); assert!( ((fn1) == (std::mem::transmute::< @@ -60,10 +48,7 @@ unsafe fn main_0() -> i32 { std::mem::transmute::< Option usize>, Option usize>, - >(Some( - my_alternative_fread_0 - as unsafe fn(*mut libc::c_char, usize, usize, *mut ::libc::c_void) -> usize, - )); + >(Some(my_alternative_fread_0)); assert!( ((unsafe { (f3).unwrap()(std::ptr::null_mut(), 0_usize, 0_usize, std::ptr::null_mut(),) }) == (22_usize)) @@ -136,27 +121,15 @@ unsafe fn main_0() -> i32 { } let mut gn1: Option< unsafe fn(*const ::libc::c_void, usize, usize, *mut ::libc::FILE) -> usize, - > = Some( - libcc2rs::fwrite_unsafe - as unsafe fn(*const ::libc::c_void, usize, usize, *mut ::libc::FILE) -> usize, - ); - assert!( - ((gn1) - == (Some( - libcc2rs::fwrite_unsafe - as unsafe fn(*const ::libc::c_void, usize, usize, *mut ::libc::FILE) -> usize - ))) - ); + > = Some(libcc2rs::fwrite_unsafe); + assert!(((gn1) == (Some(libcc2rs::fwrite_unsafe)))); assert!(!((gn1).is_none())); let mut gn2: Option< unsafe fn(*const libc::c_char, usize, usize, *mut ::libc::c_void) -> usize, > = std::mem::transmute::< Option usize>, Option usize>, - >(Some( - libcc2rs::fwrite_unsafe - as unsafe fn(*const ::libc::c_void, usize, usize, *mut ::libc::FILE) -> usize, - )); + >(Some(libcc2rs::fwrite_unsafe)); assert!( ((gn1) == (std::mem::transmute::< @@ -168,10 +141,7 @@ unsafe fn main_0() -> i32 { std::mem::transmute::< Option usize>, Option usize>, - >(Some( - my_alternative_fwrite_1 - as unsafe fn(*const libc::c_char, usize, usize, *mut ::libc::c_void) -> usize, - )); + >(Some(my_alternative_fwrite_1)); assert!( ((unsafe { (g3).unwrap()(std::ptr::null(), 0_usize, 0_usize, std::ptr::null_mut(),) }) == (33_usize)) diff --git a/tests/unit/out/unsafe/fn_ptr_struct.rs b/tests/unit/out/unsafe/fn_ptr_struct.rs index 26d4b33d..c8480075 100644 --- a/tests/unit/out/unsafe/fn_ptr_struct.rs +++ b/tests/unit/out/unsafe/fn_ptr_struct.rs @@ -34,16 +34,16 @@ pub fn main() { unsafe fn main_0() -> i32 { let mut h1: Handler = Handler { tag: 1, - cb: Some(double_it_0 as unsafe fn(i32) -> i32), + cb: Some(double_it_0), }; let mut h2: Handler = Handler { tag: 2, - cb: Some(negate_1 as unsafe fn(i32) -> i32), + cb: Some(negate_1), }; assert!(!((h1.cb).is_none())); assert!(((unsafe { (h1.cb).unwrap()(5,) }) == (10))); assert!(((unsafe { (h2.cb).unwrap()(7,) }) == (-7_i32))); - (h1.cb) = Some(negate_1 as unsafe fn(i32) -> i32); + (h1.cb) = Some(negate_1); assert!(((unsafe { (h1.cb).unwrap()(3,) }) == (-3_i32))); assert!(((h1.cb) == (h2.cb))); return 0; diff --git a/tests/unit/out/unsafe/fn_ptr_void_return.rs b/tests/unit/out/unsafe/fn_ptr_void_return.rs index 83f75ce1..4a98d7f1 100644 --- a/tests/unit/out/unsafe/fn_ptr_void_return.rs +++ b/tests/unit/out/unsafe/fn_ptr_void_return.rs @@ -22,16 +22,11 @@ pub fn main() { } unsafe fn main_0() -> i32 { let mut a: i32 = 42; - (unsafe { run_2(Some(negate_0 as unsafe fn(*mut i32)), (&mut a as *mut i32)) }); + (unsafe { run_2(Some(negate_0), (&mut a as *mut i32)) }); assert!(((a) == (-42_i32))); - (unsafe { - run_2( - Some(zero_out_1 as unsafe fn(*mut i32)), - (&mut a as *mut i32), - ) - }); + (unsafe { run_2(Some(zero_out_1), (&mut a as *mut i32)) }); assert!(((a) == (0))); - let mut fn_: Option = Some(negate_0 as unsafe fn(*mut i32)); + let mut fn_: Option = Some(negate_0); assert!(!((fn_).is_none())); let mut b: i32 = 10; (unsafe { (fn_).unwrap()((&mut b as *mut i32)) }); diff --git a/tests/unit/out/unsafe/fn_ptr_vtable.rs b/tests/unit/out/unsafe/fn_ptr_vtable.rs index 97fcb1e6..5eff7364 100644 --- a/tests/unit/out/unsafe/fn_ptr_vtable.rs +++ b/tests/unit/out/unsafe/fn_ptr_vtable.rs @@ -40,9 +40,9 @@ pub fn main() { } unsafe fn main_0() -> i32 { let mut vt: Vtable = Vtable { - create: Some(int_create_1 as unsafe fn(i32) -> *mut ::libc::c_void), - get: Some(int_get_2 as unsafe fn(*mut ::libc::c_void) -> i32), - destroy: Some(int_destroy_3 as unsafe fn(*mut ::libc::c_void)), + create: Some(int_create_1), + get: Some(int_get_2), + destroy: Some(int_destroy_3), }; assert!(!((vt.create).is_none())); assert!(!((vt.get).is_none())); diff --git a/tests/unit/out/unsafe/malloc_realloc_free.rs b/tests/unit/out/unsafe/malloc_realloc_free.rs index ec25809c..588a7219 100644 --- a/tests/unit/out/unsafe/malloc_realloc_free.rs +++ b/tests/unit/out/unsafe/malloc_realloc_free.rs @@ -56,14 +56,12 @@ unsafe fn main_0() -> i32 { libcc2rs::free_unsafe((zeros as *mut i32 as *mut ::libc::c_void)); } let mut pmalloc: Option *mut ::libc::c_void> = - Some(libcc2rs::malloc_unsafe as unsafe fn(usize) -> *mut ::libc::c_void); - let mut pfree: Option = - Some(libcc2rs::free_unsafe as unsafe fn(*mut ::libc::c_void)); - let mut prealloc: Option *mut ::libc::c_void> = Some( - libcc2rs::realloc_unsafe as unsafe fn(*mut ::libc::c_void, usize) -> *mut ::libc::c_void, - ); + Some(libcc2rs::malloc_unsafe); + let mut pfree: Option = Some(libcc2rs::free_unsafe); + let mut prealloc: Option *mut ::libc::c_void> = + Some(libcc2rs::realloc_unsafe); let mut pcalloc: Option *mut ::libc::c_void> = - Some(libcc2rs::calloc_unsafe as unsafe fn(usize, usize) -> *mut ::libc::c_void); + Some(libcc2rs::calloc_unsafe); let mut __do_while = true; 'loop_: while __do_while || (0 != 0) { __do_while = false; diff --git a/tests/unit/out/unsafe/no_direct_callee.rs b/tests/unit/out/unsafe/no_direct_callee.rs index 143e065e..311d4c17 100644 --- a/tests/unit/out/unsafe/no_direct_callee.rs +++ b/tests/unit/out/unsafe/no_direct_callee.rs @@ -21,6 +21,6 @@ pub fn main() { } } unsafe fn main_0() -> i32 { - assert!(((unsafe { test_1(Some(test1_0 as unsafe fn() -> bool),) }) == (1))); + assert!(((unsafe { test_1(Some(test1_0),) }) == (1))); return 0; } diff --git a/tests/unit/out/unsafe/qsort_bsearch.rs b/tests/unit/out/unsafe/qsort_bsearch.rs index d1c9ea7b..c3fa5eb6 100644 --- a/tests/unit/out/unsafe/qsort_bsearch.rs +++ b/tests/unit/out/unsafe/qsort_bsearch.rs @@ -22,14 +22,13 @@ unsafe fn main_0() -> i32 { (arr.as_mut_ptr() as *mut i32 as *mut ::libc::c_void), 8_usize, ::std::mem::size_of::(), - Some(cmp_int_0 as unsafe fn(*const ::libc::c_void, *const ::libc::c_void) -> i32).map( - |__f| { - std::mem::transmute::< - *const (), - unsafe extern "C" fn(*const ::libc::c_void, *const ::libc::c_void) -> i32, - >(__f as *const ()) - }, - ), + Some(std::mem::transmute::< + *const (), + unsafe extern "C" fn(*const ::libc::c_void, *const ::libc::c_void) -> i32, + >( + (cmp_int_0 as unsafe fn(*const ::libc::c_void, *const ::libc::c_void) -> i32) + as *const (), + )), ); let mut i: i32 = 0; 'loop_: while ((((i) < (7)) as i32) != 0) { @@ -42,14 +41,13 @@ unsafe fn main_0() -> i32 { (arr.as_mut_ptr() as *const i32 as *const ::libc::c_void), 8_usize, ::std::mem::size_of::(), - Some(cmp_int_0 as unsafe fn(*const ::libc::c_void, *const ::libc::c_void) -> i32).map( - |__f| { - std::mem::transmute::< - *const (), - unsafe extern "C" fn(*const ::libc::c_void, *const ::libc::c_void) -> i32, - >(__f as *const ()) - }, - ), + Some(std::mem::transmute::< + *const (), + unsafe extern "C" fn(*const ::libc::c_void, *const ::libc::c_void) -> i32, + >( + (cmp_int_0 as unsafe fn(*const ::libc::c_void, *const ::libc::c_void) -> i32) + as *const (), + )), ) as *mut i32); assert!((((!((hit).is_null())) as i32) != 0)); assert!(((((*hit) == (7)) as i32) != 0)); @@ -59,14 +57,13 @@ unsafe fn main_0() -> i32 { (arr.as_mut_ptr() as *const i32 as *const ::libc::c_void), 8_usize, ::std::mem::size_of::(), - Some(cmp_int_0 as unsafe fn(*const ::libc::c_void, *const ::libc::c_void) -> i32).map( - |__f| { - std::mem::transmute::< - *const (), - unsafe extern "C" fn(*const ::libc::c_void, *const ::libc::c_void) -> i32, - >(__f as *const ()) - }, - ), + Some(std::mem::transmute::< + *const (), + unsafe extern "C" fn(*const ::libc::c_void, *const ::libc::c_void) -> i32, + >( + (cmp_int_0 as unsafe fn(*const ::libc::c_void, *const ::libc::c_void) -> i32) + as *const (), + )), ) as *mut i32); assert!(((((miss).is_null()) as i32) != 0)); return 0; diff --git a/tests/unit/out/unsafe/string_literal_ptr_init.rs b/tests/unit/out/unsafe/string_literal_ptr_init.rs index ab58d771..c6395ccf 100644 --- a/tests/unit/out/unsafe/string_literal_ptr_init.rs +++ b/tests/unit/out/unsafe/string_literal_ptr_init.rs @@ -34,7 +34,7 @@ pub static mut table_1: [label; 2] = unsafe { }, label { name: ((c"second").as_ptr().cast_mut()).cast_const(), - probe: (Some(probe_two_0 as unsafe fn() -> i32)), + probe: (Some(probe_two_0)), mask: ((1) << (5)), }, ] diff --git a/tests/unit/out/unsafe/va_arg_fn_ptr.rs b/tests/unit/out/unsafe/va_arg_fn_ptr.rs index f6b375d2..a02eea3d 100644 --- a/tests/unit/out/unsafe/va_arg_fn_ptr.rs +++ b/tests/unit/out/unsafe/va_arg_fn_ptr.rs @@ -55,9 +55,10 @@ unsafe fn main_0() -> i32 { ((((unsafe { apply_unary_3( 5, - &[(Some(square_0 as unsafe fn(i32) -> i32) - .map_or(::std::ptr::null_mut(), |f| f as *mut ::libc::c_void)) - .into()], + &[ + (Some(square_0).map_or(::std::ptr::null_mut(), |f| f as *mut ::libc::c_void)) + .into(), + ], ) }) == (25)) as i32) != 0) @@ -66,9 +67,10 @@ unsafe fn main_0() -> i32 { ((((unsafe { apply_unary_3( 7, - &[(Some(negate_1 as unsafe fn(i32) -> i32) - .map_or(::std::ptr::null_mut(), |f| f as *mut ::libc::c_void)) - .into()], + &[ + (Some(negate_1).map_or(::std::ptr::null_mut(), |f| f as *mut ::libc::c_void)) + .into(), + ], ) }) == (-7_i32)) as i32) != 0) @@ -78,9 +80,10 @@ unsafe fn main_0() -> i32 { apply_binary_4( 3, 4, - &[(Some(add_2 as unsafe fn(i32, i32) -> i32) - .map_or(::std::ptr::null_mut(), |f| f as *mut ::libc::c_void)) - .into()], + &[ + (Some(add_2).map_or(::std::ptr::null_mut(), |f| f as *mut ::libc::c_void)) + .into(), + ], ) }) == (7)) as i32) != 0) @@ -92,7 +95,7 @@ unsafe fn main_0() -> i32 { ((&mut dummy as *mut i32) as *mut i32 as *mut ::libc::c_void); let _extra: *mut ::libc::c_void = ((&mut dummy as *mut i32) as *mut i32 as *mut ::libc::c_void); - not_supported_5(_ctx, Some(square_0 as unsafe fn(i32) -> i32), _extra) + not_supported_5(_ctx, Some(square_0), _extra) }) == (-3_i32)) as i32) != 0) ); diff --git a/tests/unit/out/unsafe/void_cast.rs b/tests/unit/out/unsafe/void_cast.rs index 0d6b373e..aea1827d 100644 --- a/tests/unit/out/unsafe/void_cast.rs +++ b/tests/unit/out/unsafe/void_cast.rs @@ -84,10 +84,10 @@ unsafe fn main_0() -> i32 { assert!(((chosen) == (123))); &(bump_and_return_4); assert!(((side_effect_counter_3) == (2))); - &(Some(bump_and_return_4 as unsafe fn() -> i32)); + &(Some(bump_and_return_4)); assert!(((side_effect_counter_3) == (2))); &(std::mem::transmute:: i32>, Option i32>>( - (Some(bump_and_return_4 as unsafe fn() -> i32)), + (Some(bump_and_return_4)), )); assert!(((side_effect_counter_3) == (2))); let mut storage: i32 = 11;