@@ -688,26 +688,37 @@ pub fn translate(
688688 }
689689 }
690690
691- // Export top-level value declarations
692- for top_id in & t. ast_context . c_decls_top {
693- use CDeclKind :: * ;
694- let needs_export = match t. ast_context [ * top_id] . kind {
695- Function { is_implicit, .. } => !is_implicit,
696- Variable { .. } => true ,
697- MacroObject { .. } => true , // Depends on `tcfg.translate_const_macros`, but handled in `fn convert_const_macro_expansion`.
698- MacroFunction { .. } => true , // Depends on `tcfg.translate_fn_macros`, but handled in `fn convert_fn_macro_invocation`.
699- _ => false ,
700- } ;
701- if needs_export {
702- let decl = t. ast_context . get_decl ( top_id) . unwrap ( ) ;
691+ // Export top-level value declarations.
692+ // We do this in a conversion pass and then an insertion pass
693+ // so that the conversion order can differ from the order they're emitted in.
694+ let mut converted_decls = t
695+ . ast_context
696+ . c_decls_top
697+ . iter ( )
698+ . filter_map ( |& top_id| {
699+ use CDeclKind :: * ;
700+ let needs_export = match t. ast_context [ top_id] . kind {
701+ Function { is_implicit, .. } => !is_implicit,
702+ Variable { .. } => true ,
703+ MacroObject { .. } => true , // Depends on `tcfg.translate_const_macros`, but handled in `fn convert_const_macro_expansion`.
704+ MacroFunction { .. } => true , // Depends on `tcfg.translate_fn_macros`, but handled in `fn convert_fn_macro_invocation`.
705+ _ => false ,
706+ } ;
707+ if !needs_export {
708+ return None ;
709+ }
710+
711+ let decl = t. ast_context . get_decl ( & top_id) . unwrap ( ) ;
703712 let decl_file_id = t. ast_context . file_id ( decl) ;
704713
705714 if t. tcfg . reorganize_definitions
706715 && decl_file_id. map_or ( false , |id| id != t. main_file )
707716 {
708717 t. cur_file . set ( decl_file_id) ;
709718 }
710- match t. convert_decl ( ctx, * top_id) {
719+
720+ // TODO use `.inspect_err` once stabilized in Rust 1.76.
721+ let converted = match t. convert_decl ( ctx, top_id) {
711722 Err ( e) => {
712723 let decl_identifier = decl. kind . get_name ( ) . map_or_else (
713724 || {
@@ -719,32 +730,45 @@ pub fn translate(
719730 ) ;
720731 let msg = format ! ( "Failed to translate {}: {}" , decl_identifier, e) ;
721732 translate_failure ( t. tcfg , & msg) ;
733+ Err ( e)
722734 }
723- Ok ( converted_decl) => {
724- use ConvertedDecl :: * ;
725- match converted_decl {
726- Item ( item) => {
727- t. insert_item ( item, decl) ;
728- }
729- ForeignItem ( item) => {
730- t. insert_foreign_item ( * item, decl) ;
731- }
732- Items ( items) => {
733- for item in items {
734- t. insert_item ( item, decl) ;
735- }
736- }
737- NoItem => { }
738- }
739- }
735+ Ok ( converted) => Ok ( converted) ,
740736 }
737+ . ok ( ) ?;
738+
741739 t. cur_file . take ( ) ;
742740
743- if t. tcfg . reorganize_definitions
744- && decl_file_id. map_or ( false , |id| id != t. main_file )
745- {
746- t. generate_submodule_imports ( * top_id, decl_file_id) ;
741+ Some ( ( top_id, converted) )
742+ } )
743+ . collect :: < HashMap < _ , _ > > ( ) ;
744+
745+ for top_id in & t. ast_context . c_decls_top {
746+ let decl = t. ast_context . get_decl ( top_id) . unwrap ( ) ;
747+ let decl_file_id = t. ast_context . file_id ( decl) ;
748+ // TODO use `let else` when it stabilizes.
749+ let converted_decl = match converted_decls. remove ( top_id) {
750+ Some ( converted) => converted,
751+ None => continue ,
752+ } ;
753+
754+ use ConvertedDecl :: * ;
755+ match converted_decl {
756+ Item ( item) => {
757+ t. insert_item ( item, decl) ;
747758 }
759+ ForeignItem ( item) => {
760+ t. insert_foreign_item ( * item, decl) ;
761+ }
762+ Items ( items) => {
763+ for item in items {
764+ t. insert_item ( item, decl) ;
765+ }
766+ }
767+ NoItem => { }
768+ } ;
769+
770+ if t. tcfg . reorganize_definitions && decl_file_id. map_or ( false , |id| id != t. main_file ) {
771+ t. generate_submodule_imports ( * top_id, decl_file_id) ;
748772 }
749773 }
750774
0 commit comments