Skip to content

Commit

Permalink
Remove lifetime from impl blocks; add to fns.
Browse files Browse the repository at this point in the history
Previously we parameterized some impl blocks by <'a>.
Instead, parameterize each function individually.
  • Loading branch information
adetaylor committed Jan 21, 2025
1 parent 356c442 commit ee104e6
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 76 deletions.
7 changes: 0 additions & 7 deletions engine/src/conversion/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -719,10 +719,3 @@ impl<T: AnalysisPhase> Api<T> {
Ok(Box::new(std::iter::once(Api::Enum { name, item })))
}
}

/// Whether a type is a pointer of some kind.
pub(crate) enum Pointerness {
Not,
ConstPtr,
MutPtr,
}
12 changes: 0 additions & 12 deletions engine/src/conversion/codegen_cpp/function_wrapper_cpp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use syn::{Type, TypePtr};

use crate::conversion::{
analysis::fun::function_wrapper::{CppConversionType, TypeConversionPolicy},
api::Pointerness,
ConvertErrorFromCpp,
};

Expand Down Expand Up @@ -63,17 +62,6 @@ impl TypeConversionPolicy {
cpp_name_map.type_to_cpp(self.cxxbridge_type())
}

pub(crate) fn is_a_pointer(&self) -> Pointerness {
match self.cxxbridge_type() {
Type::Ptr(TypePtr {
mutability: Some(_),
..
}) => Pointerness::MutPtr,
Type::Ptr(_) => Pointerness::ConstPtr,
_ => Pointerness::Not,
}
}

fn unique_ptr_wrapped_type(
&self,
original_name_map: &CppNameMap,
Expand Down
37 changes: 5 additions & 32 deletions engine/src/conversion/codegen_rs/fun_codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use autocxx_parser::IncludeCppConfig;
use indexmap::set::IndexSet as HashSet;
use std::borrow::Cow;

Expand All @@ -24,15 +23,15 @@ use super::{
function_wrapper_rs::RustParamConversion,
maybe_unsafes_to_tokens,
unqualify::{unqualify_params, unqualify_ret_type},
ImplBlockDetails, ImplBlockKey, MaybeUnsafeStmt, RsCodegenResult, TraitImplBlockDetails, Use,
ImplBlockDetails, MaybeUnsafeStmt, RsCodegenResult, TraitImplBlockDetails, Use,
};
use crate::{
conversion::{
analysis::fun::{
function_wrapper::TypeConversionPolicy, ArgumentAnalysis, FnAnalysis, FnKind,
MethodKind, RustRenameStrategy, TraitMethodDetails,
},
api::{Pointerness, UnsafetyNeeded},
api::UnsafetyNeeded,
},
minisyn::minisynize_vec,
types::{Namespace, QualifiedName},
Expand Down Expand Up @@ -91,13 +90,13 @@ pub(super) fn gen_function(
analysis: FnAnalysis,
cpp_call_name: String,
non_pod_types: &HashSet<QualifiedName>,
config: &IncludeCppConfig,
) -> RsCodegenResult {
if analysis.ignore_reason.is_err() || !analysis.externally_callable {
return RsCodegenResult::default();
}
let cxxbridge_name = analysis.cxxbridge_name;
let rust_name = &analysis.rust_name;
eprintln!("GENERATING {rust_name}");
let ret_type = analysis.ret_type;
let ret_conversion = analysis.ret_conversion;
let param_details = analysis.param_details;
Expand Down Expand Up @@ -125,7 +124,6 @@ pub(super) fn gen_function(
non_pod_types,
ret_type: &ret_type,
ret_conversion: &ret_conversion,
reference_wrappers: config.unsafe_policy.requires_cpprefs(),
};
// In rare occasions, we might need to give an explicit lifetime.
let (lifetime_tokens, params, ret_type) = add_explicit_lifetime_if_necessary(
Expand Down Expand Up @@ -239,7 +237,6 @@ struct FnGenerator<'a> {
always_unsafe_due_to_trait_definition: bool,
doc_attrs: &'a Vec<Attribute>,
non_pod_types: &'a HashSet<QualifiedName>,
reference_wrappers: bool,
}

impl<'a> FnGenerator<'a> {
Expand Down Expand Up @@ -396,39 +393,15 @@ impl<'a> FnGenerator<'a> {
let rust_name = make_ident(self.rust_name);
let unsafety = self.unsafety.wrapper_token();
let doc_attrs = self.doc_attrs;
let receiver_pointerness = self
.param_details
.iter()
.next()
.map(|pd| pd.conversion.is_a_pointer())
.unwrap_or(Pointerness::Not);
let ty = impl_block_type_name.get_final_ident();
let ty = match receiver_pointerness {
Pointerness::MutPtr if self.reference_wrappers => ImplBlockKey {
ty: parse_quote! {
#ty
},
lifetime: Some(parse_quote! { 'a }),
},
Pointerness::ConstPtr if self.reference_wrappers => ImplBlockKey {
ty: parse_quote! {
#ty
},
lifetime: Some(parse_quote! { 'a }),
},
_ => ImplBlockKey {
ty: parse_quote! { # ty },
lifetime: None,
},
};
Box::new(ImplBlockDetails {
item: ImplItem::Fn(parse_quote! {
#(#doc_attrs)*
pub #unsafety fn #rust_name #lifetime_tokens ( #wrapper_params ) #ret_type {
#call_body
}
}),
ty,
ty: parse_quote! { # ty },
})
}

Expand Down Expand Up @@ -471,7 +444,7 @@ impl<'a> FnGenerator<'a> {
};
Box::new(ImplBlockDetails {
item: ImplItem::Fn(parse_quote! { #stuff }),
ty: ImplBlockKey { ty, lifetime: None },
ty,
})
}

Expand Down
21 changes: 13 additions & 8 deletions engine/src/conversion/codegen_rs/lifetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use syn::{
/// built-in type
/// 3) Any parameter is any form of reference, and we're returning an `impl New`
/// 3a) an 'impl ValueParam' counts as a reference.
/// 4) If we're using CppRef<'a, T> as a return type
/// 4) If we're using CppRef<'a, T> as a param or return type
pub(crate) fn add_explicit_lifetime_if_necessary<'r>(
param_details: &[ArgumentAnalysis],
mut params: Punctuated<FnArg, Comma>,
Expand All @@ -56,6 +56,13 @@ pub(crate) fn add_explicit_lifetime_if_necessary<'r>(
RustConversionType::FromValueParamToPtr
)
});

let any_param_is_cppref = param_details.iter().any(|pd| {
matches!(
pd.conversion.rust_conversion,
RustConversionType::FromReferenceWrapperToPointer
)
});
let return_type_is_impl = return_type_is_impl(&ret_type);
let return_type_is_cppref = matches!(
ret_conversion,
Expand All @@ -71,7 +78,8 @@ pub(crate) fn add_explicit_lifetime_if_necessary<'r>(
if !(has_mutable_receiver
|| hits_1024_bug
|| returning_impl_with_a_reference_param
|| return_type_is_cppref)
|| return_type_is_cppref
|| any_param_is_cppref)
{
return (None, params, ret_type);
}
Expand All @@ -97,18 +105,15 @@ pub(crate) fn add_explicit_lifetime_if_necessary<'r>(
#rarrow #old_tyit + 'a
})
}
Type::Ptr(_) if return_type_is_cppref => {
// The ptr will be converted to CppRef<'a, T> elsewhere, so we
// just need to return the return type as-is such that the
// next match statement adds <'a> to the function.
Some(ret_type.clone().into_owned())
}
_ => None,
},
_ => None,
};

match new_return_type {
None if return_type_is_cppref || any_param_is_cppref => {
(Some(quote! { <'a> }), params, ret_type)
}
None => (None, params, ret_type),
Some(new_return_type) => {
for FnArg::Typed(PatType { ty, .. }) | FnArg::Receiver(syn::Receiver { ty, .. }) in
Expand Down
21 changes: 4 additions & 17 deletions engine/src/conversion/codegen_rs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ use itertools::Itertools;
use proc_macro2::{Span, TokenStream};
use syn::{
parse_quote, punctuated::Punctuated, token::Comma, Attribute, Expr, FnArg, ForeignItem,
ForeignItemFn, Ident, ImplItem, Item, ItemForeignMod, ItemMod, Lifetime, TraitItem, Type,
TypePath,
ForeignItemFn, Ident, ImplItem, Item, ItemForeignMod, ItemMod, TraitItem, Type, TypePath,
};

use crate::{
Expand Down Expand Up @@ -59,16 +58,10 @@ use super::{
use super::{convert_error::ErrorContext, ConvertErrorFromCpp};
use quote::quote;

#[derive(Clone, Hash, PartialEq, Eq)]
struct ImplBlockKey {
ty: Type,
lifetime: Option<Lifetime>,
}

/// An entry which needs to go into an `impl` block for a given type.
struct ImplBlockDetails {
item: ImplItem,
ty: ImplBlockKey,
ty: Type,
}

struct TraitImplBlockDetails {
Expand Down Expand Up @@ -412,10 +405,8 @@ impl<'a> RsCodeGenerator<'a> {
}
}
for (ty, entries) in impl_entries_by_type.into_iter() {
let lt = ty.lifetime.map(|lt| quote! { < #lt > });
let ty = ty.ty;
output_items.push(Item::Impl(parse_quote! {
impl #lt #ty {
impl #ty {
#(#entries)*
}
}))
Expand Down Expand Up @@ -494,7 +485,6 @@ impl<'a> RsCodeGenerator<'a> {
analysis,
cpp_call_name,
non_pod_types,
self.config,
),
Api::Const { const_item, .. } => RsCodegenResult {
bindgen_mod_items: vec![Item::Const(const_item.into())],
Expand Down Expand Up @@ -1095,10 +1085,7 @@ impl<'a> RsCodeGenerator<'a> {
fn #method(_uhoh: autocxx::BindingGenerationFailure) {
}
},
ty: ImplBlockKey {
ty: parse_quote! { #self_ty },
lifetime: None,
},
ty: parse_quote! { #self_ty },
})),
None,
None,
Expand Down

0 comments on commit ee104e6

Please sign in to comment.