@@ -700,6 +700,62 @@ fn per_module_llvm_ir_units_split_definitions_and_declarations() {
700700 ) ;
701701}
702702
703+ #[ test]
704+ fn per_module_llvm_ir_units_preserve_enum_payload_abi_across_modules ( ) {
705+ let path = fixture ( "ok_enum_payload_across_modules.w" ) ;
706+ let opts = CompilerOptions {
707+ emit_llvm_ir_units : true ,
708+ ..Default :: default ( )
709+ } ;
710+
711+ let result = whatever_driver:: check ( & path, & opts) ;
712+ assert ! (
713+ result. ok,
714+ "expected fixture to pass, got:\n {}" ,
715+ result. rendered_diags
716+ ) ;
717+
718+ let units = result
719+ . llvm_ir_units
720+ . expect ( "emit_llvm_ir_units should produce per-module LLVM IR units" ) ;
721+ let entry = units
722+ . get ( "ok_enum_payload_across_modules" )
723+ . expect ( "expected entry module unit: ok_enum_payload_across_modules" ) ;
724+ let eabi = units. get ( "eabi" ) . expect ( "expected module unit: eabi" ) ;
725+
726+ assert ! (
727+ entry. contains( "declare" ) && entry. contains( "@eabi__takes" ) ,
728+ "expected entry unit to declare eabi::takes, got:\n {entry}"
729+ ) ;
730+ assert ! (
731+ entry. contains( "call" ) && entry. contains( "@eabi__takes" ) ,
732+ "expected entry unit to call eabi::takes, got:\n {entry}"
733+ ) ;
734+ assert ! (
735+ !entry. contains( "define ccc i32 @eabi__takes" ) ,
736+ "expected entry unit to not define eabi::takes, got:\n {entry}"
737+ ) ;
738+
739+ assert ! (
740+ eabi. contains( "define ccc" ) && eabi. contains( "@eabi__takes" ) ,
741+ "expected eabi unit to define eabi::takes, got:\n {eabi}"
742+ ) ;
743+ assert ! (
744+ !eabi. contains( "declare i32 @eabi__takes" ) ,
745+ "expected eabi unit to not declare eabi::takes (it defines it), got:\n {eabi}"
746+ ) ;
747+
748+ // Shape-level ABI stability: both units should agree on the enum representation.
749+ assert ! (
750+ entry. contains( "{ i32, i1, i32 }" ) ,
751+ "expected entry unit to contain enum repr shape, got:\n {entry}"
752+ ) ;
753+ assert ! (
754+ eabi. contains( "{ i32, i1, i32 }" ) ,
755+ "expected eabi unit to contain enum repr shape, got:\n {eabi}"
756+ ) ;
757+ }
758+
703759fn tool_available ( tool : & str ) -> bool {
704760 std:: process:: Command :: new ( tool)
705761 . arg ( "--version" )
@@ -769,6 +825,52 @@ fn separate_compilation_emits_per_module_objects_when_clang_is_available() {
769825 assert ! ( foo_o. exists( ) , "expected foo object to exist: {foo_o:?}" ) ;
770826}
771827
828+ #[ test]
829+ fn separate_compilation_emits_per_module_objects_for_enum_payload_when_clang_is_available ( ) {
830+ // Strong regression for cross-module ABI: compiles per-module objects.
831+ if !tool_available ( "clang" ) {
832+ eprintln ! (
833+ "skipping: clang not found in PATH (install LLVM/Clang to enable separate-compilation object emission regression)"
834+ ) ;
835+ return ;
836+ }
837+
838+ let path = fixture ( "ok_enum_payload_across_modules.w" ) ;
839+ let out_dir = unique_temp_out_dir ( "separate_compilation_enum_payload_emits_objects" ) ;
840+
841+ let opts = CompilerOptions {
842+ emit_object : true ,
843+ link_executable : false ,
844+ separate_compilation : true ,
845+ codegen_tool : Some ( "clang" . to_string ( ) ) ,
846+ output_dir : Some ( out_dir. clone ( ) ) ,
847+ ..Default :: default ( )
848+ } ;
849+
850+ let result = whatever_driver:: check ( & path, & opts) ;
851+ assert ! (
852+ result. ok,
853+ "expected fixture to pass, got:\n {}" ,
854+ result. rendered_diags
855+ ) ;
856+
857+ let entry_ll = out_dir. join ( "ok_enum_payload_across_modules.ll" ) ;
858+ let entry_o = out_dir. join ( "ok_enum_payload_across_modules.o" ) ;
859+ let eabi_ll = out_dir. join ( "eabi.ll" ) ;
860+ let eabi_o = out_dir. join ( "eabi.o" ) ;
861+
862+ assert ! (
863+ entry_ll. exists( ) ,
864+ "expected entry ll to exist: {entry_ll:?}"
865+ ) ;
866+ assert ! (
867+ entry_o. exists( ) ,
868+ "expected entry object to exist: {entry_o:?}"
869+ ) ;
870+ assert ! ( eabi_ll. exists( ) , "expected eabi ll to exist: {eabi_ll:?}" ) ;
871+ assert ! ( eabi_o. exists( ) , "expected eabi object to exist: {eabi_o:?}" ) ;
872+ }
873+
772874#[ test]
773875fn separate_compilation_links_executable_when_toolchain_is_available ( ) {
774876 // Strong regression: exercises the link stage.
0 commit comments