Use local variables to extend lifetime of holder references.
This commit is contained in:
parent
1dca87972a
commit
27019b5523
|
@ -35,16 +35,18 @@ pub fn impl_arg_params(
|
|||
if !fastcall && is_forwarded_args(&spec.signature) {
|
||||
// In the varargs convention, we can just pass though if the signature
|
||||
// is (*args, **kwds).
|
||||
let mut holders = Vec::new();
|
||||
let arg_convert = spec
|
||||
.signature
|
||||
.arguments
|
||||
.iter()
|
||||
.map(|arg| impl_arg_param(arg, &mut 0, &args_array))
|
||||
.map(|arg| impl_arg_param(arg, &mut 0, &args_array, &mut holders))
|
||||
.collect::<Result<_>>()?;
|
||||
return Ok((
|
||||
quote! {
|
||||
let _args = py.from_borrowed_ptr::<_pyo3::types::PyTuple>(_args);
|
||||
let _kwargs: ::std::option::Option<&_pyo3::types::PyDict> = py.from_borrowed_ptr_or_opt(_kwargs);
|
||||
#( #holders )*
|
||||
},
|
||||
arg_convert,
|
||||
));
|
||||
|
@ -73,11 +75,12 @@ pub fn impl_arg_params(
|
|||
let num_params = positional_parameter_names.len() + keyword_only_parameters.len();
|
||||
|
||||
let mut option_pos = 0;
|
||||
let mut holders = Vec::new();
|
||||
let param_conversion = spec
|
||||
.signature
|
||||
.arguments
|
||||
.iter()
|
||||
.map(|arg| impl_arg_param(arg, &mut option_pos, &args_array))
|
||||
.map(|arg| impl_arg_param(arg, &mut option_pos, &args_array, &mut holders))
|
||||
.collect::<Result<_>>()?;
|
||||
|
||||
let args_handler = if spec.signature.python_signature.varargs.is_some() {
|
||||
|
@ -130,8 +133,8 @@ pub fn impl_arg_params(
|
|||
required_positional_parameters: #required_positional_parameters,
|
||||
keyword_only_parameters: &[#(#keyword_only_parameters),*],
|
||||
};
|
||||
|
||||
let mut #args_array = [::std::option::Option::None; #num_params];
|
||||
#( #holders )*
|
||||
let (_args, _kwargs) = #extract_expression;
|
||||
},
|
||||
param_conversion,
|
||||
|
@ -144,6 +147,7 @@ fn impl_arg_param(
|
|||
arg: &FnArg<'_>,
|
||||
option_pos: &mut usize,
|
||||
args_array: &syn::Ident,
|
||||
holders: &mut Vec<TokenStream>,
|
||||
) -> Result<TokenStream> {
|
||||
// Use this macro inside this function, to ensure that all code generated here is associated
|
||||
// with the function argument
|
||||
|
@ -162,15 +166,25 @@ fn impl_arg_param(
|
|||
let name = arg.name;
|
||||
let name_str = name.to_string();
|
||||
|
||||
let mut push_holder = || {
|
||||
let holder = syn::Ident::new(&format!("holder_{}", holders.len()), arg.ty.span());
|
||||
holders.push(quote_arg_span! {
|
||||
#[allow(clippy::let_unit_value)]
|
||||
let mut #holder = _pyo3::impl_::extract_argument::FunctionArgumentHolder::INIT;
|
||||
});
|
||||
holder
|
||||
};
|
||||
|
||||
if arg.is_varargs {
|
||||
ensure_spanned!(
|
||||
arg.optional.is_none(),
|
||||
arg.name.span() => "args cannot be optional"
|
||||
);
|
||||
let holder = push_holder();
|
||||
return Ok(quote_arg_span! {
|
||||
_pyo3::impl_::extract_argument::extract_argument(
|
||||
_args,
|
||||
&mut { _pyo3::impl_::extract_argument::FunctionArgumentHolder::INIT },
|
||||
&mut #holder,
|
||||
#name_str
|
||||
)?
|
||||
});
|
||||
|
@ -179,10 +193,11 @@ fn impl_arg_param(
|
|||
arg.optional.is_some(),
|
||||
arg.name.span() => "kwargs must be Option<_>"
|
||||
);
|
||||
let holder = push_holder();
|
||||
return Ok(quote_arg_span! {
|
||||
_pyo3::impl_::extract_argument::extract_optional_argument(
|
||||
_kwargs.map(::std::convert::AsRef::as_ref),
|
||||
&mut { _pyo3::impl_::extract_argument::FunctionArgumentHolder::INIT },
|
||||
&mut #holder,
|
||||
#name_str,
|
||||
|| ::std::option::Option::None
|
||||
)?
|
||||
|
@ -221,30 +236,33 @@ fn impl_arg_param(
|
|||
}
|
||||
}
|
||||
} else if arg.optional.is_some() {
|
||||
let holder = push_holder();
|
||||
quote_arg_span! {
|
||||
#[allow(clippy::redundant_closure)]
|
||||
_pyo3::impl_::extract_argument::extract_optional_argument(
|
||||
#arg_value,
|
||||
&mut { _pyo3::impl_::extract_argument::FunctionArgumentHolder::INIT },
|
||||
&mut #holder,
|
||||
#name_str,
|
||||
|| #default
|
||||
)?
|
||||
}
|
||||
} else if let Some(default) = default {
|
||||
let holder = push_holder();
|
||||
quote_arg_span! {
|
||||
#[allow(clippy::redundant_closure)]
|
||||
_pyo3::impl_::extract_argument::extract_argument_with_default(
|
||||
#arg_value,
|
||||
&mut { _pyo3::impl_::extract_argument::FunctionArgumentHolder::INIT },
|
||||
&mut #holder,
|
||||
#name_str,
|
||||
|| #default
|
||||
)?
|
||||
}
|
||||
} else {
|
||||
let holder = push_holder();
|
||||
quote_arg_span! {
|
||||
_pyo3::impl_::extract_argument::extract_argument(
|
||||
_pyo3::impl_::extract_argument::unwrap_required_argument(#arg_value),
|
||||
&mut { _pyo3::impl_::extract_argument::FunctionArgumentHolder::INIT },
|
||||
&mut #holder,
|
||||
#name_str
|
||||
)?
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue