@@ -633,6 +633,90 @@ fn test_array_sort_with_compare_uses_stable_sort_adapters() {
633633 assert normalized.contains ('_qsort_adapter);' )
634634}
635635
636+ fn test_array_sort_expression_key_avoids_sanitized_name_collisions () {
637+ os.chdir (vroot) or {}
638+ test_dir := os.join_path (os.vtmp_dir (), 'coutput_array_sort_expr_collision_${os .getpid ()}' )
639+ os.mkdir_all (test_dir)!
640+ defer {
641+ os.rmdir_all (test_dir) or {}
642+ }
643+ os.write_file (os.join_path (test_dir, 'main.v' ),
644+ ['module main' , '' , 'struct Inner {' , '\t bar int' , '}' , '' , 'struct Item {' , '\t foo Inner' , '\t foo_bar int' , '\t label string' , '}' , '' , 'fn main() {' , '\t println(sort_by_nested())' , '\t println(sort_by_flat())' , '}' ].join ('\n ' ) +
645+ '\n ' )!
646+ os.write_file (os.join_path (test_dir, 'nested.v' ),
647+ ['module main' , '' , 'fn sort_by_nested() string {' , "\t mut items := [Item{ foo: Inner{ bar: 2 }, foo_bar: 1, label: 'nested-wrong' }, Item{ foo: Inner{ bar: 1 }, foo_bar: 2, label: 'nested-ok' }]" , '\t items.sort(a.foo.bar < b.foo.bar)' , '\t return items[0].label' , '}' ].join ('\n ' ) +
648+ '\n ' )!
649+ os.write_file (os.join_path (test_dir, 'flat.v' ),
650+ ['module main' , '' , 'fn sort_by_flat() string {' , "\t mut items := [Item{ foo: Inner{ bar: 1 }, foo_bar: 2, label: 'flat-wrong' }, Item{ foo: Inner{ bar: 2 }, foo_bar: 1, label: 'flat-ok' }]" , '\t items.sort(a.foo_bar < b.foo_bar)' , '\t return items[0].label' , '}' ].join ('\n ' ) +
651+ '\n ' )!
652+ pexe := os.join_path (test_dir, 'sort_expr_collision' )
653+ cmd := '${os .quoted_path (vexe )} -o ${os .quoted_path (pexe )} ${os .quoted_path (test_dir )}'
654+ compilation := os.execute (cmd)
655+ ensure_compilation_succeeded (compilation, cmd)
656+ res := os.execute (os.quoted_path (pexe))
657+ assert res.exit_code == 0
658+ assert res.output.trim_space ().replace ('\r\n ' , '\n ' ) == 'nested-ok\n flat-ok'
659+ }
660+
661+ // generated_c_symbol_with_prefix extracts one generated C symbol from compiler output.
662+ fn generated_c_symbol_with_prefix (output string , prefix string ) string {
663+ idx := output.index (prefix) or { return '' }
664+ rest := output[idx..]
665+ mut end := 0
666+ for end < rest.len && (rest[end].is_letter () || rest[end].is_digit () || rest[end] == `_` ) {
667+ end++
668+ }
669+ return rest[..end]
670+ }
671+
672+ fn test_auxiliary_c_symbols_use_stable_type_hashes () {
673+ os.chdir (vroot) or {}
674+ test_dir := os.join_path (os.vtmp_dir (), 'coutput_stable_type_symbol_hash_${os .getpid ()}' )
675+ dir_a := os.join_path (test_dir, 'a' )
676+ dir_b := os.join_path (test_dir, 'b' )
677+ os.mkdir_all (dir_a)!
678+ os.mkdir_all (dir_b)!
679+ defer {
680+ os.rmdir_all (test_dir) or {}
681+ }
682+ source_lines := [
683+ 'module main' ,
684+ '' ,
685+ 'struct Item {' ,
686+ '\t name string' ,
687+ '\t rank int' ,
688+ '}' ,
689+ '' ,
690+ 'fn main() {' ,
691+ "\t mut items := [Item{'b', 2}, Item{'a', 1}, Item{'c', 3}]" ,
692+ '\t items.sort(a.rank < b.rank)' ,
693+ '\t mut nested := [items]' ,
694+ '\t println("\$ {nested[0][0].name}")' ,
695+ '}' ,
696+ ]
697+ source := source_lines.join ('\n ' ) + '\n '
698+ path_a := os.join_path (dir_a, 'main.v' )
699+ path_b := os.join_path (dir_b, 'main.v' )
700+ os.write_file (path_a, source)!
701+ os.write_file (path_b, source)!
702+ cmd_a := '${os .quoted_path (vexe )} -prod -gc boehm_full_opt -o - ${os .quoted_path (path_a )}'
703+ cmd_b := '${os .quoted_path (vexe )} -prod -gc boehm_full_opt -o - ${os .quoted_path (path_b )}'
704+ compilation_a := os.execute (cmd_a)
705+ compilation_b := os.execute (cmd_b)
706+ ensure_compilation_succeeded (compilation_a, cmd_a)
707+ ensure_compilation_succeeded (compilation_b, cmd_b)
708+ compare_a := generated_c_symbol_with_prefix (compilation_a.output, 'compare_' )
709+ compare_b := generated_c_symbol_with_prefix (compilation_b.output, 'compare_' )
710+ keepalive_a := generated_c_symbol_with_prefix (compilation_a.output,
711+ '__v_boehm_collect_keepalive_' )
712+ keepalive_b := generated_c_symbol_with_prefix (compilation_b.output,
713+ '__v_boehm_collect_keepalive_' )
714+ assert compare_a != ''
715+ assert keepalive_a != ''
716+ assert compare_a == compare_b
717+ assert keepalive_a == keepalive_b
718+ }
719+
636720fn test_veb_implicit_ctx_alias_uses_user_context_name () {
637721 os.chdir (vroot) or {}
638722 test_source := os.join_path (os.vtmp_dir (), 'coutput_veb_implicit_ctx_alias.vv' )
0 commit comments