From 0b1a1f5181fdc3541397bef00a42245fb3817a3c Mon Sep 17 00:00:00 2001 From: xinchengxx <2240131203@qq.com> Date: Tue, 11 Mar 2025 19:12:28 +0800 Subject: [PATCH] Fix code generation to comply with rfc 2585 --- engine/src/conversion/analysis/fun/mod.rs | 7 ------- .../src/conversion/codegen_rs/fun_codegen.rs | 21 +++++++++++-------- engine/src/lib.rs | 4 ++-- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/engine/src/conversion/analysis/fun/mod.rs b/engine/src/conversion/analysis/fun/mod.rs index 6ad07ef2c..07c7eb75f 100644 --- a/engine/src/conversion/analysis/fun/mod.rs +++ b/engine/src/conversion/analysis/fun/mod.rs @@ -108,9 +108,6 @@ pub(crate) struct TraitMethodDetails { /// interface, we may need to reorder the parameters to fit that /// interface. pub(crate) parameter_reordering: Option>, - /// The function we're calling from the trait requires unsafe even - /// though the trait and its function aren't. - pub(crate) trait_call_is_unsafe: bool, } #[derive(Clone, Debug)] @@ -894,7 +891,6 @@ impl<'a> FnAnalyzer<'a> { avoid_self: true, method_name: make_ident(method_name), parameter_reordering: Some(vec![1, 0]), - trait_call_is_unsafe: false, }), }, error_context, @@ -930,7 +926,6 @@ impl<'a> FnAnalyzer<'a> { avoid_self: false, method_name: make_ident("drop"), parameter_reordering: None, - trait_call_is_unsafe: false, }), }, error_context, @@ -1582,7 +1577,6 @@ impl<'a> FnAnalyzer<'a> { avoid_self: false, method_name, parameter_reordering: None, - trait_call_is_unsafe: false, }), }, ErrorContext::new_for_item(make_ident(&rust_name)), @@ -1626,7 +1620,6 @@ impl<'a> FnAnalyzer<'a> { avoid_self: false, method_name: make_ident(method_name), parameter_reordering: None, - trait_call_is_unsafe: false, }), kind, }, diff --git a/engine/src/conversion/codegen_rs/fun_codegen.rs b/engine/src/conversion/codegen_rs/fun_codegen.rs index 9e00da576..4317fb56e 100644 --- a/engine/src/conversion/codegen_rs/fun_codegen.rs +++ b/engine/src/conversion/codegen_rs/fun_codegen.rs @@ -109,16 +109,12 @@ pub(super) fn gen_function( let mut cpp_name_attr = Vec::new(); let mut impl_entry = None; let mut trait_impl_entry = None; - let always_unsafe_due_to_trait_definition = match kind { - FnKind::TraitMethod { ref details, .. } => details.trait_call_is_unsafe, - _ => false, - }; + let fn_generator = FnGenerator { param_details: ¶m_details, cxxbridge_name: &cxxbridge_name, rust_name, unsafety: &analysis.requires_unsafe, - always_unsafe_due_to_trait_definition, doc_attrs: &doc_attrs, non_pod_types, ret_type: &ret_type, @@ -229,7 +225,6 @@ struct FnGenerator<'a> { cxxbridge_name: &'a Ident, rust_name: &'a str, unsafety: &'a UnsafetyNeeded, - always_unsafe_due_to_trait_definition: bool, doc_attrs: &'a Vec, non_pod_types: &'a HashSet, } @@ -309,10 +304,18 @@ impl<'a> FnGenerator<'a> { quote! { cxxbridge::#cxxbridge_name ( #(#arg_list),* ) }, - any_conversion_requires_unsafe || matches!(self.unsafety, UnsafetyNeeded::JustBridge), + any_conversion_requires_unsafe + || matches!( + self.unsafety, + UnsafetyNeeded::JustBridge | UnsafetyNeeded::Always + ), ); - let context_is_unsafe = matches!(self.unsafety, UnsafetyNeeded::Always) - || self.always_unsafe_due_to_trait_definition; + + // Per RFC 2585 (https://rust-lang.github.io/rfcs/2585-unsafe-block-in-unsafe-fn.html), + // all calls to unsafe functions must be wrapped in an unsafe block, even within an unsafe function. + // Therefore, the outer context is always treated as "safe" (false), ensuring proper unsafe blocks + // are generated around unsafe operations. + let context_is_unsafe = false; let (call_body, ret_type) = match self.ret_conversion { Some(ret_conversion) if ret_conversion.rust_work_needed() => { // There's a potential lurking bug below. If the return type conversion requires diff --git a/engine/src/lib.rs b/engine/src/lib.rs index 26a126de8..18857e1e1 100644 --- a/engine/src/lib.rs +++ b/engine/src/lib.rs @@ -367,7 +367,8 @@ impl IncludeCppEngine { .raw_line(raw_line) .every_module_raw_line(all_module_raw_line) .generate_private_functions(true) - .layout_tests(false); // TODO revisit later + .layout_tests(false) // TODO revisit later + .wrap_unsafe_ops(true); // 3. Passes allowlist and other options to the bindgen::Builder equivalent // to --output-style=cxx --allowlist= @@ -519,7 +520,6 @@ impl IncludeCppEngine { #[allow(dead_code)] #[allow(non_upper_case_globals)] #[allow(non_camel_case_types)] - #[allow(unsafe_op_in_unsafe_fn)] #[doc = "Generated using autocxx - do not edit directly"] #[doc = "@generated"] mod #mod_name {