1use proc_macro2::TokenStream;
2
3use std::collections::BTreeMap;
4
5use super::func::{AssocType, CustomFuncImpl, ParsedFunc, WrappedType};
6use super::generics::{GenericType, ParsedGenerics};
7
8use quote::*;
9use syn::{
10 parse::*,
11 punctuated::Punctuated,
12 token::{Add, Comma},
13 *,
14};
15
16pub struct PathTokens {
17 lifetime: Option<Lifetime>,
18 path: Path,
19 tokens: TokenStream,
20}
21
22impl Parse for PathTokens {
23 fn parse(input: ParseStream) -> Result<Self> {
24 let lifetime = if let Ok(lifetime) = input.parse() {
25 input.parse::<Comma>()?;
26 Some(lifetime)
27 } else {
28 None
29 };
30
31 let path = input.parse()?;
32 let tokens = input.parse()?;
33
34 Ok(Self {
35 lifetime,
36 path,
37 tokens,
38 })
39 }
40}
41
42pub fn ctx_bound() -> TokenStream {
44 let crate_path = crate::util::crate_path();
45 quote!(#crate_path::trait_group::ContextBounds)
46}
47
48pub fn cglue_c_opaque_bound() -> TokenStream {
49 let crate_path = crate::util::crate_path();
50 quote!(CGlueC::OpaqueTarget: #crate_path::trait_group::Opaquable + #crate_path::trait_group::CGlueObjBase,)
51}
52
53pub fn process_item(
54 (ty_def, ty_bounds, ty_where_clause, ty_attrs): (
55 &Option<AssocType>,
56 &Punctuated<TypeParamBound, Add>,
57 Option<&WhereClause>,
58 &[Attribute],
59 ),
60 trait_name: &Ident,
61 generics: &ParsedGenerics,
62 trait_type_defs: &mut TokenStream,
63 types: &mut BTreeMap<Option<AssocType>, WrappedType>,
64 assoc_types: &mut BTreeMap<AssocType, Punctuated<TypeParamBound, Add>>,
65 crate_path: &TokenStream,
66) {
67 let c_void = crate::util::void_type();
68
69 let static_lifetime = Lifetime {
70 apostrophe: proc_macro2::Span::call_site(),
71 ident: format_ident!("static"),
72 };
73
74 let cglue_a_lifetime = Lifetime {
75 apostrophe: proc_macro2::Span::call_site(),
76 ident: format_ident!("cglue_a"),
77 };
78
79 let cglue_b_lifetime = Lifetime {
80 apostrophe: proc_macro2::Span::call_site(),
81 ident: format_ident!("cglue_b"),
82 };
83
84 let cglue_c_lifetime = Lifetime {
85 apostrophe: proc_macro2::Span::call_site(),
86 ident: format_ident!("cglue_c"),
87 };
88
89 let mut lifetime_bounds = ty_bounds.iter().filter_map(|b| match b {
90 TypeParamBound::Lifetime(lt) => Some(lt),
91 _ => None,
92 });
93
94 let orig_lifetime_bound = lifetime_bounds.next();
95
96 let orig_lifetime_bound = if orig_lifetime_bound.map(|lt| lt.ident == "_") == Some(true) {
98 Some(&cglue_c_lifetime)
99 } else {
100 orig_lifetime_bound
101 };
102
103 if lifetime_bounds.next().is_some() {
104 panic!("Traits with multiple lifetime bounds are not supported!");
105 }
106
107 let mut wrapped = false;
108
109 for attr in ty_attrs {
110 let s = attr.path.to_token_stream().to_string();
111
112 let x = s.as_str();
113
114 match x {
115 "wrap_with" => {
116 wrapped = true;
117 let new_ty = attr
118 .parse_args::<GenericType>()
119 .expect("Invalid type in wrap_with.");
120
121 if let Some(ty_def) = ty_def {
122 trait_type_defs.extend(quote!(type #ty_def = #new_ty #ty_where_clause;));
123 }
124
125 types.insert(
126 ty_def.clone(),
127 WrappedType {
128 ty: new_ty.clone(),
129 ty_ret_tmp: Some(new_ty),
130 ty_static: None,
131 return_conv: None,
132 lifetime_bound: None,
133 lifetime_type_bound: None,
134 other_bounds: None,
135 other_bounds_simple: None,
136 impl_return_conv: None,
137 inject_ret_tmp: false,
138 unbounded_hrtb: false,
139 },
140 );
141 }
142 "return_wrap" => {
143 wrapped = true;
144 let closure = attr
145 .parse_args::<ExprClosure>()
146 .expect("A valid closure must be supplied accepting the wrapped type!");
147
148 types
149 .get_mut(ty_def)
150 .expect("Type must be first wrapped with #[wrap_with(T)] atribute.")
151 .return_conv = Some(closure);
152 }
153 "wrap_with_obj"
154 | "wrap_with_obj_ref"
155 | "wrap_with_obj_mut"
156 | "wrap_with_group"
157 | "wrap_with_group_ref"
158 | "wrap_with_group_mut" => {
159 wrapped = true;
160 let mut new_ty = attr
161 .parse_args::<GenericType>()
162 .expect("Invalid type in wrap_with.");
163
164 let target_ty = new_ty.clone();
165 let target = new_ty.target.clone();
166
167 if ["wrap_with_obj", "wrap_with_obj_ref", "wrap_with_obj_mut"].contains(&x) {
170 new_ty.target = format_ident!("{}Base", target.to_string()).to_token_stream();
171 }
172
173 let mut from_new_ty = new_ty.clone();
175 let mut from_new_ty_ref = TokenStream::new();
176 let mut from_new_ty_simple = new_ty.clone();
177 let mut from_new_ty_simple_ref = TokenStream::new();
178
179 let mut new_ty_static = new_ty.clone();
180
181 let lifetime_bound = if orig_lifetime_bound.is_none()
184 && (x == "wrap_with_group" || x == "wrap_with_obj")
185 {
186 Some(&static_lifetime)
187 } else {
188 orig_lifetime_bound
189 };
190
191 let lifetime = lifetime_bound.unwrap_or(&static_lifetime);
192
193 new_ty.push_lifetime_start(lifetime);
195 new_ty_static.push_lifetime_start(&static_lifetime);
196
197 let from_lifetime = if (x == "wrap_with_group" || x == "wrap_with_obj")
198 && lifetime == &static_lifetime
199 {
200 lifetime
201 } else {
202 &cglue_b_lifetime
203 };
204
205 from_new_ty.push_lifetime_start(from_lifetime);
206
207 let from_lifetime_simple = if (x == "wrap_with_group" || x == "wrap_with_obj")
208 && lifetime == &static_lifetime
209 {
210 lifetime
211 } else {
212 &cglue_a_lifetime
213 };
214
215 from_new_ty_simple.push_lifetime_start(from_lifetime_simple);
216
217 let gen_use = &generics.gen_use;
218
219 let mut new_ty_trait_impl = new_ty.clone();
220 let mut new_ty_ret_tmp = new_ty.clone();
221
222 let (other_bounds, other_bounds_simple) = {
223 let (type_bounds, type_bounds_simple) = {
224 let hrtb_lifetime = quote!(#cglue_b_lifetime);
227
228 let hrtb_lifetime_use = if generics.life_use.is_empty() {
229 quote!()
230 } else {
231 quote!(#from_lifetime)
232 };
233
234 let simple_lifetime_use = if generics.life_use.is_empty() {
235 quote!()
236 } else {
237 quote!(#from_lifetime_simple)
238 };
239
240 let cglue_f_tys = ty_def.as_ref().map(|ty_def| {
241 let ty_def = ty_def.remap_for_hrtb();
242 (
243 quote!(<CGlueC::ObjType as #trait_name<#hrtb_lifetime_use #gen_use>>::#ty_def),
244 quote!(<CGlueC::ObjType as #trait_name<#simple_lifetime_use #gen_use>>::#ty_def),
245 )
246 });
247
248 let mut new_ty_hrtb = from_new_ty.clone();
249 let mut new_ty_simple = from_new_ty_simple.clone();
250
251 if x == "wrap_with_group" || x == "wrap_with_obj" {
252 new_ty.push_types_start(
254 quote!(#crate_path::boxed::CBox<#lifetime, #c_void>, CGlueC::Context, ),
255 );
256 new_ty_ret_tmp.push_types_start(
257 quote!(#crate_path::boxed::CBox<#lifetime, #c_void>, CGlueCtx, ),
258 );
259 new_ty_trait_impl.push_types_start(
260 quote!(#crate_path::boxed::CBox<#lifetime, #c_void>, <CGlueO::ContType as #crate_path::trait_group::CGlueObjBase>::Context, ),
261 );
262 new_ty_hrtb.push_types_start(
263 quote!(#crate_path::boxed::CBox<#from_lifetime, #c_void>, CGlueC::Context, ),
264 );
265 new_ty_simple.push_types_start(
266 quote!(#crate_path::boxed::CBox<#from_lifetime_simple, #c_void>, CGlueC::Context, ),
267 );
268 new_ty_static.push_types_start(
269 quote!(#crate_path::boxed::CBox<'static, #c_void>, CGlueCtx, ),
270 );
271
272 if let Some((cglue_f_ty_def, cglue_f_ty_simple_ident)) = &cglue_f_tys {
273 from_new_ty.push_types_start(
274 quote!(#crate_path::boxed::CBox<#from_lifetime, #cglue_f_ty_def>, CGlueC::Context, ),
275 );
276 from_new_ty_simple.push_types_start(
277 quote!(#crate_path::boxed::CBox<#from_lifetime_simple, #cglue_f_ty_simple_ident>, CGlueC::Context, ),
278 );
279 }
280 } else if x == "wrap_with_group_ref" || x == "wrap_with_obj_ref" {
281 let no_context = quote!(CGlueC::Context);
282 new_ty.push_types_start(quote!(&#lifetime #c_void, CGlueC::Context, ));
283 new_ty_ret_tmp.push_types_start(quote!(&#lifetime #c_void, CGlueCtx, ));
284 new_ty_trait_impl.push_types_start(
285 quote!(&#lifetime #c_void, <CGlueO::ContType as crate::trait_group::CGlueObjBase>::Context, ),
286 );
287 new_ty_hrtb.push_types_start(
288 quote!(&#from_lifetime #c_void, CGlueC::Context, ),
289 );
290 new_ty_simple.push_types_start(
291 quote!(&#from_lifetime_simple #c_void, CGlueC::Context, ),
292 );
293 new_ty_static.push_types_start(quote!(&'static #c_void, CGlueCtx, ));
294 if let Some((cglue_f_ty_def, cglue_f_ty_simple_ident)) = &cglue_f_tys {
295 from_new_ty.push_types_start(
296 quote!(&#from_lifetime #cglue_f_ty_def, #no_context, ),
297 );
298 from_new_ty_ref.extend(quote!(&#from_lifetime));
299 from_new_ty_simple.push_types_start(
300 quote!(&#from_lifetime_simple #cglue_f_ty_simple_ident, #no_context, ),
301 );
302 from_new_ty_simple_ref.extend(quote!(&#from_lifetime_simple));
303 }
304 } else if x == "wrap_with_group_mut" || x == "wrap_with_obj_mut" {
305 let no_context = quote!(CGlueC::Context);
306 new_ty.push_types_start(
307 quote!(&#lifetime mut #c_void, CGlueC::Context, ),
308 );
309 new_ty_ret_tmp
310 .push_types_start(quote!(&#lifetime mut #c_void, CGlueCtx, ));
311 new_ty_trait_impl.push_types_start(
312 quote!(&#lifetime mut #c_void, <CGlueO::ContType as crate::trait_group::CGlueObjBase>::Context, ),
313 );
314 new_ty_hrtb.push_types_start(
315 quote!(&#from_lifetime mut #c_void, CGlueC::Context, ),
316 );
317 new_ty_simple.push_types_start(
318 quote!(&#from_lifetime_simple mut #c_void, CGlueC::Context, ),
319 );
320 new_ty_static
321 .push_types_start(quote!(&'static mut #c_void, CGlueCtx, ));
322 if let Some((cglue_f_ty_def, cglue_f_ty_simple_ident)) = &cglue_f_tys {
323 from_new_ty.push_types_start(
324 quote!(&#from_lifetime mut #cglue_f_ty_def, #no_context, ),
325 );
326 from_new_ty_ref.extend(quote!(&#from_lifetime mut));
327 from_new_ty_simple.push_types_start(
328 quote!(&#from_lifetime_simple mut #cglue_f_ty_simple_ident, #no_context, ),
329 );
330 from_new_ty_simple_ref.extend(quote!(&#from_lifetime_simple mut));
331 }
332 } else {
333 unreachable!()
334 }
335
336 if let Some((cglue_f_ty_def, cglue_f_ty_simple_ident)) = cglue_f_tys {
337 let (ty_ref, ty_ref_simple) = {
338 (
339 quote!((#from_new_ty_ref #cglue_f_ty_def, CGlueC::Context)),
340 quote!((#from_new_ty_simple_ref #cglue_f_ty_simple_ident, CGlueC::Context)),
341 )
342 };
343
344 let type_bounds = quote! {
345 for<#hrtb_lifetime> #ty_ref: Into<#from_new_ty>,
346 for<#hrtb_lifetime> #from_new_ty: #crate_path::trait_group::Opaquable<OpaqueTarget = #new_ty_hrtb>,
347 };
348
349 let type_bounds_simple = quote! {
350 #ty_ref_simple: Into<#from_new_ty_simple>,
351 #from_new_ty_simple: #crate_path::trait_group::Opaquable<OpaqueTarget = #new_ty_simple>,
352 };
353 (Some(type_bounds), Some(type_bounds_simple))
354 } else if lifetime_bound == Some(&static_lifetime) {
355 (
356 Some(quote!(CGlueC::ObjType: 'static,)),
357 Some(quote!(CGlueC::ObjType: 'static,)),
358 )
359 } else {
360 (None, None)
361 }
362 };
363
364 if let Some(ty_def) = ty_def {
365 trait_type_defs
366 .extend(quote!(type #ty_def = #new_ty_trait_impl #ty_where_clause;));
367 }
368
369 (type_bounds, type_bounds_simple)
370 };
371
372 let ret_write_unsafe = quote! {
373 unsafe {
377 assert!(std::mem::size_of_val(ret_tmp) == std::mem::size_of_val(&ret));
381 std::ptr::copy_nonoverlapping(std::mem::transmute(&ret), ret_tmp.as_mut_ptr(), 1);
382 std::mem::forget(ret);
383 }
384 };
385
386 let (ret_write, conv_bound) = if lifetime != &static_lifetime {
387 (
388 quote! {
389 unsafe {
390 ret_tmp.as_mut_ptr().write(ret);
391 }
392 },
393 quote!(#lifetime),
394 )
395 } else {
396 (ret_write_unsafe.clone(), quote!('cglue_a))
397 };
398
399 let target = target_ty;
400
401 let (return_conv, inject_ret_tmp) = match x {
402 "wrap_with_obj" => (
403 parse2(quote!(|ret| trait_obj!((ret, cglue_ctx) as #target)))
404 .expect("Internal closure parsing fail"),
405 false,
406 ),
407 "wrap_with_group" => (
408 parse2(quote!(|ret| group_obj!((ret, cglue_ctx) as #target)))
409 .expect("Internal closure parsing fail"),
410 false,
411 ),
412 "wrap_with_obj_ref" => (
413 parse2(quote!(|ret: &#conv_bound _| {
414 let ret = trait_obj!((ret, cglue_ctx) as #target);
415 #ret_write_unsafe
416 unsafe { &*ret_tmp.as_ptr() }
417 }))
418 .expect("Internal closure parsing fail"),
419 true,
420 ),
421 "wrap_with_group_ref" => (
422 parse2(quote!(|ret: &#conv_bound _| {
423 let ret = group_obj!((ret, cglue_ctx) as #target);
424 #ret_write_unsafe
425 unsafe { &*ret_tmp.as_ptr() }
426 }))
427 .expect("Internal closure parsing fail"),
428 true,
429 ),
430 "wrap_with_obj_mut" => (
431 parse2(quote!(|ret: &#conv_bound mut _| {
432 let ret = trait_obj!((ret, cglue_ctx) as #target);
433 #ret_write
434 unsafe { &mut *ret_tmp.as_mut_ptr() }
435 }))
436 .expect("Internal closure parsing fail"),
437 true,
438 ),
439 "wrap_with_group_mut" => (
440 parse2(quote!(|ret: &#conv_bound mut _| {
441 let ret = group_obj!((ret, cglue_ctx) as #target);
442 #ret_write
443 unsafe { &mut *ret_tmp.as_mut_ptr() }
444 }))
445 .expect("Internal closure parsing fail"),
446 true,
447 ),
448 _ => unreachable!(),
449 };
450
451 let lifetime_type_bound = if orig_lifetime_bound != Some(&static_lifetime) {
456 lifetime_bound.cloned()
457 } else {
458 None
459 };
460
461 let lifetime_bound = if lifetime_bound != Some(&static_lifetime) {
462 lifetime_bound.cloned()
463 } else {
464 None
465 };
466
467 types.insert(
470 ty_def.clone(),
471 WrappedType {
472 ty: new_ty,
473 ty_ret_tmp: Some(new_ty_ret_tmp),
474 ty_static: Some(new_ty_static),
475 return_conv: Some(return_conv),
476 impl_return_conv: None,
477 lifetime_bound,
478 lifetime_type_bound,
479 other_bounds,
480 other_bounds_simple,
481 inject_ret_tmp,
482 unbounded_hrtb: false,
483 },
484 );
485 }
486 _ => {}
487 }
488 }
489
490 if let (Some(ty_def), false) = (ty_def, wrapped) {
491 let new_ty = parse2(format_ident!("CGlueA{}", ty_def.ident).to_token_stream())
492 .expect("Invalid type in unwrapped assoc");
493
494 trait_type_defs.extend(quote!(type #ty_def = #new_ty #ty_where_clause;));
495
496 types.insert(
497 Some(ty_def.clone()),
498 WrappedType {
499 ty: new_ty,
500 ty_ret_tmp: None,
501 ty_static: None,
502 return_conv: None,
503 impl_return_conv: None,
504 lifetime_bound: None,
505 lifetime_type_bound: None,
506 other_bounds: None,
507 other_bounds_simple: None,
508 inject_ret_tmp: false,
509 unbounded_hrtb: false,
510 },
511 );
512
513 assoc_types.insert(ty_def.clone(), ty_bounds.clone());
514 }
515}
516
517pub fn parse_trait(
518 tr: &ItemTrait,
519 crate_path: &TokenStream,
520 also_parse_vtbl_only: bool,
521 mut process_item: impl FnMut(
522 (
523 &Option<AssocType>,
524 &Punctuated<TypeParamBound, Add>,
525 Option<&WhereClause>,
526 &[Attribute],
527 ),
528 &Ident,
529 &ParsedGenerics,
530 &mut TokenStream,
531 &mut BTreeMap<Option<AssocType>, WrappedType>,
532 &mut BTreeMap<AssocType, Punctuated<TypeParamBound, Add>>,
533 &TokenStream,
534 ),
535) -> (
536 Vec<ParsedFunc>,
537 ParsedGenerics,
538 (ParsedGenerics, Vec<Ident>, TokenStream),
539 TokenStream,
540) {
541 let mut funcs = vec![];
542 let generics = ParsedGenerics::from(&tr.generics);
543 let mut trait_type_defs = TokenStream::new();
544 let mut types = BTreeMap::new();
545 let mut types_c_side_vtbl = BTreeMap::new();
546
547 let mut assocs = BTreeMap::new();
548
549 let trait_name = &tr.ident;
550
551 types.insert(
552 Some(AssocType::from(format_ident!("Self"))),
553 WrappedType {
554 ty: parse2(quote!(CGlueC)).unwrap(),
555 ty_ret_tmp: None,
557 ty_static: None,
558 return_conv: Some(
559 parse2(quote!(|ret| {
560 use #crate_path::from2::From2;
561 CGlueC::from2((ret, cglue_ctx))
562 }))
563 .expect("Internal closure parsing fail"),
564 ),
565 lifetime_bound: None,
566 lifetime_type_bound: None,
567 other_bounds: Some(quote!((CGlueC::ObjType, CGlueCtx): Into<CGlueC>,)),
568 other_bounds_simple: Some(quote!((CGlueC::ObjType, CGlueCtx): Into<CGlueC>,)),
569 impl_return_conv: Some(quote!(self.build_with_ccont(ret))),
570 inject_ret_tmp: false,
571 unbounded_hrtb: true,
572 },
573 );
574
575 let int_result = tr
576 .attrs
577 .iter()
578 .filter(|a| a.path.to_token_stream().to_string() == "int_result")
579 .map(|a| {
580 a.parse_args::<Ident>()
581 .unwrap_or_else(|_| format_ident!("Result"))
582 })
583 .next();
584
585 fn unwind_abi(attrs: &[impl AsRef<str>]) -> Option<bool> {
586 if cfg!(__cglue_force_no_unwind_abi) || attrs.iter().any(|i| i.as_ref() == "no_unwind_abi")
587 {
588 return Some(false);
589 }
590 if attrs.iter().any(|i| i.as_ref() == "unwind_abi") {
591 return Some(true);
592 }
593 None
594 }
595
596 let global_unwind_abi = unwind_abi(
597 &tr.attrs
598 .iter()
599 .map(|a| a.path.to_token_stream().to_string())
600 .collect::<Vec<_>>(),
601 );
602
603 for item in &tr.items {
605 match item {
606 TraitItem::Type(ty) => process_item(
608 (
609 &Some(AssocType::new(ty.ident.clone(), ty.generics.clone())),
610 &ty.bounds,
611 ty.generics.where_clause.as_ref(),
612 &ty.attrs,
613 ),
614 &tr.ident,
615 &generics,
616 &mut trait_type_defs,
617 &mut types,
618 &mut assocs,
619 crate_path,
620 ),
621 TraitItem::Method(m) => {
622 let attrs = m
623 .attrs
624 .iter()
625 .map(|a| a.path.to_token_stream().to_string())
626 .collect::<Vec<_>>();
627
628 if attrs.iter().any(|i| i == "skip_func") {
629 continue;
630 }
631
632 let custom_impl = m
633 .attrs
634 .iter()
635 .filter(|a| a.path.to_token_stream().to_string() == "custom_impl")
636 .map(|a| a.parse_args::<CustomFuncImpl>().unwrap())
637 .next();
638
639 let only_c_side = m
640 .attrs
641 .iter()
642 .filter(|a| a.path.to_token_stream().to_string() == "vtbl_only")
643 .map(|a| {
644 a.parse_args::<PathTokens>().ok().map(
645 |PathTokens {
646 lifetime,
647 path,
648 tokens,
649 }| {
650 (
651 lifetime,
652 Attribute {
653 pound_token: Default::default(),
654 style: AttrStyle::Outer,
655 bracket_token: Default::default(),
656 path,
657 tokens,
658 },
659 )
660 },
661 )
662 })
663 .next();
664
665 let (only_c_side, types) = if let Some(attr) = only_c_side {
666 if !also_parse_vtbl_only {
667 continue;
668 }
669
670 types_c_side_vtbl.clear();
671 if let Some((lt, attr)) = attr {
672 let mut punctuated = Punctuated::default();
673
674 if let Some(lt) = lt {
675 punctuated.push_value(TypeParamBound::Lifetime(lt));
676 }
677
678 let attr_slice = std::slice::from_ref(&attr);
679 process_item(
680 (&None, &punctuated, None, attr_slice),
681 &tr.ident,
682 &generics,
683 &mut trait_type_defs,
684 &mut types_c_side_vtbl,
685 &mut Default::default(),
686 crate_path,
687 );
688 }
689 (true, &types_c_side_vtbl)
690 } else {
691 (false, &types)
692 };
693
694 let mut iter = m.sig.generics.params.iter();
695
696 if custom_impl.is_none() && iter.any(|p| !matches!(p, GenericParam::Lifetime(_))) {
697 if m.default.is_none() {
698 panic!("Generic function `{}` detected with neither a default nor custom implementation! This is not supported.", m.sig.ident);
699 }
700 continue;
701 }
702
703 let int_result_new = m
704 .attrs
705 .iter()
706 .filter(|a| a.path.to_token_stream().to_string() == "int_result")
707 .map(|a| {
708 a.parse_args::<Ident>()
709 .unwrap_or_else(|_| format_ident!("Result"))
710 })
711 .next();
712
713 let int_result = int_result_new.as_ref().or(int_result.as_ref());
714
715 funcs.extend(ParsedFunc::new(
716 m.sig.clone(),
717 trait_name.clone(),
718 &generics,
719 types,
720 int_result,
721 int_result
722 .filter(|_| !attrs.iter().any(|i| i == "no_int_result"))
723 .is_some(),
724 crate_path,
725 only_c_side,
726 custom_impl,
727 unwind_abi(&attrs)
728 .or(global_unwind_abi)
729 .unwrap_or(cfg!(feature = "unwind_abi_default")),
730 ));
731 }
732 _ => {}
733 }
734 }
735
736 let assoc_types = {
737 let mut tokens = TokenStream::new();
739 let mut equality = TokenStream::new();
741
742 let mut assoc_vec = vec![];
743
744 for (t, mut b) in assocs {
746 let t = t.ident;
747 let ident = format_ident!("CGlueA{}", t);
748 equality.extend(quote!(#t = #ident,));
749 if b.is_empty() {
750 tokens.extend(quote!(#ident,));
751 } else {
752 if !b.trailing_punct() {
753 b.push_punct(Default::default());
754 }
755 tokens.extend(quote!(#ident: #b))
756 }
757 assoc_vec.push(t);
758 }
759
760 (parse2(quote!(<#tokens>)).unwrap(), assoc_vec, equality)
761 };
762
763 (funcs, generics, assoc_types, trait_type_defs)
764}
765
766pub fn gen_trait(mut tr: ItemTrait, ext_name: Option<&Ident>) -> TokenStream {
767 let crate_path = crate::util::crate_path();
769 let trg_path: TokenStream = quote!(#crate_path::trait_group);
770
771 let vis = tr.vis.to_token_stream();
773
774 let unsafety = tr.unsafety;
775 let trait_name = tr.ident.clone();
776 let trait_name = &trait_name;
777
778 let trait_impl_name = ext_name.unwrap_or(trait_name);
779
780 let c_void = crate::util::void_type();
781
782 let vtbl_ident = format_ident!("{}Vtbl", trait_name);
784 let vtbl_get_ident = format_ident!("{}VtblGet", trait_name);
785 let ret_tmp_ident = format_ident!("{}RetTmp", trait_name);
786 let ret_tmp_ident_phantom = format_ident!("{}RetTmpPhantom", trait_name);
787 let accessor_trait_ident = format_ident!("{}OpaqueObj", trait_name);
788 let assoc_bind_ident = format_ident!("{}AssocBind", trait_name);
789
790 let base_box_trait_obj_ident = format_ident!("{}BaseBox", trait_name);
791 let base_ctx_trait_obj_ident = format_ident!("{}BaseCtxBox", trait_name);
792 let base_arc_trait_obj_ident = format_ident!("{}BaseArcBox", trait_name);
793 let base_mut_trait_obj_ident = format_ident!("{}BaseMut", trait_name);
794 let base_ctx_mut_trait_obj_ident = format_ident!("{}BaseCtxMut", trait_name);
795 let base_arc_mut_trait_obj_ident = format_ident!("{}BaseArcMut", trait_name);
796 let base_ref_trait_obj_ident = format_ident!("{}BaseRef", trait_name);
797 let base_ctx_ref_trait_obj_ident = format_ident!("{}BaseCtxRef", trait_name);
798 let base_arc_ref_trait_obj_ident = format_ident!("{}BaseArcRef", trait_name);
799 let base_trait_obj_ident = format_ident!("{}Base", trait_name);
800
801 let opaque_box_trait_obj_ident = format_ident!("{}Box", trait_name);
802 let opaque_ctx_trait_obj_ident = format_ident!("{}CtxBox", trait_name);
803 let opaque_arc_trait_obj_ident = format_ident!("{}ArcBox", trait_name);
804 let opaque_mut_trait_obj_ident = format_ident!("{}Mut", trait_name);
805 let opaque_ctx_mut_trait_obj_ident = format_ident!("{}CtxMut", trait_name);
806 let opaque_arc_mut_trait_obj_ident = format_ident!("{}ArcMut", trait_name);
807 let opaque_ref_trait_obj_ident = format_ident!("{}Ref", trait_name);
808 let opaque_ctx_ref_trait_obj_ident = format_ident!("{}CtxRef", trait_name);
809 let opaque_arc_ref_trait_obj_ident = format_ident!("{}ArcRef", trait_name);
810
811 let (funcs, generics, (assocs, assoc_idents, assoc_equality), trait_type_defs) =
812 parse_trait(&tr, &crate_path, true, process_item);
813
814 let cglue_c_opaque_bound = cglue_c_opaque_bound();
815 let ctx_bound = ctx_bound();
816
817 tr.ident = trait_impl_name.clone();
818
819 let mut trait_type_bounds = TokenStream::new();
820
821 let ParsedGenerics {
822 life_declare,
823 life_use,
824 gen_declare,
825 gen_use,
826 gen_where_bounds,
827 ..
828 } = &generics;
829
830 let ParsedGenerics {
831 gen_use: assoc_use,
832 gen_declare: assoc_declare,
833 ..
834 } = &assocs;
835
836 let assoc_declare_stripped = assocs.declare_without_nonstatic_bounds();
837
838 let cglue_a_outlives = if life_use.is_empty() {
840 None
841 } else {
842 let mut outlives = quote!(:);
843 for lt in life_use.iter() {
844 outlives.extend(quote!(#lt + ));
845 }
846 Some(outlives)
847 };
848
849 let gen_declare_stripped = generics.declare_without_nonstatic_bounds();
850 let gen_lt_bounds = generics.declare_lt_for_all("e!('cglue_a));
851 let gen_sabi_bounds = generics.declare_sabi_for_all(&crate_path);
852 let assoc_sabi_bounds = assocs.declare_sabi_for_all(&crate_path);
853
854 let gen_where_bounds_base_nolt = gen_where_bounds.clone();
855
856 let gen_where_bounds_base = quote! {
857 #gen_where_bounds
858 #gen_lt_bounds
859 };
860
861 let gen_where_bounds = quote! {
862 #gen_where_bounds_base
863 #gen_sabi_bounds
864 #assoc_sabi_bounds
865 };
866
867 #[cfg(feature = "layout_checks")]
868 let derive_layouts = quote!(#[derive(::abi_stable::StableAbi)]);
869 #[cfg(not(feature = "layout_checks"))]
870 let derive_layouts = quote!();
871
872 let mut vtbl_func_definitions = TokenStream::new();
874
875 for func in &funcs {
876 func.vtbl_def(&mut vtbl_func_definitions);
877 }
878
879 let mut vtbl_getter_defintions = TokenStream::new();
881
882 for func in &funcs {
883 func.vtbl_getter_def(&mut vtbl_getter_defintions);
884 }
885
886 let mut vtbl_default_funcs = TokenStream::new();
888
889 for func in &funcs {
890 func.vtbl_default_def(&mut vtbl_default_funcs);
891 }
892
893 let mut cfuncs = TokenStream::new();
895
896 let ret_tmp_ty = quote!(#ret_tmp_ident<CGlueCtx, #gen_use #assoc_use>);
897
898 for func in funcs.iter() {
899 let extra_bounds = func.cfunc_def(
900 &mut cfuncs,
901 &trg_path,
902 &ret_tmp_ty,
903 &assocs,
904 &assoc_equality,
905 );
906 trait_type_bounds.extend(extra_bounds.to_token_stream());
907 }
908
909 let mut ret_tmp_type_defs = TokenStream::new();
911
912 for func in funcs.iter() {
913 func.ret_tmp_def(&mut ret_tmp_type_defs);
914 }
915
916 let mut ret_tmp_default_defs = TokenStream::new();
918
919 for func in funcs.iter() {
920 func.ret_default_def(&mut ret_tmp_default_defs);
921 }
922
923 let mut ret_tmp_getter_defs = TokenStream::new();
925
926 for func in funcs.iter() {
927 func.ret_getter_def(&mut ret_tmp_getter_defs);
928 }
929
930 let phantom_data_definitions = generics.phantom_data_definitions();
934 let phantom_data_init = generics.phantom_data_init();
935 let assoc_phantom_data_definitions = assocs.phantom_data_definitions();
936 let assoc_phantom_data_init = assocs.phantom_data_init();
937
938 let mut trait_impl_fns = TokenStream::new();
940
941 let mut need_mut = false;
943 let mut need_own = false;
944 let mut need_cgluef = false;
945 let mut return_self = false;
946
947 for func in &funcs {
948 let (nm, no, rs) = func.trait_impl(&mut trait_impl_fns);
949 need_mut = nm || need_mut;
950 need_own = no || need_own;
951 need_cgluef = !no || need_cgluef;
952 return_self = rs || return_self;
953 }
954
955 let required_ctx = if need_mut {
956 quote!(#trg_path::CGlueObjMut<#ret_tmp_ty, Context = CGlueCtx> + )
957 } else {
958 quote!(#trg_path::CGlueObjRef<#ret_tmp_ty, Context = CGlueCtx> + )
959 };
960
961 let cglue_c_into_inner = if need_own {
962 Some(quote!(
963 CGlueC::InstType: #trg_path::IntoInner<InnerTarget = CGlueC::ObjType>,
964 ))
965 } else {
966 None
967 };
968
969 let cglue_c_bounds = quote!(: #required_ctx 'cglue_a);
970
971 let supertrait_bounds = {
974 let sup = &tr.supertraits;
975 if sup.is_empty() {
976 quote!()
977 } else {
978 quote!(+ #sup)
979 }
980 };
981
982 let internal_trait_impl = if let Some(ext_name) = ext_name {
985 let mut impls = TokenStream::new();
986
987 for a in &assoc_idents {
988 impls.extend(quote!(type #a = <Self as #ext_name<#life_use #gen_use>>::#a;));
989 }
990
991 for func in &funcs {
992 func.int_trait_impl(None, ext_name, &mut impls);
993 }
994
995 quote! {
996 #unsafety impl<#life_declare CGlueT, CGlueV, CGlueC, CGlueR, #gen_declare> #trait_name<#life_use #gen_use>
997 for #trg_path::CGlueTraitObj<'_, CGlueT, CGlueV, CGlueC, CGlueR>
998 where
999 Self: #ext_name<#life_use #gen_use>
1000 {
1001 #impls
1002 }
1003 }
1004 } else {
1005 quote!()
1006 };
1007
1008 let vtbl_doc = format!(" CGlue vtable for trait {}.", trait_name);
1010
1011 let base_box_trait_obj_doc = format!(" Boxed CGlue trait object for trait {}.", trait_name);
1012 let base_ctx_trait_obj_doc = format!(
1013 " CtxBoxed CGlue trait object for trait {} with context.",
1014 trait_name
1015 );
1016 let base_arc_trait_obj_doc = format!(" Boxed CGlue trait object for trait {} with a [`CArc`](cglue::arc::CArc) reference counted context.", trait_name);
1017 let base_mut_trait_obj_doc = format!(" By-mut CGlue trait object for trait {}.", trait_name);
1018 let base_ctx_mut_trait_obj_doc = format!(
1019 " By-mut CGlue trait object for trait {} with a context.",
1020 trait_name
1021 );
1022 let base_arc_mut_trait_obj_doc = format!(" By-mut CGlue trait object for trait {} with a [`CArc`](cglue::arc::CArc) reference counted context.", trait_name);
1023 let base_ref_trait_obj_doc = format!(" By-ref CGlue trait object for trait {}.", trait_name);
1024 let base_ctx_ref_trait_obj_doc = format!(
1025 " By-ref CGlue trait object for trait {} with a context.",
1026 trait_name
1027 );
1028 let base_arc_ref_trait_obj_doc = format!(" By-ref CGlue trait object for trait {} with a [`CArc`](cglue::arc::CArc) reference counted context.", trait_name);
1029 let base_trait_obj_doc = format!(" Base CGlue trait object for trait {}.", trait_name);
1030 let opaque_box_trait_obj_doc =
1031 format!(" Opaque Boxed CGlue trait object for trait {}.", trait_name);
1032 let opaque_ctx_trait_obj_doc = format!(
1033 " Opaque CtxBoxed CGlue trait object for trait {} with a context.",
1034 trait_name
1035 );
1036 let opaque_arc_trait_obj_doc = format!(" Opaque Boxed CGlue trait object for trait {} with a [`CArc`](cglue::arc::CArc) reference counted context.", trait_name);
1037 let opaque_mut_trait_obj_doc = format!(
1038 " Opaque by-mut CGlue trait object for trait {}.",
1039 trait_name
1040 );
1041 let opaque_ctx_mut_trait_obj_doc = format!(
1042 " Opaque by-mut CGlue trait object for trait {} with a context.",
1043 trait_name
1044 );
1045 let opaque_arc_mut_trait_obj_doc = format!(
1046 " Opaque by-mut CGlue trait object for trait {} with a [`CArc`](cglue::arc::CArc) reference counted context.",
1047 trait_name
1048 );
1049 let opaque_ref_trait_obj_doc = format!(
1050 " Opaque by-ref CGlue trait object for trait {}.",
1051 trait_name
1052 );
1053 let opaque_ctx_ref_trait_obj_doc = format!(
1054 " Opaque by-ref CGlue trait object for trait {} with a context.",
1055 trait_name
1056 );
1057 let opaque_arc_ref_trait_obj_doc = format!(
1058 " Opaque by-ref CGlue trait object for trait {} with a [`CArc`](cglue::arc::CArc) reference counted context.",
1059 trait_name
1060 );
1061 let submod_name = format_ident!("cglue_{}", trait_name.to_string().to_lowercase());
1062
1063 let ret_tmp = if !ret_tmp_type_defs.is_empty() {
1064 quote! {
1065 #[repr(C)]
1071 #derive_layouts
1072 pub struct #ret_tmp_ident<CGlueCtx: #ctx_bound, #gen_use #assoc_use>
1073 {
1074 #ret_tmp_type_defs
1075 #phantom_data_definitions
1076 #assoc_phantom_data_definitions
1077 _ty_cglue_ctx: ::core::marker::PhantomData<CGlueCtx>,
1078 }
1079
1080 impl<CGlueCtx: #ctx_bound, #gen_use #assoc_use> #ret_tmp_ident<CGlueCtx, #gen_use #assoc_use>
1081 {
1082 #ret_tmp_getter_defs
1083 }
1084
1085 impl<CGlueCtx: #ctx_bound, #gen_use #assoc_use> Default for #ret_tmp_ident<CGlueCtx, #gen_use #assoc_use>
1086 {
1087 fn default() -> Self {
1088 Self {
1089 #ret_tmp_default_defs
1090 #phantom_data_init
1091 #assoc_phantom_data_init
1092 _ty_cglue_ctx: ::core::marker::PhantomData,
1093 }
1094 }
1095 }
1096 }
1097 } else {
1098 quote! {
1099 #[repr(C)]
1101 #derive_layouts
1102 pub struct #ret_tmp_ident_phantom<CGlueCtx: #ctx_bound, #gen_use #assoc_use>
1103 {
1104 #phantom_data_definitions
1105 #assoc_phantom_data_definitions
1106 _ty_cglue_ctx: ::core::marker::PhantomData<CGlueCtx>,
1107 }
1108
1109 pub type #ret_tmp_ident<CGlueCtx, #gen_use #assoc_use> = ::core::marker::PhantomData<#ret_tmp_ident_phantom<CGlueCtx, #gen_use #assoc_use>>;
1120 }
1121 };
1122
1123 #[cfg(feature = "layout_checks")]
1124 let (opaque_vtbl_bounds, container_vtbl_bounds) = (
1125 quote!(#vtbl_ident<'cglue_a, CGlueC::OpaqueTarget, #gen_use #assoc_use>: ::abi_stable::StableAbi,),
1126 quote!(#vtbl_ident<'cglue_a, <Self as #trg_path::GetContainer>::ContType, #gen_use #assoc_use>: ::abi_stable::StableAbi,),
1127 );
1128 #[cfg(not(feature = "layout_checks"))]
1129 let (opaque_vtbl_bounds, container_vtbl_bounds) = (quote!(), quote!());
1130
1131 #[cfg(feature = "layout_checks")]
1132 let (layout_checkable_bound, objcont_accessor_bound) = (
1133 quote!(::abi_stable::StableAbi),
1134 quote!(<CGlueO as #trg_path::GetContainer>::ContType: ::abi_stable::StableAbi,),
1135 );
1136 #[cfg(not(feature = "layout_checks"))]
1137 let (layout_checkable_bound, objcont_accessor_bound) = (quote!(), quote!());
1138
1139 quote! {
1141 #tr
1142
1143 #[doc(hidden)]
1144 #vis use #submod_name::*;
1145
1146 pub mod #submod_name {
1147 use super::*;
1148 use super::#trait_impl_name;
1149
1150 #vis use cglue_internal::{
1151 #vtbl_ident,
1152 #vtbl_get_ident,
1153 #ret_tmp_ident,
1154 #accessor_trait_ident,
1155 #assoc_bind_ident,
1156
1157 #base_box_trait_obj_ident,
1158 #base_ctx_trait_obj_ident,
1159 #base_arc_trait_obj_ident,
1160 #base_mut_trait_obj_ident,
1161 #base_ctx_mut_trait_obj_ident,
1162 #base_arc_mut_trait_obj_ident,
1163 #base_ref_trait_obj_ident,
1164 #base_ctx_ref_trait_obj_ident,
1165 #base_arc_ref_trait_obj_ident,
1166 #base_trait_obj_ident,
1167
1168 #opaque_box_trait_obj_ident,
1169 #opaque_ctx_trait_obj_ident,
1170 #opaque_arc_trait_obj_ident,
1171 #opaque_mut_trait_obj_ident,
1172 #opaque_ctx_mut_trait_obj_ident,
1173 #opaque_arc_mut_trait_obj_ident,
1174 #opaque_ref_trait_obj_ident,
1175 #opaque_ctx_ref_trait_obj_ident,
1176 #opaque_arc_ref_trait_obj_ident,
1177 };
1178
1179 mod cglue_internal {
1180 use super::*;
1181 use super::#trait_impl_name;
1182
1183 #[doc = #vtbl_doc]
1186 #[repr(C)]
1189 #derive_layouts
1190 pub struct #vtbl_ident<
1191 'cglue_a,
1192 CGlueC: 'cglue_a + #trg_path::CGlueObjBase,
1193 #gen_declare_stripped
1194 #assoc_declare_stripped
1195 >
1196 where
1197 #gen_where_bounds_base_nolt
1198 {
1199 #vtbl_func_definitions
1200 #assoc_phantom_data_definitions
1201 _lt_cglue_a: ::core::marker::PhantomData<&'cglue_a CGlueC>,
1202 }
1203
1204 impl<
1205 'cglue_a,
1206 CGlueC: #trg_path::CGlueObjBase,
1207 #gen_declare_stripped
1208 #assoc_declare_stripped
1209 > #vtbl_ident<'cglue_a, CGlueC, #gen_use #assoc_use>
1210 where
1211 #gen_where_bounds
1212 {
1213 #vtbl_getter_defintions
1214 }
1215
1216 #ret_tmp
1217
1218 impl<'cglue_a, CGlueC #cglue_c_bounds, CGlueCtx: #ctx_bound, #gen_declare_stripped #assoc_declare_stripped> Default
1222 for &'cglue_a #vtbl_ident<'cglue_a, CGlueC, #gen_use #assoc_use>
1223 where #gen_where_bounds #trait_type_bounds #cglue_c_into_inner
1224 CGlueC::ObjType: for<#life_declare> #trait_name<#life_use #gen_use #assoc_equality>,
1225 CGlueC: #trg_path::Opaquable,
1226 CGlueC::OpaqueTarget: #trg_path::GenericTypeBounds,
1227 #vtbl_ident<'cglue_a, CGlueC, #gen_use #assoc_use>: #trg_path::CGlueBaseVtbl,
1228 {
1229 fn default() -> Self {
1231 &#vtbl_ident {
1232 #vtbl_default_funcs
1233 #assoc_phantom_data_init
1234 _lt_cglue_a: ::core::marker::PhantomData,
1235 }
1236 }
1237 }
1238
1239 impl<
1242 'cglue_a,
1243 CGlueC: #trg_path::CGlueObjBase,
1244 #gen_declare_stripped
1245 #assoc_declare_stripped
1246 >
1247 #trg_path::CGlueVtblCont for #vtbl_ident<'cglue_a, CGlueC, #gen_use #assoc_use>
1248 where
1249 #gen_where_bounds
1250 {
1251 type ContType = CGlueC;
1252 }
1253
1254 unsafe impl<
1255 'cglue_a,
1256 CGlueC: #trg_path::Opaquable + #trg_path::CGlueObjBase + 'cglue_a,
1257 #gen_declare_stripped
1258 #assoc_declare_stripped
1259 > #trg_path::CGlueBaseVtbl
1260 for #vtbl_ident<'cglue_a, CGlueC, #gen_use #assoc_use>
1261 where #gen_where_bounds #cglue_c_opaque_bound
1262 CGlueC::ObjType: for<#life_declare> #trait_name<#life_use #gen_use #assoc_equality>,
1263 CGlueC::OpaqueTarget: #trg_path::GenericTypeBounds,
1264 #opaque_vtbl_bounds
1265 {
1266 type OpaqueVtbl = #vtbl_ident<'cglue_a, CGlueC::OpaqueTarget, #gen_use #assoc_use>;
1267 type Context = CGlueC::Context;
1268 type RetTmp = #ret_tmp_ident<CGlueC::Context, #gen_use #assoc_use>;
1269 }
1270
1271 impl<'cglue_a, CGlueC #cglue_c_bounds, CGlueCtx: #ctx_bound, #gen_declare_stripped #assoc_declare_stripped> #trg_path::CGlueVtbl<CGlueC>
1272 for #vtbl_ident<'cglue_a, CGlueC, #gen_use #assoc_use>
1273 where #gen_where_bounds
1274 #cglue_c_opaque_bound
1275 CGlueC: #trg_path::Opaquable,
1276 CGlueC::OpaqueTarget: #trg_path::GenericTypeBounds,
1277 CGlueC::ObjType: for<#life_declare> #trait_name<#life_use #gen_use #assoc_equality> {}
1278
1279 #[doc = #base_box_trait_obj_doc]
1280 pub type #base_box_trait_obj_ident<'cglue_a, CGlueT, #gen_use #assoc_use>
1281 = #base_trait_obj_ident<'cglue_a, #crate_path::boxed::CBox<'cglue_a, CGlueT>, #trg_path::NoContext, #gen_use #assoc_use>;
1282
1283 #[doc = #base_ctx_trait_obj_doc]
1284 pub type #base_ctx_trait_obj_ident<'cglue_a, CGlueT, CGlueCtx, #gen_use #assoc_use>
1285 = #base_trait_obj_ident<'cglue_a, #crate_path::boxed::CBox<'cglue_a, CGlueT>, CGlueCtx, #gen_use #assoc_use>;
1286
1287 #[doc = #base_arc_trait_obj_doc]
1288 pub type #base_arc_trait_obj_ident<'cglue_a, CGlueT, CGlueC, #gen_use #assoc_use>
1289 = #base_ctx_trait_obj_ident<'cglue_a, CGlueT, #crate_path::arc::CArc<CGlueC>, #gen_use #assoc_use>;
1290
1291 #[doc = #base_mut_trait_obj_doc]
1292 pub type #base_mut_trait_obj_ident<'cglue_a, CGlueT, #gen_use #assoc_use>
1293 = #base_trait_obj_ident<'cglue_a, &'cglue_a mut CGlueT, #trg_path::NoContext, #gen_use #assoc_use>;
1294
1295 #[doc = #base_ctx_mut_trait_obj_doc]
1296 pub type #base_ctx_mut_trait_obj_ident<'cglue_a, CGlueT, CGlueCtx, #gen_use #assoc_use>
1297 = #base_trait_obj_ident<'cglue_a, &'cglue_a mut CGlueT, CGlueCtx, #gen_use #assoc_use>;
1298
1299 #[doc = #base_arc_mut_trait_obj_doc]
1300 pub type #base_arc_mut_trait_obj_ident<'cglue_a, CGlueT, CGlueC, #gen_use #assoc_use>
1301 = #base_trait_obj_ident<'cglue_a, &'cglue_a mut CGlueT, #crate_path::arc::CArc<CGlueC>, #gen_use #assoc_use>;
1302
1303 #[doc = #base_ref_trait_obj_doc]
1304 pub type #base_ref_trait_obj_ident<'cglue_a, CGlueT, #gen_use #assoc_use>
1305 = #base_trait_obj_ident<'cglue_a, &'cglue_a CGlueT, #trg_path::NoContext, #gen_use #assoc_use>;
1306
1307 #[doc = #base_ctx_ref_trait_obj_doc]
1308 pub type #base_ctx_ref_trait_obj_ident<'cglue_a, CGlueT, CGlueCtx, #gen_use #assoc_use>
1309 = #base_trait_obj_ident<'cglue_a, &'cglue_a CGlueT, CGlueCtx, #gen_use #assoc_use>;
1310
1311 #[doc = #base_arc_ref_trait_obj_doc]
1312 pub type #base_arc_ref_trait_obj_ident<'cglue_a, CGlueT, CGlueC, #gen_use #assoc_use>
1313 = #base_trait_obj_ident<'cglue_a, &'cglue_a CGlueT, #crate_path::arc::CArc<CGlueC>, #gen_use #assoc_use>;
1314
1315 #[doc = #base_trait_obj_doc]
1316 pub type #base_trait_obj_ident<'cglue_a, CGlueInst, CGlueCtx, #gen_use #assoc_use>
1317 = #trg_path::CGlueTraitObj::<
1318 'cglue_a,
1319 CGlueInst,
1320 #vtbl_ident<
1321 'cglue_a,
1322 #trg_path::CGlueObjContainer<CGlueInst, CGlueCtx, #ret_tmp_ident<CGlueCtx, #gen_use #assoc_use>>,
1323 #gen_use
1324 #assoc_use
1325 >,
1326 CGlueCtx,
1327 #ret_tmp_ident<CGlueCtx, #gen_use #assoc_use>
1328 >;
1329
1330 #[doc = #opaque_box_trait_obj_doc]
1331 pub type #opaque_box_trait_obj_ident<'cglue_a, #gen_use #assoc_use>
1332 = #base_box_trait_obj_ident<'cglue_a, #c_void, #gen_use #assoc_use>;
1333
1334 #[doc = #opaque_ctx_trait_obj_doc]
1335 pub type #opaque_ctx_trait_obj_ident<'cglue_a, CGlueCtx, #gen_use #assoc_use>
1336 = #base_ctx_trait_obj_ident<'cglue_a, #c_void, CGlueCtx, #gen_use #assoc_use>;
1337
1338 #[doc = #opaque_arc_trait_obj_doc]
1339 pub type #opaque_arc_trait_obj_ident<'cglue_a, #gen_use #assoc_use>
1340 = #base_arc_trait_obj_ident<'cglue_a, #c_void, #c_void, #gen_use #assoc_use>;
1341
1342 #[doc = #opaque_mut_trait_obj_doc]
1343 pub type #opaque_mut_trait_obj_ident<'cglue_a, #gen_use #assoc_use>
1344 = #base_mut_trait_obj_ident<'cglue_a, #c_void, #gen_use #assoc_use>;
1345
1346 #[doc = #opaque_ctx_mut_trait_obj_doc]
1347 pub type #opaque_ctx_mut_trait_obj_ident<'cglue_a, CGlueCtx, #gen_use #assoc_use>
1348 = #base_ctx_mut_trait_obj_ident<'cglue_a, #c_void, CGlueCtx, #gen_use #assoc_use>;
1349
1350 #[doc = #opaque_arc_mut_trait_obj_doc]
1351 pub type #opaque_arc_mut_trait_obj_ident<'cglue_a, #gen_use #assoc_use>
1352 = #base_arc_mut_trait_obj_ident<'cglue_a, #c_void, #c_void, #gen_use #assoc_use>;
1353
1354 #[doc = #opaque_ref_trait_obj_doc]
1355 pub type #opaque_ref_trait_obj_ident<'cglue_a, #gen_use #assoc_use>
1356 = #base_ref_trait_obj_ident<'cglue_a, #c_void, #gen_use #assoc_use>;
1357
1358 #[doc = #opaque_ctx_ref_trait_obj_doc]
1359 pub type #opaque_ctx_ref_trait_obj_ident<'cglue_a, CGlueCtx, #gen_use #assoc_use>
1360 = #base_ctx_ref_trait_obj_ident<'cglue_a, #c_void, CGlueCtx, #gen_use #assoc_use>;
1361
1362 #[doc = #opaque_arc_ref_trait_obj_doc]
1363 pub type #opaque_arc_ref_trait_obj_ident<'cglue_a, #gen_use #assoc_use>
1364 = #base_arc_ref_trait_obj_ident<'cglue_a, #c_void, #c_void, #gen_use #assoc_use>;
1365
1366 #cfuncs
1369
1370 pub trait #accessor_trait_ident<'cglue_a #cglue_a_outlives, #life_declare #gen_declare #assoc_declare>
1373 : 'cglue_a + #trg_path::GetContainer + #vtbl_get_ident<'cglue_a, #gen_use #assoc_use> #supertrait_bounds
1374 where
1375 #gen_where_bounds
1376 {
1377 type #vtbl_ident: #trg_path::CGlueVtblCont<ContType = <Self as #trg_path::GetContainer>::ContType> + #layout_checkable_bound;
1378 }
1379
1380 impl<'cglue_a #cglue_a_outlives, #life_declare
1381 CGlueO: 'cglue_a + #trg_path::GetContainer + #vtbl_get_ident<'cglue_a, #gen_use #assoc_use> #supertrait_bounds, #gen_declare #assoc_declare>
1382 #accessor_trait_ident<'cglue_a, #life_use #gen_use #assoc_use> for CGlueO
1383 where
1384 #objcont_accessor_bound
1385 #gen_where_bounds
1386 {
1387 type #vtbl_ident = #vtbl_ident<'cglue_a, <Self as #trg_path::GetContainer>::ContType, #gen_use #assoc_use>;
1388 }
1389
1390 pub trait #assoc_bind_ident<#gen_use> {
1393 type Assocs;
1394 }
1395
1396 impl<
1397 'cglue_a,
1398 CGlueT: ::core::ops::Deref<Target = CGlueF>,
1399 CGlueF,
1400 CGlueCtx: #ctx_bound,
1401 CGlueRetTmp,
1402 #gen_declare_stripped
1403 #assoc_declare_stripped
1404 >
1405 #assoc_bind_ident<#gen_use>
1406 for #trg_path::CGlueTraitObj<'cglue_a, CGlueT, #vtbl_ident<'cglue_a, #trg_path::CGlueObjContainer<CGlueT, CGlueCtx, CGlueRetTmp>, #gen_use #assoc_use>, CGlueCtx, CGlueRetTmp>
1407 where
1408 #gen_where_bounds_base
1409 {
1410 type Assocs = (#assoc_use);
1411 }
1412
1413 pub trait #vtbl_get_ident<'cglue_a, #gen_declare_stripped #assoc_declare_stripped>:
1416 #trg_path::GetContainer
1417 where
1418 #gen_where_bounds_base
1419 {
1420 fn get_vtbl(&self) -> &#vtbl_ident<'cglue_a, <Self as #trg_path::GetContainer>::ContType, #gen_use #assoc_use>;
1421 }
1422
1423 impl<
1424 'cglue_a,
1425 CGlueT: ::core::ops::Deref<Target = CGlueF>,
1426 CGlueF,
1427 CGlueCtx: #ctx_bound,
1428 CGlueRetTmp,
1429 #gen_declare_stripped
1430 #assoc_declare_stripped
1431 >
1432 #vtbl_get_ident<'cglue_a, #gen_use #assoc_use>
1433 for #trg_path::CGlueTraitObj<'cglue_a, CGlueT, #vtbl_ident<'cglue_a, #trg_path::CGlueObjContainer<CGlueT, CGlueCtx, CGlueRetTmp>, #gen_use #assoc_use>, CGlueCtx, CGlueRetTmp>
1434 where
1435 #gen_where_bounds_base
1436 {
1437 fn get_vtbl(&self) -> &#vtbl_ident<'cglue_a, <Self as #trg_path::GetContainer>::ContType, #gen_use #assoc_use> {
1438 #trg_path::GetVtblBase::get_vtbl_base(self)
1439 }
1440 }
1441
1442 #unsafety impl<'cglue_a #cglue_a_outlives, #life_declare
1445 CGlueO: 'cglue_a + #vtbl_get_ident<'cglue_a, #gen_use #assoc_use> #supertrait_bounds
1446 + #accessor_trait_ident<'cglue_a, #life_use #gen_use #assoc_use>
1450 + #assoc_bind_ident<#gen_use Assocs = (#assoc_use)>
1452 + #trg_path::GetVtblBase<#vtbl_ident<'cglue_a, <Self as #trg_path::GetContainer>::ContType, #gen_use #assoc_use>>,
1456 #gen_declare #assoc_declare>
1457 #trait_impl_name<#life_use #gen_use> for CGlueO
1458 where
1459 #gen_where_bounds
1460 #container_vtbl_bounds
1461 {
1462 #trait_type_defs
1464 #trait_impl_fns
1465 }
1466
1467 #internal_trait_impl
1468 }
1469 }
1470 }
1471}