1use proc_macro2::TokenStream;
133use syn::ItemTrait;
134
135pub fn expand_trait(
158 _attr: proc_macro::TokenStream,
159 item: proc_macro::TokenStream,
160) -> proc_macro::TokenStream {
161 let trait_item = match ::syn::parse::<ItemTrait>(item) {
::syn::__private::Ok(data) => data,
::syn::__private::Err(err) => {
return ::syn::__private::TokenStream::from(err.to_compile_error());
}
}syn::parse_macro_input!(item as ItemTrait);
162
163 if let Err(e) = validate_trait(&trait_item) {
165 return e.into_compile_error().into();
166 }
167
168 let expanded = generate_trait_abi(&trait_item);
170
171 expanded.into()
172}
173
174fn validate_trait(trait_item: &ItemTrait) -> syn::Result<()> {
183 let trait_name = &trait_item.ident;
184
185 for item in &trait_item.items {
187 if let syn::TraitItem::Fn(method) = item {
188 validate_method(method, trait_name)?;
189 }
190 }
191
192 Ok(())
193}
194
195fn validate_method(method: &syn::TraitItemFn, trait_name: &syn::Ident) -> syn::Result<()> {
201 let method_name = &method.sig.ident;
202
203 if method.sig.asyncness.is_some() {
205 return Err(syn::Error::new_spanned(
206 method.sig.asyncness,
207 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("#[miniextendr] trait `{0}::{1}` cannot be async",
trait_name, method_name))
})format!(
208 "#[miniextendr] trait `{}::{}` cannot be async",
209 trait_name, method_name
210 ),
211 ));
212 }
213
214 {
218 let has_type_or_const = method
219 .sig
220 .generics
221 .params
222 .iter()
223 .any(|p| #[allow(non_exhaustive_omitted_patterns)] match p {
syn::GenericParam::Type(_) | syn::GenericParam::Const(_) => true,
_ => false,
}matches!(p, syn::GenericParam::Type(_) | syn::GenericParam::Const(_)));
224 if has_type_or_const {
225 return Err(syn::Error::new_spanned(
226 &method.sig.generics,
227 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("#[miniextendr] trait method `{0}::{1}` cannot have generic type or const parameters",
trait_name, method_name))
})format!(
228 "#[miniextendr] trait method `{}::{}` cannot have generic type or const parameters",
229 trait_name, method_name
230 ),
231 ));
232 }
233 }
234
235 let receiver = method.sig.inputs.first();
239 if let Some(syn::FnArg::Receiver(r)) = receiver {
240 let is_ref = if r.reference.is_some() {
244 true
245 } else if r.colon_token.is_some() {
246 #[allow(non_exhaustive_omitted_patterns)] match r.ty.as_ref() {
syn::Type::Reference(_) => true,
_ => false,
}matches!(r.ty.as_ref(), syn::Type::Reference(_))
248 } else {
249 false
250 };
251
252 if !is_ref && crate::trait_receiver::owner_receiver(&method.sig).is_none() {
253 return Err(syn::Error::new_spanned(
254 r,
255 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("#[miniextendr] trait method `{0}::{1}` receiver must be `&self` or `&mut self`, not `self` by value",
trait_name, method_name))
})format!(
256 "#[miniextendr] trait method `{}::{}` receiver must be `&self` or `&mut self`, not `self` by value",
257 trait_name, method_name
258 ),
259 ));
260 }
261 }
262 crate::miniextendr_fn::refuse_lazy_dots_in_trait_method(&method.sig.inputs)?;
267 crate::miniextendr_fn::refuse_rng_guard_in_trait_method(&method.sig.inputs)?;
268
269 Ok(())
270}
271
272fn generate_trait_abi(trait_item: &ItemTrait) -> TokenStream {
281 let trait_name = &trait_item.ident;
282 let vis = &trait_item.vis;
283
284 let tag_name = crate::naming::trait_tag_ident(trait_name);
286 let vtable_name = match ::quote::__private::IdentFragmentAdapter(&trait_name) {
arg =>
::quote::__private::mk_ident(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}VTable", arg))
}), ::quote::__private::Option::None.or(arg.span())),
}quote::format_ident!("{}VTable", trait_name);
287 let view_name = match ::quote::__private::IdentFragmentAdapter(&trait_name) {
arg =>
::quote::__private::mk_ident(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}View", arg))
}), ::quote::__private::Option::None.or(arg.span())),
}quote::format_ident!("{}View", trait_name);
288 let build_vtable_fn = crate::naming::trait_vtable_builder_ident(trait_name);
289
290 let trait_type_params: Vec<&syn::GenericParam> = trait_item.generics.params.iter().collect();
292 let trait_param_idents: Vec<&syn::Ident> = trait_type_params
293 .iter()
294 .filter_map(|p| {
295 if let syn::GenericParam::Type(tp) = p {
296 Some(&tp.ident)
297 } else {
298 None
299 }
300 })
301 .collect();
302 let has_generics = !trait_item.generics.params.is_empty();
303
304 let assoc_types: Vec<&syn::Ident> = trait_item
306 .items
307 .iter()
308 .filter_map(|item| {
309 if let syn::TraitItem::Type(t) = item {
310 Some(&t.ident)
311 } else {
312 None
313 }
314 })
315 .collect();
316
317 let trait_where_clause = &trait_item.generics.where_clause;
319
320 let methods: Vec<_> = {
323 let mut collected = Vec::new();
324 for item in &trait_item.items {
325 if let syn::TraitItem::Fn(method) = item {
326 let info = match extract_method_info(method) {
327 Ok(info) => info,
328 Err(e) => return e.into_compile_error(),
329 };
330 if info.has_self && !info.skip {
331 collected.push(info);
332 }
333 }
334 }
335 collected
336 }
337 .into_iter()
338 .collect();
339
340 let tag_path = trait_abi_tag_path(trait_name, &methods);
344
345 let vtable_fields: Vec<_> = methods
347 .iter()
348 .map(|m| {
349 let name = &m.name;
350 let abi = if m.owner_receiver.is_some() {
351 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "abi");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "mx_owner_meth");
_s
}quote::quote!(::miniextendr_api::abi::mx_owner_meth)
352 } else {
353 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "abi");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "mx_meth");
_s
}quote::quote!(::miniextendr_api::abi::mx_meth)
354 };
355 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "pub");
::quote::ToTokens::to_tokens(&name, &mut _s);
::quote::__private::push_colon(&mut _s);
::quote::ToTokens::to_tokens(&abi, &mut _s);
_s
}quote::quote! { pub #name: #abi }
356 })
357 .collect();
358
359 let extra_bounds =
361 compute_extra_bounds(&methods, trait_name, &assoc_types, &trait_param_idents);
362
363 let impl_t = ::quote::__private::mk_ident(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("__ImplT"))
}), ::quote::__private::Option::None)quote::format_ident!("__ImplT");
365 let trait_bound = if trait_param_idents.is_empty() {
366 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&trait_name, &mut _s);
_s
}quote::quote! { #trait_name }
367 } else {
368 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&trait_name, &mut _s);
::quote::__private::push_lt(&mut _s);
{
use ::quote::__private::ext::*;
let mut _first = true;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut trait_param_idents, i) =
trait_param_idents.quote_into_iter();
let has_iter = has_iter | i;
<_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let trait_param_idents =
match trait_param_idents.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
if !_first { ::quote::__private::push_comma(&mut _s); }
_first = false;
::quote::ToTokens::to_tokens(&trait_param_idents, &mut _s);
}
}
::quote::__private::push_gt(&mut _s);
_s
}quote::quote! { #trait_name<#(#trait_param_idents),*> }
369 };
370
371 let all_where_predicates = build_where_predicates(trait_where_clause, &extra_bounds);
373 let where_clause = if all_where_predicates.is_empty() {
374 ::quote::__private::TokenStream::new();quote::quote! {}
375 } else {
376 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "where");
{
use ::quote::__private::ext::*;
let mut _first = true;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut all_where_predicates, i) =
all_where_predicates.quote_into_iter();
let has_iter = has_iter | i;
<_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let all_where_predicates =
match all_where_predicates.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
if !_first { ::quote::__private::push_comma(&mut _s); }
_first = false;
::quote::ToTokens::to_tokens(&all_where_predicates, &mut _s);
}
}
_s
}quote::quote! { where #(#all_where_predicates),* }
377 };
378
379 let vtable_inits: Vec<_> = methods
381 .iter()
382 .map(|m| {
383 let name = &m.name;
384 let shim_name = crate::naming::trait_method_shim_ident(trait_name, name);
385 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&name, &mut _s);
::quote::__private::push_colon(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&impl_t, &mut _s);
::quote::__private::push_ident(&mut _s, "as");
::quote::ToTokens::to_tokens(&trait_bound, &mut _s);
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::ToTokens::to_tokens(&shim_name, &mut _s);
_s
}quote::quote! {
386 #name: <#impl_t as #trait_bound>::#shim_name
387 }
388 })
389 .collect();
390
391 let view_methods: Vec<_> = if has_generics {
394 ::alloc::vec::Vec::new()vec![]
395 } else {
396 methods.iter().filter_map(generate_view_method).collect()
397 };
398
399 let mut clean_trait = trait_item.clone();
401 for item in &mut clean_trait.items {
402 if let syn::TraitItem::Fn(method) = item {
403 method
404 .attrs
405 .retain(|attr| !attr.path().is_ident("miniextendr"));
406 crate::trait_receiver::rewrite(&mut method.sig, method.default.as_mut());
407 }
408 }
409
410 if !has_generics {
414 clean_trait.items.extend(methods.iter().map(|m| {
415 syn::TraitItem::Fn(associated_method_shim(generate_method_shim(
416 trait_name,
417 m,
418 &extra_bounds,
419 &trait_param_idents,
420 &trait_type_params,
421 trait_where_clause,
422 )))
423 }));
424 }
425
426 let trait_name_str = trait_name.to_string();
427 let source_loc_doc = crate::source_location_doc(trait_name.span());
428
429 let impl_bounds = &extra_bounds.impl_bounds;
430
431 let view_tokens = if has_generics {
433 ::quote::__private::TokenStream::new();quote::quote! {}
434 } else {
435 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "concat");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::parse(&mut _s,
"\"Runtime view for objects implementing `\"");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "stringify");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&trait_name, &mut _s);
_s
});
::quote::__private::push_comma(&mut _s);
::quote::__private::parse(&mut _s, "\"`.\"");
_s
});
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::ToTokens::to_tokens(&source_loc_doc, &mut _s);
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "concat");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::parse(&mut _s,
"\"Generated from source file `\"");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "file");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
::quote::__private::TokenStream::new());
::quote::__private::push_comma(&mut _s);
::quote::__private::parse(&mut _s, "\"`.\"");
_s
});
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s, "r\"\"");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s,
"r\" Keeps the receiver alive for method dispatch. Use `try_from_sexp`\"");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s,
"r\" to create a view with its own root for the R external pointer.\"");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s,
"r\" Construction, use and drop belong on R\'s main thread.\"");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "allow");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s,
"non_camel_case_types");
_s
});
_s
});
::quote::ToTokens::to_tokens(&vis, &mut _s);
::quote::__private::push_ident(&mut _s, "struct");
::quote::ToTokens::to_tokens(&view_name, &mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "__mx_view");
::quote::__private::push_colon(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "trait_abi");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "TraitViewData");
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&vtable_name, &mut _s);
::quote::__private::push_gt(&mut _s);
::quote::__private::push_comma(&mut _s);
_s
});
::quote::__private::push_ident(&mut _s, "impl");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "TraitView");
::quote::__private::push_ident(&mut _s, "for");
::quote::ToTokens::to_tokens(&view_name, &mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "const");
::quote::__private::push_ident(&mut _s, "TAG");
::quote::__private::push_colon(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "abi");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "mx_tag");
::quote::__private::push_eq(&mut _s);
::quote::ToTokens::to_tokens(&tag_name, &mut _s);
::quote::__private::push_semi(&mut _s);
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "inline");
_s
});
::quote::__private::push_ident(&mut _s, "unsafe");
::quote::__private::push_ident(&mut _s, "fn");
::quote::__private::push_ident(&mut _s, "from_raw_parts");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "data");
::quote::__private::push_colon(&mut _s);
::quote::__private::push_star(&mut _s);
::quote::__private::push_ident(&mut _s, "mut");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "std");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "os");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "raw");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "c_void");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "vtable");
::quote::__private::push_colon(&mut _s);
::quote::__private::push_star(&mut _s);
::quote::__private::push_ident(&mut _s, "const");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "std");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "os");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "raw");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "c_void");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "owner");
::quote::__private::push_colon(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "option");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "Option");
::quote::__private::push_lt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "SEXP");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_comma(&mut _s);
_s
});
::quote::__private::push_rarrow(&mut _s);
::quote::__private::push_ident(&mut _s, "Self");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "Self");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "__mx_view");
::quote::__private::push_colon(&mut _s);
::quote::__private::push_ident(&mut _s, "unsafe");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "trait_abi");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "TraitViewData");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "new");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "data");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "vtable");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "owner");
_s
});
_s
});
::quote::__private::push_comma(&mut _s);
_s
});
_s
});
_s
});
::quote::__private::push_ident(&mut _s, "impl");
::quote::ToTokens::to_tokens(&view_name, &mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s,
"r\" Try to create a view from an R SEXP.\"");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s, "r\"\"");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s,
"r\" Returns `Some(Self)` if the object implements this trait,\"");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s,
"r\" `None` otherwise.\"");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s, "r\"\"");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s, "r\" # Safety\"");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s, "r\"\"");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s,
"r\" - `sexp` must be a valid R external pointer (EXTPTRSXP)\"");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s,
"r\" - The object must stay live through construction; the view then roots it\"");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s,
"r\" - A call that conflicts with one still running on the same object\"");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s,
"r\" raises the `miniextendr_borrow_conflict` error\"");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s,
"r\" - Construction, use and drop must all run on R\'s main thread\"");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "inline");
_s
});
::quote::__private::push_ident(&mut _s, "pub");
::quote::__private::push_ident(&mut _s, "unsafe");
::quote::__private::push_ident(&mut _s, "fn");
::quote::__private::push_ident(&mut _s, "try_from_sexp");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "sexp");
::quote::__private::push_colon(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "SEXP");
_s
});
::quote::__private::push_rarrow(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "option");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "Option");
::quote::__private::push_lt(&mut _s);
::quote::__private::push_ident(&mut _s, "Self");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "unsafe");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_lt(&mut _s);
::quote::__private::push_ident(&mut _s, "Self");
::quote::__private::push_ident(&mut _s, "as");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "TraitView");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "try_from_sexp");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "sexp");
_s
});
_s
});
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s,
"r\" Try to create a view, panicking with error message on failure.\"");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s, "r\"\"");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s, "r\" # Safety\"");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s, "r\"\"");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s,
"r\" Same as `try_from_sexp`.\"");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "inline");
_s
});
::quote::__private::push_ident(&mut _s, "pub");
::quote::__private::push_ident(&mut _s, "unsafe");
::quote::__private::push_ident(&mut _s, "fn");
::quote::__private::push_ident(&mut _s, "from_sexp");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "sexp");
::quote::__private::push_colon(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "SEXP");
_s
});
::quote::__private::push_rarrow(&mut _s);
::quote::__private::push_ident(&mut _s, "Self");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "unsafe");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "Self");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "try_from_sexp");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "sexp");
_s
});
_s
});
::quote::__private::push_dot(&mut _s);
::quote::__private::push_ident(&mut _s, "expect");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "concat");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::parse(&mut _s,
"\"Object does not implement \"");
::quote::__private::push_comma(&mut _s);
::quote::ToTokens::to_tokens(&trait_name_str, &mut _s);
::quote::__private::push_comma(&mut _s);
::quote::__private::parse(&mut _s, "\" trait\"");
_s
});
_s
});
_s
});
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut view_methods, i) = view_methods.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let view_methods =
match view_methods.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&view_methods, &mut _s);
}
}
_s
});
_s
}quote::quote! {
436 #[doc = ::core::concat!(
437 "Runtime view for objects implementing `",
438 ::core::stringify!(#trait_name),
439 "`."
440 )]
441 #[doc = #source_loc_doc]
442 #[doc = ::core::concat!("Generated from source file `", ::core::file!(), "`.")]
443 #[allow(non_camel_case_types)]
448 #vis struct #view_name {
449 __mx_view: ::miniextendr_api::trait_abi::TraitViewData<#vtable_name>,
450 }
451
452 impl ::miniextendr_api::TraitView for #view_name {
454 const TAG: ::miniextendr_api::abi::mx_tag = #tag_name;
455
456 #[inline]
457 unsafe fn from_raw_parts(
458 data: *mut ::std::os::raw::c_void,
459 vtable: *const ::std::os::raw::c_void,
460 owner: ::core::option::Option<::miniextendr_api::SEXP>,
461 ) -> Self {
462 Self {
463 __mx_view: unsafe {
464 ::miniextendr_api::trait_abi::TraitViewData::new(data, vtable, owner)
465 },
466 }
467 }
468 }
469
470 impl #view_name {
472 #[inline]
485 pub unsafe fn try_from_sexp(sexp: ::miniextendr_api::SEXP) -> ::core::option::Option<Self> {
486 unsafe { <Self as ::miniextendr_api::TraitView>::try_from_sexp(sexp) }
487 }
488
489 #[inline]
495 pub unsafe fn from_sexp(sexp: ::miniextendr_api::SEXP) -> Self {
496 unsafe { Self::try_from_sexp(sexp) }
497 .expect(::core::concat!("Object does not implement ", #trait_name_str, " trait"))
498 }
499
500 #(#view_methods)*
501 }
502 }
503 };
504
505 let shim_and_builder = if has_generics {
510 ::quote::__private::TokenStream::new();quote::quote! {}
511 } else {
512 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "concat");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::parse(&mut _s,
"\"Build a vtable for a concrete type implementing `\"");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "stringify");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&trait_name, &mut _s);
_s
});
::quote::__private::push_comma(&mut _s);
::quote::__private::parse(&mut _s, "\"`.\"");
_s
});
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::ToTokens::to_tokens(&source_loc_doc, &mut _s);
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "concat");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::parse(&mut _s,
"\"Generated from source file `\"");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "file");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
::quote::__private::TokenStream::new());
::quote::__private::push_comma(&mut _s);
::quote::__private::parse(&mut _s, "\"`.\"");
_s
});
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "allow");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "non_snake_case");
_s
});
_s
});
::quote::ToTokens::to_tokens(&vis, &mut _s);
::quote::__private::push_ident(&mut _s, "const");
::quote::__private::push_ident(&mut _s, "fn");
::quote::ToTokens::to_tokens(&build_vtable_fn, &mut _s);
::quote::__private::push_lt(&mut _s);
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut trait_type_params, i) = trait_type_params.quote_into_iter();
let has_iter = has_iter | i;
<_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let trait_type_params =
match trait_type_params.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&trait_type_params, &mut _s);
::quote::__private::push_comma(&mut _s);
}
}
::quote::ToTokens::to_tokens(&impl_t, &mut _s);
::quote::__private::push_colon(&mut _s);
::quote::ToTokens::to_tokens(&trait_bound, &mut _s);
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut impl_bounds, i) = impl_bounds.quote_into_iter();
let has_iter = has_iter | i;
<_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let impl_bounds =
match impl_bounds.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::__private::push_add(&mut _s);
::quote::ToTokens::to_tokens(&impl_bounds, &mut _s);
}
}
::quote::__private::push_gt(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
::quote::__private::TokenStream::new());
::quote::__private::push_rarrow(&mut _s);
::quote::ToTokens::to_tokens(&vtable_name, &mut _s);
::quote::ToTokens::to_tokens(&where_clause, &mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&vtable_name, &mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let mut _first = true;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut vtable_inits, i) = vtable_inits.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let vtable_inits =
match vtable_inits.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
if !_first { ::quote::__private::push_comma(&mut _s); }
_first = false;
::quote::ToTokens::to_tokens(&vtable_inits, &mut _s);
}
}
_s
});
_s
});
_s
}quote::quote! {
513 #[doc = ::core::concat!(
514 "Build a vtable for a concrete type implementing `",
515 ::core::stringify!(#trait_name),
516 "`."
517 )]
518 #[doc = #source_loc_doc]
519 #[doc = ::core::concat!("Generated from source file `", ::core::file!(), "`.")]
520 #[allow(non_snake_case)]
521 #vis const fn #build_vtable_fn<#(#trait_type_params,)* #impl_t: #trait_bound #(+ #impl_bounds)*>() -> #vtable_name
522 #where_clause
523 {
524 #vtable_name {
525 #(#vtable_inits),*
526 }
527 }
528 }
529 };
530
531 let mut method_metadata = Vec::new();
535 let mut tpie_method_metadata = Vec::new();
536 for item in &trait_item.items {
537 if let syn::TraitItem::Fn(method) = item {
538 let info = match extract_method_info(method) {
539 Ok(info) => info,
540 Err(e) => return e.into_compile_error(),
541 };
542 let name = &method.sig.ident;
543 let r_name_attr = info
544 .r_name
545 .as_ref()
546 .map(|name| {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "miniextendr");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "r_name");
::quote::__private::push_eq(&mut _s);
::quote::ToTokens::to_tokens(&name, &mut _s);
_s
});
_s
});
_s
}quote::quote!(#[miniextendr(r_name = #name)]));
547 let skip_attr = info.skip.then(|| {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "miniextendr");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "skip");
_s
});
_s
});
_s
}quote::quote!(#[miniextendr(skip)]));
548 let mut sig = method.sig.clone();
552 for (arg, name) in sig
553 .inputs
554 .iter_mut()
555 .filter_map(|arg| match arg {
556 syn::FnArg::Typed(arg) => Some(arg),
557 syn::FnArg::Receiver(_) => None,
558 })
559 .zip(&info.param_names)
560 {
561 *arg.pat = ::syn::__private::parse_quote({
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&name, &mut _s);
_s
})syn::parse_quote!(#name);
562 }
563 if method.default.is_some() {
569 let docs = method
570 .attrs
571 .iter()
572 .filter(|attr| attr.path().is_ident("doc"));
573 method_metadata.push({
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut docs, i) = docs.quote_into_iter();
let has_iter = has_iter | i;
<_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let docs =
match docs.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&docs, &mut _s);
}
}
::quote::ToTokens::to_tokens(&r_name_attr, &mut _s);
::quote::ToTokens::to_tokens(&skip_attr, &mut _s);
::quote::ToTokens::to_tokens(&sig, &mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
::quote::__private::TokenStream::new());
_s
}quote::quote! {
574 #(#docs)* #r_name_attr #skip_attr #sig {}
575 });
576 } else {
577 let params = &info.param_names;
578 method_metadata.push({
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&r_name_attr, &mut _s);
::quote::ToTokens::to_tokens(&skip_attr, &mut _s);
::quote::__private::push_ident(&mut _s, "fn");
::quote::ToTokens::to_tokens(&name, &mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let mut _first = true;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut params, i) = params.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let params =
match params.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
if !_first { ::quote::__private::push_comma(&mut _s); }
_first = false;
::quote::ToTokens::to_tokens(¶ms, &mut _s);
::quote::__private::push_colon(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
::quote::__private::TokenStream::new());
}
}
_s
});
::quote::__private::push_semi(&mut _s);
_s
}quote::quote! {
579 #r_name_attr #skip_attr fn #name(#(#params: ()),*);
580 });
581 }
582 if !has_generics && assoc_types.is_empty() && !info.skip {
583 let r_name = info
584 .r_name
585 .as_deref()
586 .map(crate::naming::name_ident)
587 .unwrap_or_else(|| name.clone());
588 tpie_method_metadata.push({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "method");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "r_name");
::quote::__private::push_eq(&mut _s);
::quote::ToTokens::to_tokens(&r_name, &mut _s);
::quote::__private::push_semi(&mut _s);
::quote::ToTokens::to_tokens(&sig, &mut _s);
::quote::__private::push_semi(&mut _s);
_s
});
_s
}quote::quote! {
589 method { r_name = #r_name; #sig; }
590 });
591 }
592 }
593 }
594 let abi_metadata = {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "abi");
::quote::ToTokens::to_tokens(&trait_name, &mut _s);
::quote::ToTokens::to_tokens(&has_generics, &mut _s);
::quote::ToTokens::to_tokens(&tag_path, &mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let mut _first = true;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut vtable_fields, i) = vtable_fields.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let vtable_fields =
match vtable_fields.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
if !_first { ::quote::__private::push_comma(&mut _s); }
_first = false;
::quote::ToTokens::to_tokens(&vtable_fields, &mut _s);
}
}
_s
});
_s
}quote::quote! {
597 abi #trait_name #has_generics #tag_path { #(#vtable_fields),* }
598 };
599 let empty_impl_arm = if !has_generics && assoc_types.is_empty() {
600 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::parse(&mut _s, "$");
::quote::__private::push_ident(&mut _s, "concrete_type");
::quote::__private::push_colon(&mut _s);
::quote::__private::push_ident(&mut _s, "ty");
::quote::__private::push_comma(&mut _s);
::quote::__private::parse(&mut _s, "$");
::quote::__private::push_ident(&mut _s, "trait_path");
::quote::__private::push_colon(&mut _s);
::quote::__private::push_ident(&mut _s, "path");
::quote::__private::push_comma(&mut _s);
::quote::__private::parse(&mut _s, "$");
::quote::__private::push_ident(&mut _s, "class_system");
::quote::__private::push_colon(&mut _s);
::quote::__private::push_ident(&mut _s, "ident");
::quote::__private::push_comma(&mut _s);
::quote::__private::parse(&mut _s, "$");
::quote::__private::push_ident(&mut _s, "no_rd");
::quote::__private::push_colon(&mut _s);
::quote::__private::push_ident(&mut _s, "tt");
::quote::__private::push_comma(&mut _s);
::quote::__private::parse(&mut _s, "$");
::quote::__private::push_ident(&mut _s, "internal");
::quote::__private::push_colon(&mut _s);
::quote::__private::push_ident(&mut _s, "tt");
::quote::__private::push_comma(&mut _s);
::quote::__private::parse(&mut _s, "$");
::quote::__private::push_ident(&mut _s, "noexport");
::quote::__private::push_colon(&mut _s);
::quote::__private::push_ident(&mut _s, "tt");
::quote::__private::push_comma(&mut _s);
::quote::__private::parse(&mut _s, "$");
::quote::__private::push_ident(&mut _s, "no_preconditions");
::quote::__private::push_colon(&mut _s);
::quote::__private::push_ident(&mut _s, "tt");
_s
});
::quote::__private::push_fat_arrow(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "__mx_trait_impl_expand");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "concrete_type");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s, "$");
::quote::__private::push_ident(&mut _s, "concrete_type");
::quote::__private::push_semi(&mut _s);
::quote::__private::push_ident(&mut _s, "trait_path");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s, "$");
::quote::__private::push_ident(&mut _s, "trait_path");
::quote::__private::push_semi(&mut _s);
::quote::__private::push_ident(&mut _s, "class_system");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s, "$");
::quote::__private::push_ident(&mut _s, "class_system");
::quote::__private::push_semi(&mut _s);
::quote::__private::push_ident(&mut _s, "no_rd");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s, "$");
::quote::__private::push_ident(&mut _s, "no_rd");
::quote::__private::push_semi(&mut _s);
::quote::__private::push_ident(&mut _s, "internal");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s, "$");
::quote::__private::push_ident(&mut _s, "internal");
::quote::__private::push_semi(&mut _s);
::quote::__private::push_ident(&mut _s, "noexport");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s, "$");
::quote::__private::push_ident(&mut _s, "noexport");
::quote::__private::push_semi(&mut _s);
::quote::__private::push_ident(&mut _s, "no_preconditions");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s, "$");
::quote::__private::push_ident(&mut _s, "no_preconditions");
::quote::__private::push_semi(&mut _s);
::quote::ToTokens::to_tokens(&abi_metadata, &mut _s);
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut tpie_method_metadata, i) =
tpie_method_metadata.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let tpie_method_metadata =
match tpie_method_metadata.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&tpie_method_metadata,
&mut _s);
}
}
_s
});
_s
});
::quote::__private::push_semi(&mut _s);
_s
}quote::quote! {
601 ($concrete_type:ty, $trait_path:path, $class_system:ident, $no_rd:tt, $internal:tt, $noexport:tt, $no_preconditions:tt) => {
602 ::miniextendr_api::__mx_trait_impl_expand! {
603 concrete_type = $concrete_type;
604 trait_path = $trait_path;
605 class_system = $class_system;
606 no_rd = $no_rd;
607 internal = $internal;
608 noexport = $noexport;
609 no_preconditions = $no_preconditions;
610 #abi_metadata
611 #(#tpie_method_metadata)*
612 }
613 };
614 }
615 } else {
616 ::quote::__private::TokenStream::new();quote::quote! {}
617 };
618 let declaration_generics = &trait_item.generics;
619 let metadata_macro_name = crate::naming::trait_metadata_macro_ident(trait_name);
620 let metadata_macro = {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "macro_export");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "hidden");
_s
});
_s
});
::quote::__private::push_ident(&mut _s, "macro_rules");
::quote::__private::push_bang(&mut _s);
::quote::ToTokens::to_tokens(&metadata_macro_name, &mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_at(&mut _s);
::quote::__private::push_ident(&mut _s, "impl");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::parse(&mut _s, "$");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::parse(&mut _s, "$");
::quote::__private::push_ident(&mut _s, "attrs");
::quote::__private::push_colon(&mut _s);
::quote::__private::push_ident(&mut _s, "tt");
_s
});
::quote::__private::push_star(&mut _s);
_s
});
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::parse(&mut _s, "$");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::parse(&mut _s, "$");
::quote::__private::push_ident(&mut _s, "implementation");
::quote::__private::push_colon(&mut _s);
::quote::__private::push_ident(&mut _s, "tt");
_s
});
::quote::__private::push_star(&mut _s);
_s
});
_s
});
::quote::__private::push_fat_arrow(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s,
"__mx_trait_impl_expand");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_at(&mut _s);
::quote::__private::push_ident(&mut _s, "impl");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::parse(&mut _s, "$");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::parse(&mut _s, "$");
::quote::__private::push_ident(&mut _s, "attrs");
_s
});
::quote::__private::push_star(&mut _s);
_s
});
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::parse(&mut _s, "$");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::parse(&mut _s, "$");
::quote::__private::push_ident(&mut _s, "implementation");
_s
});
::quote::__private::push_star(&mut _s);
_s
});
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut method_metadata, i) =
method_metadata.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let method_metadata =
match method_metadata.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&method_metadata, &mut _s);
}
}
_s
});
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&declaration_generics,
&mut _s);
_s
});
::quote::ToTokens::to_tokens(&abi_metadata, &mut _s);
_s
});
_s
});
::quote::__private::push_semi(&mut _s);
::quote::ToTokens::to_tokens(&empty_impl_arm, &mut _s);
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "hidden");
_s
});
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "allow");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "unused_imports");
_s
});
_s
});
::quote::ToTokens::to_tokens(&vis, &mut _s);
::quote::__private::push_ident(&mut _s, "use");
::quote::ToTokens::to_tokens(&metadata_macro_name, &mut _s);
::quote::__private::push_ident(&mut _s, "as");
::quote::ToTokens::to_tokens(&trait_name, &mut _s);
::quote::__private::push_semi(&mut _s);
_s
}quote::quote! {
621 #[macro_export]
622 #[doc(hidden)]
623 macro_rules! #metadata_macro_name {
624 (@impl { $($attrs:tt)* } { $($implementation:tt)* }) => {
625 ::miniextendr_api::__mx_trait_impl_expand! {
626 @impl { $($attrs)* } { $($implementation)* }
627 { #(#method_metadata)* }
628 { #declaration_generics }
629 #abi_metadata
630 }
631 };
632 #empty_impl_arm
633 }
634 #[doc(hidden)]
635 #[allow(unused_imports)]
636 #vis use #metadata_macro_name as #trait_name;
637 };
638
639 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&clean_trait, &mut _s);
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "concat");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::parse(&mut _s,
"\"Type tag for runtime identification of the `\"");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "stringify");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&trait_name, &mut _s);
_s
});
::quote::__private::push_comma(&mut _s);
::quote::__private::parse(&mut _s, "\"` trait.\"");
_s
});
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::ToTokens::to_tokens(&source_loc_doc, &mut _s);
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "concat");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::parse(&mut _s,
"\"Generated from source file `\"");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "file");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
::quote::__private::TokenStream::new());
::quote::__private::push_comma(&mut _s);
::quote::__private::parse(&mut _s, "\"`.\"");
_s
});
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "allow");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s,
"non_upper_case_globals");
_s
});
_s
});
::quote::ToTokens::to_tokens(&vis, &mut _s);
::quote::__private::push_ident(&mut _s, "const");
::quote::ToTokens::to_tokens(&tag_name, &mut _s);
::quote::__private::push_colon(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "abi");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "mx_tag");
::quote::__private::push_eq(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "abi");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "mx_tag_from_path");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&tag_path, &mut _s);
_s
});
::quote::__private::push_semi(&mut _s);
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "concat");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::parse(&mut _s, "\"Vtable for the `\"");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "stringify");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&trait_name, &mut _s);
_s
});
::quote::__private::push_comma(&mut _s);
::quote::__private::parse(&mut _s, "\"` trait.\"");
_s
});
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::ToTokens::to_tokens(&source_loc_doc, &mut _s);
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "concat");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::parse(&mut _s,
"\"Generated from source file `\"");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "file");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
::quote::__private::TokenStream::new());
::quote::__private::push_comma(&mut _s);
::quote::__private::parse(&mut _s, "\"`.\"");
_s
});
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s, "r\"\"");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s,
"r\" Contains one `mx_meth` function pointer per trait method.\"");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "repr");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "C");
_s
});
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "hidden");
_s
});
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "allow");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s,
"non_camel_case_types");
_s
});
_s
});
::quote::ToTokens::to_tokens(&vis, &mut _s);
::quote::__private::push_ident(&mut _s, "struct");
::quote::ToTokens::to_tokens(&vtable_name, &mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let mut _first = true;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut vtable_fields, i) = vtable_fields.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let vtable_fields =
match vtable_fields.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
if !_first { ::quote::__private::push_comma(&mut _s); }
_first = false;
::quote::ToTokens::to_tokens(&vtable_fields, &mut _s);
}
}
_s
});
::quote::ToTokens::to_tokens(&view_tokens, &mut _s);
::quote::ToTokens::to_tokens(&shim_and_builder, &mut _s);
::quote::ToTokens::to_tokens(&metadata_macro, &mut _s);
_s
}quote::quote! {
640 #clean_trait
642
643 #[doc = ::core::concat!(
644 "Type tag for runtime identification of the `",
645 ::core::stringify!(#trait_name),
646 "` trait."
647 )]
648 #[doc = #source_loc_doc]
649 #[doc = ::core::concat!("Generated from source file `", ::core::file!(), "`.")]
650 #[allow(non_upper_case_globals)]
651 #vis const #tag_name: ::miniextendr_api::abi::mx_tag =
652 ::miniextendr_api::abi::mx_tag_from_path(#tag_path);
653
654 #[doc = ::core::concat!("Vtable for the `", ::core::stringify!(#trait_name), "` trait.")]
655 #[doc = #source_loc_doc]
656 #[doc = ::core::concat!("Generated from source file `", ::core::file!(), "`.")]
657 #[repr(C)]
660 #[doc(hidden)]
661 #[allow(non_camel_case_types)]
662 #vis struct #vtable_name {
663 #(#vtable_fields),*
664 }
665
666 #view_tokens
667
668 #shim_and_builder
669
670 #metadata_macro
671 }
672}
673
674fn trait_abi_tag_path(trait_name: &syn::Ident, methods: &[MethodInfo]) -> String {
680 fn push(out: &mut String, component: &str) {
681 use std::fmt::Write;
682 out.write_fmt(format_args!("{0}:{1}", component.len(), component))write!(out, "{}:{component}", component.len()).unwrap();
683 }
684
685 let mut tag = String::from("miniextendr::trait-abi/v2;");
686 push(&mut tag, &crate::naming::ident_name(trait_name));
687 push(&mut tag, &methods.len().to_string());
688 for method in methods {
689 let name = crate::naming::ident_name(&method.name);
690 push(&mut tag, &name);
691 push(&mut tag, method.r_name.as_deref().unwrap_or(&name));
692 push(
693 &mut tag,
694 match method.owner_receiver {
695 Some(crate::trait_receiver::OwnerReceiver::Shared) => "owner-ref",
696 Some(crate::trait_receiver::OwnerReceiver::Mutable) => "owner-mut",
697 None if method.is_mut => "mut",
698 None => "ref",
699 },
700 );
701 push(&mut tag, &method.param_types.len().to_string());
702 for ty in &method.param_types {
703 push(&mut tag, "e::ToTokens::to_token_stream(ty).to_string());
704 }
705 let result = method
706 .return_type
707 .as_ref()
708 .map(|ty| quote::ToTokens::to_token_stream(ty).to_string())
709 .unwrap_or_else(|| "()".to_owned());
710 push(&mut tag, &result);
711 }
712 tag
713}
714
715fn generate_view_method(method: &MethodInfo) -> Option<TokenStream> {
721 if method.return_type.as_ref().is_some_and(type_contains_self) {
725 return None;
726 }
727 if method.param_types.iter().any(type_contains_self) {
728 return None;
729 }
730
731 let method_name = &method.name;
732 let param_names = &method.param_names;
733 let param_types = &method.param_types;
734
735 let params: Vec<_> = param_names
737 .iter()
738 .zip(param_types.iter())
739 .map(|(name, ty)| {
740 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&name, &mut _s);
::quote::__private::push_colon(&mut _s);
::quote::ToTokens::to_tokens(&ty, &mut _s);
_s
}quote::quote! { #name: #ty }
741 })
742 .collect();
743
744 let self_param = if method.is_mut {
746 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_and(&mut _s);
::quote::__private::push_ident(&mut _s, "mut");
::quote::__private::push_ident(&mut _s, "self");
_s
}quote::quote! { &mut self }
747 } else {
748 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_and(&mut _s);
::quote::__private::push_ident(&mut _s, "self");
_s
}quote::quote! { &self }
749 };
750
751 let argc = param_types.len() as i32;
756 let arg_conversions: Vec<_> = param_names
757 .iter()
758 .zip(param_types.iter())
759 .map(|(name, ty)| {
760 if crate::miniextendr_fn::get_missing_inner_type(ty).is_some() {
761 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "trait_abi");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "missing_to_sexp");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&name, &mut _s);
_s
});
_s
}quote::quote! {
762 ::miniextendr_api::trait_abi::missing_to_sexp(#name)
763 }
764 } else {
765 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "trait_abi");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "to_sexp");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&name, &mut _s);
_s
});
_s
}quote::quote! {
766 ::miniextendr_api::trait_abi::to_sexp(#name)
767 }
768 }
769 })
770 .collect();
771
772 let owner_argument = method.owner_receiver.map(|_| {
777 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "self");
::quote::__private::push_dot(&mut _s);
::quote::__private::push_ident(&mut _s, "__mx_view");
::quote::__private::push_dot(&mut _s);
::quote::__private::push_ident(&mut _s, "owner");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
::quote::__private::TokenStream::new());
::quote::__private::push_dot(&mut _s);
::quote::__private::push_ident(&mut _s, "expect");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::parse(&mut _s,
"\"this trait method requires an R-owned receiver\"");
_s
});
::quote::__private::push_comma(&mut _s);
_s
}quote::quote! {
778 self.__mx_view.owner().expect("this trait method requires an R-owned receiver"),
779 }
780 });
781 let vtable_call = if argc > 0 {
782 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "let");
::quote::__private::push_ident(&mut _s, "args");
::quote::__private::push_colon(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "SEXP");
::quote::__private::push_semi(&mut _s);
::quote::ToTokens::to_tokens(&argc, &mut _s);
::quote::__private::push_ident(&mut _s, "as");
::quote::__private::push_ident(&mut _s, "usize");
_s
});
::quote::__private::push_eq(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let mut _first = true;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut arg_conversions, i) =
arg_conversions.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let arg_conversions =
match arg_conversions.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
if !_first { ::quote::__private::push_comma(&mut _s); }
_first = false;
::quote::__private::push_ident(&mut _s, "__mx_roots");
::quote::__private::push_dot(&mut _s);
::quote::__private::push_ident(&mut _s, "protect_raw");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&arg_conversions, &mut _s);
_s
});
}
}
_s
});
::quote::__private::push_semi(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_star(&mut _s);
::quote::__private::push_ident(&mut _s, "self");
::quote::__private::push_dot(&mut _s);
::quote::__private::push_ident(&mut _s, "__mx_view");
::quote::__private::push_dot(&mut _s);
::quote::__private::push_ident(&mut _s, "vtable");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
::quote::__private::TokenStream::new());
_s
});
::quote::__private::push_dot(&mut _s);
::quote::ToTokens::to_tokens(&method_name, &mut _s);
_s
});
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "self");
::quote::__private::push_dot(&mut _s);
::quote::__private::push_ident(&mut _s, "__mx_view");
::quote::__private::push_dot(&mut _s);
::quote::__private::push_ident(&mut _s, "data");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
::quote::__private::TokenStream::new());
::quote::__private::push_comma(&mut _s);
::quote::ToTokens::to_tokens(&owner_argument, &mut _s);
::quote::ToTokens::to_tokens(&argc, &mut _s);
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "args");
::quote::__private::push_dot(&mut _s);
::quote::__private::push_ident(&mut _s, "as_ptr");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
::quote::__private::TokenStream::new());
_s
});
_s
}quote::quote! {
783 let args: [::miniextendr_api::SEXP; #argc as usize] =
784 [#(__mx_roots.protect_raw(#arg_conversions)),*];
785 ((*self.__mx_view.vtable()).#method_name)(self.__mx_view.data(), #owner_argument #argc, args.as_ptr())
786 }
787 } else {
788 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_star(&mut _s);
::quote::__private::push_ident(&mut _s, "self");
::quote::__private::push_dot(&mut _s);
::quote::__private::push_ident(&mut _s, "__mx_view");
::quote::__private::push_dot(&mut _s);
::quote::__private::push_ident(&mut _s, "vtable");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
::quote::__private::TokenStream::new());
_s
});
::quote::__private::push_dot(&mut _s);
::quote::ToTokens::to_tokens(&method_name, &mut _s);
_s
});
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "self");
::quote::__private::push_dot(&mut _s);
::quote::__private::push_ident(&mut _s, "__mx_view");
::quote::__private::push_dot(&mut _s);
::quote::__private::push_ident(&mut _s, "data");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
::quote::__private::TokenStream::new());
::quote::__private::push_comma(&mut _s);
::quote::ToTokens::to_tokens(&owner_argument, &mut _s);
::quote::__private::parse(&mut _s, "0");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "std");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "ptr");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "null");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
::quote::__private::TokenStream::new());
_s
});
_s
}quote::quote! {
789 ((*self.__mx_view.vtable()).#method_name)(self.__mx_view.data(), #owner_argument 0, ::std::ptr::null())
790 }
791 };
792
793 let return_type = &method.return_type;
796 let (return_sig, result_binding, result_conversion) = if let Some(ret_ty) = return_type {
797 (
798 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_rarrow(&mut _s);
::quote::ToTokens::to_tokens(&ret_ty, &mut _s);
_s
}quote::quote! { -> #ret_ty },
799 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "let");
::quote::__private::push_ident(&mut _s, "result");
::quote::__private::push_eq(&mut _s);
::quote::__private::push_ident(&mut _s, "__mx_roots");
::quote::__private::push_dot(&mut _s);
::quote::__private::push_ident(&mut _s, "protect_raw");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&vtable_call, &mut _s);
_s
});
_s
});
::quote::__private::push_semi(&mut _s);
_s
}quote::quote! { let result = __mx_roots.protect_raw({ #vtable_call }); },
800 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "trait_abi");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "from_sexp");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&ret_ty, &mut _s);
::quote::__private::push_gt(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "result");
_s
});
_s
}quote::quote! {
801 ::miniextendr_api::trait_abi::from_sexp::<#ret_ty>(result)
802 },
803 )
804 } else {
805 (
806 ::quote::__private::TokenStream::new()quote::quote! {},
807 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "let");
::quote::__private::push_ident(&mut _s, "result");
::quote::__private::push_eq(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&vtable_call, &mut _s);
_s
});
::quote::__private::push_semi(&mut _s);
_s
}quote::quote! { let result = { #vtable_call }; },
808 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "let");
::quote::__private::push_underscore(&mut _s);
::quote::__private::push_eq(&mut _s);
::quote::__private::push_ident(&mut _s, "result");
::quote::__private::push_semi(&mut _s);
_s
}quote::quote! {
809 let _ = result;
810 },
811 )
812 };
813
814 let roots = if argc > 0 || return_type.is_some() {
817 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "let");
::quote::__private::push_ident(&mut _s, "__mx_roots");
::quote::__private::push_eq(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "gc_protect");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "ProtectScope");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "new");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
::quote::__private::TokenStream::new());
::quote::__private::push_semi(&mut _s);
_s
}quote::quote! {
818 let __mx_roots = ::miniextendr_api::gc_protect::ProtectScope::new();
819 }
820 } else {
821 ::quote::__private::TokenStream::new();quote::quote! {}
822 };
823
824 Some({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "concat");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::parse(&mut _s, "\"Call `\"");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "stringify");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&method_name, &mut _s);
_s
});
::quote::__private::push_comma(&mut _s);
::quote::__private::parse(&mut _s,
"\"` through the vtable.\"");
_s
});
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "inline");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "allow");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "clippy");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s,
"duplicate_underscore_argument");
_s
});
_s
});
::quote::__private::push_ident(&mut _s, "pub");
::quote::__private::push_ident(&mut _s, "fn");
::quote::ToTokens::to_tokens(&method_name, &mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&self_param, &mut _s);
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut params, i) = params.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let params =
match params.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::__private::push_comma(&mut _s);
::quote::ToTokens::to_tokens(¶ms, &mut _s);
}
}
_s
});
::quote::ToTokens::to_tokens(&return_sig, &mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "unsafe");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&roots, &mut _s);
::quote::ToTokens::to_tokens(&result_binding, &mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "trait_abi");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s,
"repanic_if_rust_error");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "result");
_s
});
::quote::__private::push_semi(&mut _s);
::quote::ToTokens::to_tokens(&result_conversion, &mut _s);
_s
});
_s
});
_s
}quote::quote! {
827 #[doc = ::core::concat!("Call `", ::core::stringify!(#method_name), "` through the vtable.")]
828 #[inline]
829 #[allow(clippy::duplicate_underscore_argument)]
830 pub fn #method_name(#self_param #(, #params)*) #return_sig {
831 unsafe {
832 #roots
833 #result_binding
834 ::miniextendr_api::trait_abi::repanic_if_rust_error(result);
838 #result_conversion
839 }
840 }
841 })
842}
843
844fn generate_method_shim(
859 trait_name: &syn::Ident,
860 method: &MethodInfo,
861 extra_bounds: &ExtraBounds,
862 trait_param_idents: &[&syn::Ident],
863 trait_type_params: &[&syn::GenericParam],
864 trait_where_clause: &Option<syn::WhereClause>,
865) -> TokenStream {
866 let method_name = &method.name;
867 let shim_name = crate::naming::trait_method_shim_ident(trait_name, method_name);
868 let impl_t = ::quote::__private::mk_ident(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("__ImplT"))
}), ::quote::__private::Option::None)quote::format_ident!("__ImplT");
869 let data = syn::Ident::new("data", proc_macro2::Span::mixed_site());
872 let argc = syn::Ident::new("argc", proc_macro2::Span::mixed_site());
873 let argv = syn::Ident::new("argv", proc_macro2::Span::mixed_site());
874 let self_ref = syn::Ident::new("self_ref", proc_macro2::Span::mixed_site());
875 let cell = syn::Ident::new("__mx_cell", proc_macro2::Span::mixed_site());
876 let guard = syn::Ident::new("__mx_guard", proc_macro2::Span::mixed_site());
877 let owner = syn::Ident::new("owner", proc_macro2::Span::mixed_site());
878 let owner_parameter = method.owner_receiver.map(|_| {
879 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&owner, &mut _s);
::quote::__private::push_colon(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "SEXP");
::quote::__private::push_comma(&mut _s);
_s
}quote::quote! {
880 #owner: ::miniextendr_api::SEXP,
881 }
882 });
883
884 let param_count = method.param_types.len();
885 let expected_argc = param_count as i32;
886
887 let arg_extractions: Vec<_> = method
890 .param_names
891 .iter()
892 .zip(method.param_types.iter())
893 .enumerate()
894 .map(|(i, (name, ty))| {
895 crate::trait_self_ref::argument(
896 name,
897 &crate::naming::ident_name(name),
898 ty,
899 &impl_t,
900 i,
901 &argv,
902 None,
903 )
904 })
905 .collect();
906
907 let native_borrow_checks = crate::trait_self_ref::native_borrow_checks(
908 method
909 .param_names
910 .iter()
911 .zip(&method.param_types)
912 .enumerate()
913 .map(|(index, (name, ty))| (index, crate::naming::ident_name(name), ty)),
914 &argv,
915 None,
916 );
917
918 let self_refs: Vec<_> = method
919 .param_names
920 .iter()
921 .zip(&method.param_types)
922 .enumerate()
923 .filter_map(|(index, (name, ty))| {
924 crate::type_inspect::self_ref_mutability(ty).map(|mutable| (name, mutable, index))
925 })
926 .collect();
927 let handles: Vec<_> = self_refs
928 .iter()
929 .map(|(name, mutable, _)| {
930 (
931 crate::trait_self_ref::handle_ident(name),
932 *mutable,
933 crate::naming::ident_name(name),
934 )
935 })
936 .collect();
937 let alias_checks = crate::trait_self_ref::alias_checks(
938 &impl_t,
939 &handles,
940 Some((crate::trait_self_ref::cell_address(&cell), method.is_mut)),
941 );
942 let self_borrows = self_refs
943 .iter()
944 .map(|(name, mutable, _)| crate::trait_self_ref::borrow(name, *mutable));
945
946 let param_names = &method.param_names;
949 let (receiver, method_call) = if let Some(kind) = method.owner_receiver {
950 let handle = kind.type_path();
951 let trait_args =
952 (!trait_param_idents.is_empty()).then(|| {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_lt(&mut _s);
{
use ::quote::__private::ext::*;
let mut _first = true;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut trait_param_idents, i) =
trait_param_idents.quote_into_iter();
let has_iter = has_iter | i;
<_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let trait_param_idents =
match trait_param_idents.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
if !_first { ::quote::__private::push_comma(&mut _s); }
_first = false;
::quote::ToTokens::to_tokens(&trait_param_idents, &mut _s);
}
}
::quote::__private::push_gt(&mut _s);
_s
}quote::quote!(<#(#trait_param_idents),*>));
953 (
954 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "let");
::quote::ToTokens::to_tokens(&self_ref, &mut _s);
::quote::__private::push_eq(&mut _s);
::quote::__private::push_ident(&mut _s, "unsafe");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&handle, &mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&impl_t, &mut _s);
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "from_raw_parts");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_and(&mut _s);
::quote::ToTokens::to_tokens(&owner, &mut _s);
::quote::__private::push_comma(&mut _s);
::quote::ToTokens::to_tokens(&cell, &mut _s);
::quote::__private::push_comma(&mut _s);
_s
});
_s
});
::quote::__private::push_semi(&mut _s);
_s
}quote::quote! {
955 let #self_ref = unsafe {
956 #handle::<#impl_t>::from_raw_parts(
957 &#owner,
958 #cell,
959 )
960 };
961 },
962 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&impl_t, &mut _s);
::quote::__private::push_ident(&mut _s, "as");
::quote::ToTokens::to_tokens(&trait_name, &mut _s);
::quote::ToTokens::to_tokens(&trait_args, &mut _s);
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::ToTokens::to_tokens(&method_name, &mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&self_ref, &mut _s);
::quote::__private::push_comma(&mut _s);
{
use ::quote::__private::ext::*;
let mut _first = true;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut param_names, i) = param_names.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let param_names =
match param_names.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
if !_first { ::quote::__private::push_comma(&mut _s); }
_first = false;
::quote::ToTokens::to_tokens(¶m_names, &mut _s);
}
}
_s
});
_s
}quote::quote! {
963 <#impl_t as #trait_name #trait_args>::#method_name(#self_ref, #(#param_names),*)
964 },
965 )
966 } else {
967 (
968 crate::trait_self_ref::receiver_borrow(&cell, &guard, &self_ref, method.is_mut),
969 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&self_ref, &mut _s);
::quote::__private::push_dot(&mut _s);
::quote::ToTokens::to_tokens(&method_name, &mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let mut _first = true;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut param_names, i) = param_names.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let param_names =
match param_names.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
if !_first { ::quote::__private::push_comma(&mut _s); }
_first = false;
::quote::ToTokens::to_tokens(¶m_names, &mut _s);
}
}
_s
});
_s
}quote::quote! { #self_ref.#method_name(#(#param_names),*) },
970 )
971 };
972
973 let result_conversion = if method.return_type.is_some() {
975 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "unsafe");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "trait_abi");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "to_sexp");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "result");
_s
});
_s
});
_s
}quote::quote! {
976 unsafe { ::miniextendr_api::trait_abi::to_sexp(result) }
977 }
978 } else {
979 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "let");
::quote::__private::push_underscore(&mut _s);
::quote::__private::push_eq(&mut _s);
::quote::__private::push_ident(&mut _s, "result");
::quote::__private::push_semi(&mut _s);
::quote::__private::push_ident(&mut _s, "unsafe");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "trait_abi");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "nil");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
::quote::__private::TokenStream::new());
_s
});
_s
}quote::quote! {
980 let _ = result;
981 unsafe { ::miniextendr_api::trait_abi::nil() }
982 }
983 };
984
985 let trait_bound = if trait_param_idents.is_empty() {
987 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&trait_name, &mut _s);
_s
}quote::quote! { #trait_name }
988 } else {
989 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&trait_name, &mut _s);
::quote::__private::push_lt(&mut _s);
{
use ::quote::__private::ext::*;
let mut _first = true;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut trait_param_idents, i) =
trait_param_idents.quote_into_iter();
let has_iter = has_iter | i;
<_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let trait_param_idents =
match trait_param_idents.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
if !_first { ::quote::__private::push_comma(&mut _s); }
_first = false;
::quote::ToTokens::to_tokens(&trait_param_idents, &mut _s);
}
}
::quote::__private::push_gt(&mut _s);
_s
}quote::quote! { #trait_name<#(#trait_param_idents),*> }
990 };
991
992 let impl_bounds = &extra_bounds.impl_bounds;
993 let all_where_predicates = build_where_predicates(trait_where_clause, extra_bounds);
994 let where_clause = if all_where_predicates.is_empty() {
995 ::quote::__private::TokenStream::new();quote::quote! {}
996 } else {
997 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "where");
{
use ::quote::__private::ext::*;
let mut _first = true;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut all_where_predicates, i) =
all_where_predicates.quote_into_iter();
let has_iter = has_iter | i;
<_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let all_where_predicates =
match all_where_predicates.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
if !_first { ::quote::__private::push_comma(&mut _s); }
_first = false;
::quote::ToTokens::to_tokens(&all_where_predicates, &mut _s);
}
}
_s
}quote::quote! { where #(#all_where_predicates),* }
998 };
999
1000 let method_name_str = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}::{1}", trait_name,
method_name))
})format!("{}::{}", trait_name, method_name);
1001
1002 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "concat");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::parse(&mut _s, "\"Method shim for `\"");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "stringify");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&trait_name, &mut _s);
_s
});
::quote::__private::push_comma(&mut _s);
::quote::__private::parse(&mut _s, "\"::\"");
::quote::__private::push_comma(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "stringify");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&method_name, &mut _s);
_s
});
::quote::__private::push_comma(&mut _s);
::quote::__private::parse(&mut _s, "\"`.\"");
_s
});
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s, "r\"\"");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s,
"r\" Converts SEXP arguments, calls the method, and returns SEXP result.\"");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_eq(&mut _s);
::quote::__private::parse(&mut _s,
"r\" Both Rust panics and R longjmps are caught via `with_r_unwind_protect`.\"");
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "doc");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "hidden");
_s
});
_s
});
::quote::__private::push_pound(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "allow");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "non_snake_case");
_s
});
_s
});
::quote::__private::push_ident(&mut _s, "unsafe");
::quote::__private::push_ident(&mut _s, "extern");
::quote::__private::parse(&mut _s, "\"C\"");
::quote::__private::push_ident(&mut _s, "fn");
::quote::ToTokens::to_tokens(&shim_name, &mut _s);
::quote::__private::push_lt(&mut _s);
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut trait_type_params, i) = trait_type_params.quote_into_iter();
let has_iter = has_iter | i;
<_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let trait_type_params =
match trait_type_params.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&trait_type_params, &mut _s);
::quote::__private::push_comma(&mut _s);
}
}
::quote::ToTokens::to_tokens(&impl_t, &mut _s);
::quote::__private::push_colon(&mut _s);
::quote::ToTokens::to_tokens(&trait_bound, &mut _s);
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut impl_bounds, i) = impl_bounds.quote_into_iter();
let has_iter = has_iter | i;
<_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let impl_bounds =
match impl_bounds.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::__private::push_add(&mut _s);
::quote::ToTokens::to_tokens(&impl_bounds, &mut _s);
}
}
::quote::__private::push_gt(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&data, &mut _s);
::quote::__private::push_colon(&mut _s);
::quote::__private::push_star(&mut _s);
::quote::__private::push_ident(&mut _s, "mut");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "std");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "os");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "raw");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "c_void");
::quote::__private::push_comma(&mut _s);
::quote::ToTokens::to_tokens(&owner_parameter, &mut _s);
::quote::ToTokens::to_tokens(&argc, &mut _s);
::quote::__private::push_colon(&mut _s);
::quote::__private::push_ident(&mut _s, "i32");
::quote::__private::push_comma(&mut _s);
::quote::ToTokens::to_tokens(&argv, &mut _s);
::quote::__private::push_colon(&mut _s);
::quote::__private::push_star(&mut _s);
::quote::__private::push_ident(&mut _s, "const");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "SEXP");
::quote::__private::push_comma(&mut _s);
_s
});
::quote::__private::push_rarrow(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "SEXP");
::quote::ToTokens::to_tokens(&where_clause, &mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "unwind_protect");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s,
"with_r_unwind_protect_shim");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_or_or(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "trait_abi");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "check_arity");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&argc, &mut _s);
::quote::__private::push_comma(&mut _s);
::quote::ToTokens::to_tokens(&expected_argc, &mut _s);
::quote::__private::push_comma(&mut _s);
::quote::ToTokens::to_tokens(&method_name_str, &mut _s);
_s
});
::quote::__private::push_semi(&mut _s);
::quote::__private::push_ident(&mut _s, "let");
::quote::ToTokens::to_tokens(&cell, &mut _s);
::quote::__private::push_eq(&mut _s);
::quote::__private::push_ident(&mut _s, "unsafe");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_and(&mut _s);
::quote::__private::push_star(&mut _s);
::quote::ToTokens::to_tokens(&data, &mut _s);
::quote::__private::push_dot(&mut _s);
::quote::__private::push_ident(&mut _s, "cast");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "cell");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "RefCell");
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&impl_t, &mut _s);
::quote::__private::push_shr(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
::quote::__private::TokenStream::new());
_s
});
::quote::__private::push_semi(&mut _s);
::quote::ToTokens::to_tokens(&native_borrow_checks,
&mut _s);
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut arg_extractions, i) =
arg_extractions.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let arg_extractions =
match arg_extractions.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&arg_extractions, &mut _s);
}
}
::quote::ToTokens::to_tokens(&alias_checks, &mut _s);
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut self_borrows, i) = self_borrows.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let self_borrows =
match self_borrows.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&self_borrows, &mut _s);
}
}
::quote::ToTokens::to_tokens(&receiver, &mut _s);
::quote::__private::push_ident(&mut _s, "let");
::quote::__private::push_ident(&mut _s, "result");
::quote::__private::push_eq(&mut _s);
::quote::ToTokens::to_tokens(&method_call, &mut _s);
::quote::__private::push_semi(&mut _s);
::quote::ToTokens::to_tokens(&result_conversion, &mut _s);
_s
});
_s
});
_s
});
_s
}quote::quote! {
1003 #[doc = ::core::concat!(
1004 "Method shim for `",
1005 ::core::stringify!(#trait_name),
1006 "::",
1007 ::core::stringify!(#method_name),
1008 "`."
1009 )]
1010 #[doc(hidden)]
1014 #[allow(non_snake_case)]
1015 unsafe extern "C" fn #shim_name<#(#trait_type_params,)* #impl_t: #trait_bound #(+ #impl_bounds)*>(
1016 #data: *mut ::std::os::raw::c_void,
1017 #owner_parameter
1018 #argc: i32,
1019 #argv: *const ::miniextendr_api::SEXP,
1020 ) -> ::miniextendr_api::SEXP
1021 #where_clause
1022 {
1023 ::miniextendr_api::unwind_protect::with_r_unwind_protect_shim(|| {
1030 ::miniextendr_api::trait_abi::check_arity(#argc, #expected_argc, #method_name_str);
1031 let #cell = unsafe { &*#data.cast::<::core::cell::RefCell<#impl_t>>() };
1032 #native_borrow_checks
1033 #(#arg_extractions)*
1035 #alias_checks
1036 #(#self_borrows)*
1037
1038 #receiver
1040 let result = #method_call;
1041
1042 #result_conversion
1044 })
1045 }
1046 }
1047}
1048
1049fn associated_method_shim(tokens: TokenStream) -> syn::TraitItemFn {
1053 use syn::visit_mut::VisitMut;
1054
1055 struct ImplTypeToSelf;
1056 impl VisitMut for ImplTypeToSelf {
1057 fn visit_path_mut(&mut self, path: &mut syn::Path) {
1058 syn::visit_mut::visit_path_mut(self, path);
1059 if let Some(first) = path.segments.first_mut()
1060 && first.ident == "__ImplT"
1061 {
1062 first.ident = syn::Ident::new("Self", first.ident.span());
1063 }
1064 }
1065 }
1066
1067 let mut shim: syn::TraitItemFn = syn::parse2(tokens).expect("generated method shim");
1068 let syn::GenericParam::Type(implementation) =
1069 shim.sig.generics.params.pop().unwrap().into_value()
1070 else {
1071 {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("the final generated parameter is __ImplT")));
}unreachable!("the final generated parameter is __ImplT")
1072 };
1073 let bounds = implementation.bounds;
1074 shim.sig
1075 .generics
1076 .make_where_clause()
1077 .predicates
1078 .push(::syn::__private::parse_quote({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "Self");
::quote::__private::push_colon(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "marker");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "Sized");
::quote::__private::push_add(&mut _s);
::quote::ToTokens::to_tokens(&bounds, &mut _s);
_s
})syn::parse_quote!(Self: ::core::marker::Sized + #bounds));
1079 ImplTypeToSelf.visit_trait_item_fn_mut(&mut shim);
1080 shim
1081}
1082
1083#[derive(#[automatically_derived]
impl ::core::fmt::Debug for MethodInfo {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
let names: &'static _ =
&["name", "has_self", "is_mut", "owner_receiver", "param_types",
"param_names", "return_type", "skip", "r_name"];
let values: &[&dyn ::core::fmt::Debug] =
&[&self.name, &self.has_self, &self.is_mut, &self.owner_receiver,
&self.param_types, &self.param_names, &self.return_type,
&self.skip, &&self.r_name];
::core::fmt::Formatter::debug_struct_fields_finish(f, "MethodInfo",
names, values)
}
}Debug)]
1088struct MethodInfo {
1089 name: syn::Ident,
1091 has_self: bool,
1094 is_mut: bool,
1096 owner_receiver: Option<crate::trait_receiver::OwnerReceiver>,
1097 param_types: Vec<syn::Type>,
1099 param_names: Vec<syn::Ident>,
1101 return_type: Option<syn::Type>,
1103 skip: bool,
1105 r_name: Option<String>,
1108}
1109
1110fn type_contains_self(ty: &syn::Type) -> bool {
1117 match ty {
1118 syn::Type::Path(tp) => {
1119 for seg in &tp.path.segments {
1120 if seg.ident == "Self" {
1121 return true;
1122 }
1123 if let syn::PathArguments::AngleBracketed(args) = &seg.arguments {
1124 for arg in &args.args {
1125 if let syn::GenericArgument::Type(inner) = arg
1126 && type_contains_self(inner)
1127 {
1128 return true;
1129 }
1130 }
1131 }
1132 }
1133 false
1134 }
1135 syn::Type::Reference(r) => type_contains_self(&r.elem),
1136 syn::Type::Tuple(t) => t.elems.iter().any(type_contains_self),
1137 syn::Type::Slice(s) => type_contains_self(&s.elem),
1138 syn::Type::Array(a) => type_contains_self(&a.elem),
1139 syn::Type::Paren(p) => type_contains_self(&p.elem),
1140 _ => false,
1141 }
1142}
1143
1144fn type_contains_self_assoc(ty: &syn::Type, assoc_name: &syn::Ident) -> bool {
1150 match ty {
1151 syn::Type::Path(tp) => {
1152 if tp.path.segments.len() == 2
1153 && tp.path.segments[0].ident == "Self"
1154 && tp.path.segments[1].ident == *assoc_name
1155 {
1156 return true;
1157 }
1158 for seg in &tp.path.segments {
1159 if let syn::PathArguments::AngleBracketed(args) = &seg.arguments {
1160 for arg in &args.args {
1161 if let syn::GenericArgument::Type(inner) = arg
1162 && type_contains_self_assoc(inner, assoc_name)
1163 {
1164 return true;
1165 }
1166 }
1167 }
1168 }
1169 false
1170 }
1171 syn::Type::Reference(r) => type_contains_self_assoc(&r.elem, assoc_name),
1172 syn::Type::Tuple(t) => t
1173 .elems
1174 .iter()
1175 .any(|e| type_contains_self_assoc(e, assoc_name)),
1176 syn::Type::Slice(s) => type_contains_self_assoc(&s.elem, assoc_name),
1177 syn::Type::Array(a) => type_contains_self_assoc(&a.elem, assoc_name),
1178 syn::Type::Paren(p) => type_contains_self_assoc(&p.elem, assoc_name),
1179 _ => false,
1180 }
1181}
1182
1183fn rewrite_self_in_type(
1191 ty: &syn::Type,
1192 trait_name: &syn::Ident,
1193 assoc_types: &[&syn::Ident],
1194) -> syn::Type {
1195 match ty {
1196 syn::Type::Path(tp) => {
1197 if tp.path.segments.len() == 2
1199 && tp.path.segments[0].ident == "Self"
1200 && assoc_types.iter().any(|a| *a == &tp.path.segments[1].ident)
1201 {
1202 let assoc = &tp.path.segments[1].ident;
1203 let impl_t = ::quote::__private::mk_ident(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("__ImplT"))
}), ::quote::__private::Option::None)quote::format_ident!("__ImplT");
1204 return ::syn::__private::parse_quote({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&impl_t, &mut _s);
::quote::__private::push_ident(&mut _s, "as");
::quote::ToTokens::to_tokens(&trait_name, &mut _s);
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::ToTokens::to_tokens(&assoc, &mut _s);
_s
})syn::parse_quote!(<#impl_t as #trait_name>::#assoc);
1205 }
1206 if tp.path.is_ident("Self") {
1208 let impl_t = ::quote::__private::mk_ident(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("__ImplT"))
}), ::quote::__private::Option::None)quote::format_ident!("__ImplT");
1209 return ::syn::__private::parse_quote({
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&impl_t, &mut _s);
_s
})syn::parse_quote!(#impl_t);
1210 }
1211 let mut new_tp = tp.clone();
1213 for seg in &mut new_tp.path.segments {
1214 if let syn::PathArguments::AngleBracketed(args) = &mut seg.arguments {
1215 for arg in &mut args.args {
1216 if let syn::GenericArgument::Type(inner) = arg {
1217 *inner = rewrite_self_in_type(inner, trait_name, assoc_types);
1218 }
1219 }
1220 }
1221 }
1222 syn::Type::Path(new_tp)
1223 }
1224 syn::Type::Reference(r) => {
1225 let mut new_r = r.clone();
1226 new_r.elem = Box::new(rewrite_self_in_type(&r.elem, trait_name, assoc_types));
1227 syn::Type::Reference(new_r)
1228 }
1229 syn::Type::Tuple(t) => {
1230 let mut new_t = t.clone();
1231 for elem in &mut new_t.elems {
1232 *elem = rewrite_self_in_type(elem, trait_name, assoc_types);
1233 }
1234 syn::Type::Tuple(new_t)
1235 }
1236 syn::Type::Slice(s) => {
1237 let mut new_s = s.clone();
1238 new_s.elem = Box::new(rewrite_self_in_type(&s.elem, trait_name, assoc_types));
1239 syn::Type::Slice(new_s)
1240 }
1241 syn::Type::Array(a) => {
1242 let mut new_a = a.clone();
1243 new_a.elem = Box::new(rewrite_self_in_type(&a.elem, trait_name, assoc_types));
1244 syn::Type::Array(new_a)
1245 }
1246 syn::Type::Paren(p) => {
1247 let mut new_p = p.clone();
1248 new_p.elem = Box::new(rewrite_self_in_type(&p.elem, trait_name, assoc_types));
1249 syn::Type::Paren(new_p)
1250 }
1251 _ => ty.clone(),
1252 }
1253}
1254
1255fn type_contains_ident(ty: &syn::Type, ident: &syn::Ident) -> bool {
1261 match ty {
1262 syn::Type::Path(tp) => {
1263 if tp.path.segments.len() == 1 && tp.path.segments[0].ident == *ident {
1264 return true;
1265 }
1266 for seg in &tp.path.segments {
1267 if let syn::PathArguments::AngleBracketed(args) = &seg.arguments {
1268 for arg in &args.args {
1269 if let syn::GenericArgument::Type(inner) = arg
1270 && type_contains_ident(inner, ident)
1271 {
1272 return true;
1273 }
1274 }
1275 }
1276 }
1277 false
1278 }
1279 syn::Type::Reference(r) => type_contains_ident(&r.elem, ident),
1280 syn::Type::Tuple(t) => t.elems.iter().any(|e| type_contains_ident(e, ident)),
1281 syn::Type::Slice(s) => type_contains_ident(&s.elem, ident),
1282 syn::Type::Array(a) => type_contains_ident(&a.elem, ident),
1283 syn::Type::Paren(p) => type_contains_ident(&p.elem, ident),
1284 _ => false,
1285 }
1286}
1287
1288struct ExtraBounds {
1294 impl_bounds: Vec<TokenStream>,
1297 where_predicates: Vec<TokenStream>,
1300}
1301
1302fn compute_extra_bounds(
1311 methods: &[MethodInfo],
1312 trait_name: &syn::Ident,
1313 assoc_types: &[&syn::Ident],
1314 trait_param_idents: &[&syn::Ident],
1315) -> ExtraBounds {
1316 let mut impl_bounds = Vec::new();
1317 let mut where_predicates = Vec::new();
1318
1319 let mut needs_into_r = false;
1320 let mut needs_typed_external = false;
1321 let needs_owner = methods.iter().any(|method| method.owner_receiver.is_some());
1322
1323 let mut return_type_bound_keys: std::collections::BTreeMap<String, syn::Type> =
1325 Default::default();
1326 let mut param_type_bound_keys: std::collections::BTreeMap<String, syn::Type> =
1327 Default::default();
1328
1329 for method in methods {
1330 if method.return_type.as_ref().is_some_and(type_contains_self) {
1332 needs_into_r = true;
1333 }
1334 if method
1336 .param_types
1337 .iter()
1338 .any(|ty| crate::type_inspect::self_ref_mutability(ty).is_some())
1339 {
1340 needs_typed_external = true;
1341 }
1342
1343 if let Some(ref ret_ty) = method.return_type {
1348 let has_assoc = assoc_types
1349 .iter()
1350 .any(|a| type_contains_self_assoc(ret_ty, a));
1351 let has_param = trait_param_idents
1352 .iter()
1353 .any(|p| type_contains_ident(ret_ty, p));
1354 if has_assoc || has_param {
1355 let rewritten = rewrite_self_in_type(ret_ty, trait_name, assoc_types);
1356 let key = {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&rewritten, &mut _s);
_s
}quote::quote!(#rewritten).to_string();
1357 return_type_bound_keys.entry(key).or_insert(rewritten);
1358 }
1359 }
1360
1361 for param_ty in &method.param_types {
1364 if crate::type_inspect::self_ref_mutability(param_ty).is_none() {
1365 let has_param = trait_param_idents
1366 .iter()
1367 .any(|p| type_contains_ident(param_ty, p));
1368 if has_param {
1369 let key = {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(¶m_ty, &mut _s);
_s
}quote::quote!(#param_ty).to_string();
1370 param_type_bound_keys.entry(key).or_insert(param_ty.clone());
1371 }
1372 }
1373 }
1374 }
1375
1376 if needs_into_r {
1377 impl_bounds.push({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "IntoR");
_s
}quote::quote! { ::miniextendr_api::IntoR });
1378 }
1379 if needs_typed_external {
1380 impl_bounds.push(
1381 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "TypedExternal");
::quote::__private::push_add(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "marker");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "Send");
::quote::__private::push_add(&mut _s);
::quote::__private::push_lifetime(&mut _s, "\'static");
_s
}quote::quote! { ::miniextendr_api::TypedExternal + ::core::marker::Send + 'static },
1382 );
1383 }
1384
1385 if needs_owner && !needs_typed_external {
1386 impl_bounds.push({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "TypedExternal");
_s
}quote::quote! { ::miniextendr_api::TypedExternal });
1387 }
1388
1389 for ty in return_type_bound_keys.values() {
1391 where_predicates.push({
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&ty, &mut _s);
::quote::__private::push_colon(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "IntoR");
_s
}quote::quote! {
1392 #ty: ::miniextendr_api::IntoR
1393 });
1394 }
1395
1396 for ty in param_type_bound_keys.values() {
1398 where_predicates.push({
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&ty, &mut _s);
::quote::__private::push_colon(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "TryFromSexp");
_s
}quote::quote! {
1399 #ty: ::miniextendr_api::TryFromSexp
1400 });
1401 where_predicates.push({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&ty, &mut _s);
::quote::__private::push_ident(&mut _s, "as");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "TryFromSexp");
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "Error");
::quote::__private::push_colon(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "std");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "fmt");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "Display");
_s
}quote::quote! {
1402 <#ty as ::miniextendr_api::TryFromSexp>::Error: ::std::fmt::Display
1403 });
1404 }
1405
1406 ExtraBounds {
1407 impl_bounds,
1408 where_predicates,
1409 }
1410}
1411
1412fn build_where_predicates(
1420 trait_where_clause: &Option<syn::WhereClause>,
1421 extra_bounds: &ExtraBounds,
1422) -> Vec<TokenStream> {
1423 let mut all = Vec::new();
1424 if let Some(wc) = trait_where_clause {
1425 for pred in &wc.predicates {
1426 all.push({
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&pred, &mut _s);
_s
}quote::quote! { #pred });
1427 }
1428 }
1429 all.extend(extra_bounds.where_predicates.iter().cloned());
1430 all
1431}
1432
1433fn extract_method_info(method: &syn::TraitItemFn) -> syn::Result<MethodInfo> {
1439 let name = method.sig.ident.clone();
1440
1441 let mut skip = false;
1443 let mut r_name: Option<String> = None;
1444 for attr in &method.attrs {
1445 if !attr.path().is_ident("miniextendr") {
1446 continue;
1447 }
1448 attr.parse_nested_meta(|meta| {
1449 if meta.path.is_ident("skip") {
1450 skip = true;
1451 } else if meta.path.is_ident("r_name") {
1452 let value: syn::LitStr = meta.value()?.parse()?;
1453 r_name = Some(value.value());
1454 } else if meta.path.is_ident("formal") {
1455 return Err(meta.error(crate::miniextendr_fn::TRAIT_FORMAL_UNSUPPORTED));
1456 } else {
1457 return Err(meta.error(
1458 "unknown #[miniextendr] option on trait method; expected `skip` or `r_name`",
1459 ));
1460 }
1461 Ok(())
1462 })?;
1463 }
1464
1465 let (has_self, is_mut) = method.sig.inputs.first().map_or((false, false), |arg| {
1467 if let syn::FnArg::Receiver(_) = arg {
1468 (true, crate::trait_receiver::is_mut(&method.sig))
1469 } else {
1470 (false, false)
1471 }
1472 });
1473
1474 let skip_count = if has_self { 1 } else { 0 };
1476 let mut param_types = Vec::new();
1477 let mut param_names = Vec::new();
1478 for (i, arg) in method.sig.inputs.iter().skip(skip_count).enumerate() {
1479 if let syn::FnArg::Typed(pat_type) = arg {
1480 if crate::return_wrap::contains_marker(&pat_type.ty) {
1481 return Err(syn::Error::new_spanned(
1482 &pat_type.ty,
1483 "class return markers are return-position only",
1484 ));
1485 }
1486 let (markers, _) = crate::type_inspect::peel_param_markers(&pat_type.ty)?;
1490 if let Some(marker) = markers.first() {
1491 let name = match pat_type.pat.as_ref() {
1492 syn::Pat::Ident(pat_ident) => crate::naming::ident_name(&pat_ident.ident),
1493 _ => "x".to_string(),
1494 };
1495 return Err(syn::Error::new_spanned(
1496 &pat_type.ty,
1497 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}<T>` in a `#[miniextendr]` trait method: the trait\'s View passes arguments on as R values, and each impl\'s wrapper checks them; spell it on the impl, `#[miniextendr({1}({2}))]`",
marker.name(),
if marker.preconditions() == Some(true) {
"preconditions"
} else { "no_preconditions" }, name))
})format!(
1498 "`{}<T>` in a `#[miniextendr]` trait method: the trait's View passes \
1499 arguments on as R values, and each impl's wrapper checks them; spell it \
1500 on the impl, `#[miniextendr({}({name}))]`",
1501 marker.name(),
1502 if marker.preconditions() == Some(true) {
1503 "preconditions"
1504 } else {
1505 "no_preconditions"
1506 },
1507 ),
1508 ));
1509 }
1510 param_types.push((*pat_type.ty).clone());
1511 if let syn::Pat::Ident(pat_ident) = pat_type.pat.as_ref() {
1512 param_names.push(pat_ident.ident.clone());
1513 } else {
1514 param_names.push(match ::quote::__private::IdentFragmentAdapter(&i) {
arg =>
::quote::__private::mk_ident(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("arg{0}", arg))
}), ::quote::__private::Option::None.or(arg.span())),
}quote::format_ident!("arg{}", i));
1515 }
1516 }
1517 }
1518
1519 let return_type = match &method.sig.output {
1523 syn::ReturnType::Default => None,
1524 syn::ReturnType::Type(_, ty) => {
1525 if let Some(err) = crate::type_inspect::visibility_marker_error(ty, "return") {
1526 return Err(err);
1527 }
1528 let (_, ty) = crate::type_inspect::peel_visibility_marker(ty);
1529 let output: syn::ReturnType = ::syn::__private::parse_quote({
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_rarrow(&mut _s);
::quote::ToTokens::to_tokens(&ty, &mut _s);
_s
})syn::parse_quote!(-> #ty);
1530 let (wrap, output) = crate::return_wrap::resolve(&output, None)?;
1531 if wrap.as_ref().is_some_and(|wrap| wrap.conversion.is_some()) {
1532 return Err(syn::Error::new_spanned(
1533 ty,
1534 "ConvertTo/ConvertFrom require an inherent S7 impl method",
1535 ));
1536 }
1537 let syn::ReturnType::Type(_, ty) = output else {
1538 ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
1539 };
1540 let ty = ty.as_ref();
1541 if #[allow(non_exhaustive_omitted_patterns)] match ty {
syn::Type::Tuple(t) if t.elems.is_empty() => true,
_ => false,
}matches!(ty, syn::Type::Tuple(t) if t.elems.is_empty()) {
1543 None
1544 } else {
1545 Some(ty.clone())
1546 }
1547 }
1548 };
1549
1550 Ok(MethodInfo {
1551 name,
1552 has_self,
1553 is_mut,
1554 owner_receiver: crate::trait_receiver::owner_receiver(&method.sig),
1555 param_types,
1556 param_names,
1557 return_type,
1558 skip,
1559 r_name,
1560 })
1561}
1562
1563#[cfg(test)]
1564mod tests;
1565