Skip to content

Commit d1d7d70

Browse files
committed
refactor generate_varargs_trait
1 parent 35c9c5e commit d1d7d70

File tree

1 file changed

+75
-44
lines changed

1 file changed

+75
-44
lines changed

src/codegen/mod.rs

Lines changed: 75 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -4520,50 +4520,7 @@ pub(crate) fn codegen(
45204520
}
45214521

45224522
if let Some(max_len) = context.options().tuple_varargs_len {
4523-
let mut methods = Vec::with_capacity(result.variadic_methods.len());
4524-
let mut impls = (0..=max_len)
4525-
.map(|len| {
4526-
(
4527-
(0..len)
4528-
.map(|len| quote::format_ident!("t{}", len))
4529-
.collect::<Vec<_>>(),
4530-
vec![],
4531-
)
4532-
})
4533-
.collect::<Vec<_>>();
4534-
for (name, VariadicMethodInfo { args, ret, exprs }) in
4535-
result.variadic_methods.drain()
4536-
{
4537-
let call_name = quote::format_ident!("call_{}", name);
4538-
methods.push(quote! {
4539-
unsafe fn #call_name(self, #(#args),*) #ret
4540-
});
4541-
4542-
for (fields, methods) in &mut impls {
4543-
methods.push(quote! {
4544-
unsafe fn #call_name(self, #(#args),*) #ret {
4545-
let (#(#fields,)*) = self;
4546-
#name(#(#exprs),*, #(#fields),*)
4547-
}
4548-
});
4549-
}
4550-
}
4551-
result.items.push(quote! {
4552-
pub trait VarArgs {
4553-
#(#methods;)*
4554-
}
4555-
});
4556-
4557-
for (fields, methods) in impls {
4558-
let params = (0..fields.len())
4559-
.map(|len| quote::format_ident!("T{}", len))
4560-
.collect::<Vec<_>>();
4561-
result.items.push(quote! {
4562-
impl<#(#params),*> VarArgs for (#(#params,)*) {
4563-
#(#methods)*
4564-
}
4565-
});
4566-
}
4523+
utils::generate_varargs_trait(max_len, &mut result);
45674524
}
45684525

45694526
postprocessing::postprocessing(result.items, context.options())
@@ -5105,4 +5062,78 @@ pub mod utils {
51055062

51065063
true
51075064
}
5065+
5066+
pub(super) fn generate_varargs_trait(
5067+
max_len: usize,
5068+
result: &mut super::CodegenResult,
5069+
) {
5070+
// This will hold the identifiers to be used for the fields of the tuples `t0, ..., tn` as
5071+
// well as the identifiers of the type parameters for each field type of the tuples `T0, ..., TN`.
5072+
// FIXME (pvdrz): what if these identifiers are already in use?
5073+
let (fields, params): (Vec<_>, Vec<_>) = (0..max_len)
5074+
.map(|len| {
5075+
(
5076+
quote::format_ident!("t{}", len),
5077+
quote::format_ident!("T{}", len),
5078+
)
5079+
})
5080+
.unzip();
5081+
5082+
// This will hold the methods to be declared in the `VarArgs` trait as well as the
5083+
// bodies of the implementations of such methods for each tuple length.
5084+
let (trait_method_decls, trait_method_impl_fns): (Vec<_>, Vec<_>) =
5085+
result
5086+
.variadic_methods
5087+
.drain()
5088+
.map(|(name, info)| {
5089+
let super::VariadicMethodInfo { args, ret, exprs } = info;
5090+
5091+
// The name of the `VarArgs` trait method associated with this method.
5092+
// FIXME (pvdrz): what these identifiers are already in use?
5093+
let trait_method_name =
5094+
quote::format_ident!("call_{}", name);
5095+
5096+
// The declaration of the `VarArgs` trait method associated with this method.
5097+
let trait_method_decl = quote! {
5098+
unsafe fn #trait_method_name(self, #(#args),*) #ret
5099+
};
5100+
5101+
// The implementations of the `VarArgs` trait method associated with this
5102+
// method for each tuple length.
5103+
let trait_method_impls = (0..=fields.len())
5104+
.map(|index| {
5105+
let fields = &fields[..index];
5106+
quote! {
5107+
#trait_method_decl {
5108+
let (#(#fields,)*) = self;
5109+
#name(#(#exprs),*, #(#fields),*)
5110+
}
5111+
}
5112+
})
5113+
.collect::<Vec<_>>();
5114+
5115+
(trait_method_decl, trait_method_impls)
5116+
})
5117+
.unzip();
5118+
5119+
// Push the trait with the method declarations.
5120+
result.items.push(quote! {
5121+
pub trait VarArgs {
5122+
#(#trait_method_decls;)*
5123+
}
5124+
});
5125+
5126+
for index in 0..=params.len() {
5127+
let params = &params[..index];
5128+
let methods =
5129+
trait_method_impl_fns.iter().map(|impls| &impls[index]);
5130+
5131+
// Push the implementation the trait for each tuple.
5132+
result.items.push(quote! {
5133+
impl<#(#params),*> VarArgs for (#(#params,)*) {
5134+
#(#methods)*
5135+
}
5136+
});
5137+
}
5138+
}
51085139
}

0 commit comments

Comments
 (0)