@@ -23,9 +23,9 @@ use itertools::Itertools;
2323use proc_macro2:: { Ident , TokenStream } ;
2424use quote:: quote;
2525use std:: collections:: HashMap ;
26- use std:: iter;
2726use std:: num:: NonZeroUsize ;
2827use std:: rc:: Rc ;
28+ use std:: { iter, mem} ;
2929
3030/// Returns whether fields of type `ty` need to be wrapped in `ManuallyDrop<T>`
3131/// to prevent the fields from being destructed twice (once by the C++
@@ -478,15 +478,14 @@ pub fn generate_record(db: &dyn BindingsGenerator, record: Rc<Record>) -> Result
478478 } )
479479 . collect ( ) ,
480480 } ;
481- let mut features = FlagSet :: empty ( ) ;
482-
481+ let mut api_snippets = ApiSnippets :: default ( ) ;
483482 let recursively_pinned_attr = if record. is_unpin ( ) {
484483 None
485484 } else {
486485 // negative_impls are necessary for universal initialization due to Rust's
487486 // coherence rules: PhantomPinned isn't enough to prove to Rust that a
488487 // blanket impl that requires Unpin doesn't apply. See http://<internal link>=h.f6jp8ifzgt3n
489- features |= Feature :: negative_impls;
488+ api_snippets . features |= Feature :: negative_impls;
490489 Some ( RecursivelyPinnedAttr { pinned_drop : record. should_implement_drop ( ) } )
491490 } ;
492491
@@ -517,21 +516,21 @@ pub fn generate_record(db: &dyn BindingsGenerator, record: Rc<Record>) -> Result
517516
518517 let fully_qualified_cc_name = cpp_tagless_type_name_for_record ( & record, ir) ?. to_string ( ) ;
519518
520- let mut record_generated_items = vec ! [ ] ;
519+ let mut record_generated_snippets = ApiSnippets :: default ( ) ;
521520 let mut record_child_generated_main_apis = vec ! [ ] ;
522521 for & child_item_id in & record. child_item_ids {
523522 let item = ir. find_untyped_decl ( child_item_id) ;
524- let mut api_snippets = db. generate_item ( item. clone ( ) ) ?;
523+ let mut child_api_snippets = db. generate_item ( item. clone ( ) ) ?;
525524 if item. place_in_nested_module_if_nested_in_record ( )
526525 && db. has_bindings ( item. clone ( ) ) . is_ok ( )
527526 {
528527 // If it doesn't have bindings, we don't want to put it in the nested module.
529- record_child_generated_main_apis. append ( & mut api_snippets . main_api ) ;
528+ record_child_generated_main_apis. append ( & mut child_api_snippets . main_api ) ;
530529 }
531- record_generated_items . push ( api_snippets ) ;
530+ record_generated_snippets . append ( child_api_snippets ) ;
532531 }
533532
534- let generated_inherited_functions : Vec < ApiSnippets > = filter_out_ambiguous_member_functions (
533+ filter_out_ambiguous_member_functions (
535534 db,
536535 record. clone ( ) ,
537536 collect_unqualified_member_functions_from_all_bases ( db, & record) ,
@@ -544,8 +543,9 @@ pub fn generate_record(db: &dyn BindingsGenerator, record: Rc<Record>) -> Result
544543 db. generate_function ( ir_func. clone ( ) , Some ( record. clone ( ) ) ) . ok ( ) . flatten ( ) ?;
545544 Some ( ( * generated_func. snippets ) . clone ( ) )
546545 } )
547- . collect ( ) ;
548- record_generated_items. extend ( generated_inherited_functions) ;
546+ . for_each ( |func_snippets| {
547+ record_generated_snippets. append ( func_snippets) ;
548+ } ) ;
549549
550550 // Both the template definition and its instantiation should enable experimental
551551 // features.
@@ -554,7 +554,7 @@ pub fn generate_record(db: &dyn BindingsGenerator, record: Rc<Record>) -> Result
554554 crubit_features |= ir. target_crubit_features ( defining_target) ;
555555 }
556556 if crubit_features. contains ( crubit_feature:: CrubitFeature :: Experimental ) {
557- record_generated_items . push ( cc_struct_upcast_impl ( db, & record, ir) ?) ;
557+ record_generated_snippets . append ( cc_struct_upcast_impl ( db, & record, ir) ?) ;
558558 }
559559 let no_unique_address_accessors =
560560 if crubit_features. contains ( crubit_feature:: CrubitFeature :: Experimental ) {
@@ -572,18 +572,10 @@ pub fn generate_record(db: &dyn BindingsGenerator, record: Rc<Record>) -> Result
572572 None
573573 } ;
574574
575- let mut items = vec ! [ ] ;
576- let mut thunks_from_record_items = vec ! [ ] ;
577- let mut thunk_impls_from_record_items = vec ! [ cc_struct_layout_assertion( db, & record) ?] ;
578- let mut assertions_from_record_items = vec ! [ ] ;
579-
580- for generated in record_generated_items {
581- items. extend ( generated. main_api ) ;
582- thunks_from_record_items. extend ( generated. thunks ) ;
583- assertions_from_record_items. extend ( generated. assertions ) ;
584- thunk_impls_from_record_items. extend ( generated. cc_details ) ;
585- features |= generated. features ;
586- }
575+ api_snippets. cc_details . push ( cc_struct_layout_assertion ( db, & record) ?) ;
576+
577+ let items = mem:: take ( & mut record_generated_snippets. main_api ) ;
578+ api_snippets. append ( record_generated_snippets) ;
587579
588580 let cxx_impl = if fully_qualified_cc_name. contains ( '<' ) {
589581 // cxx can't parse templated type names.
@@ -638,7 +630,7 @@ pub fn generate_record(db: &dyn BindingsGenerator, record: Rc<Record>) -> Result
638630 nested_items : record_child_generated_main_apis,
639631 } ;
640632
641- features |= Feature :: negative_impls;
633+ api_snippets . features |= Feature :: negative_impls;
642634 let record_trait_assertions = {
643635 let mut assert_impls = FlagSet :: empty ( ) ;
644636 let mut assert_not_impls = FlagSet :: empty ( ) ;
@@ -665,27 +657,19 @@ pub fn generate_record(db: &dyn BindingsGenerator, record: Rc<Record>) -> Result
665657 }
666658 } ;
667659
668- let mut assertions = vec ! [ ] ;
669- assertions. push ( rs_size_align_assertions ( qualified_ident, & record. size_align ) ) ;
670- assertions. push ( record_trait_assertions) ;
671- assertions. push ( field_offset_assertions) ;
672- assertions. extend ( fields_that_must_be_copy. into_iter ( ) . map ( |formatted_field_type| {
673- Assertion :: Impls {
660+ api_snippets. assertions . push ( rs_size_align_assertions ( qualified_ident, & record. size_align ) ) ;
661+ api_snippets. assertions . push ( record_trait_assertions) ;
662+ api_snippets. assertions . push ( field_offset_assertions) ;
663+ api_snippets. assertions . extend ( fields_that_must_be_copy. into_iter ( ) . map (
664+ |formatted_field_type| Assertion :: Impls {
674665 type_name : formatted_field_type,
675666 all_of : AssertableTrait :: Copy . into ( ) ,
676667 none_of : FlagSet :: empty ( ) ,
677- }
678- } ) ) ;
679- assertions. extend ( assertions_from_record_items) ;
680-
681- Ok ( ApiSnippets {
682- main_api : vec ! [ MainApi :: Record ( record_tokens) ] ,
683- features,
684- assertions,
685- thunks : thunks_from_record_items,
686- cc_details : thunk_impls_from_record_items,
687- ..Default :: default ( )
688- } )
668+ } ,
669+ ) ) ;
670+
671+ api_snippets. main_api . push ( MainApi :: Record ( record_tokens) ) ;
672+ Ok ( api_snippets)
689673}
690674
691675pub fn rs_size_align_assertions ( type_name : TokenStream , size_align : & ir:: SizeAlign ) -> Assertion {
0 commit comments