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