@@ -2806,9 +2806,7 @@ fn (mut t Transformer) array_map_expr_result_retains_element_address(id flat.Nod
28062806 && t.array_map_expr_result_retains_element_address (t.a.child (& node, 0 ), name)
28072807 }
28082808 .block, .match_branch {
2809- return node.children_count > 0
2810- && t.array_map_expr_result_retains_element_address (t.a.child (& node,
2811- node.children_count - 1 ), name)
2809+ return t.array_map_block_result_retains_element_address (node, name)
28122810 }
28132811 .if_expr, .match_stmt {
28142812 for i in 1 .. node.children_count {
@@ -2867,6 +2865,55 @@ fn (mut t Transformer) array_map_expr_result_retains_element_address(id flat.Nod
28672865 }
28682866}
28692867
2868+ fn (mut t Transformer) array_map_block_result_retains_element_address (node flat.Node, name string ) bool {
2869+ if node.children_count == 0 {
2870+ return false
2871+ }
2872+ mut seen := map [string ]bool {}
2873+ return t.array_map_block_value_retains_element_address (node, int (node.children_count) - 1 ,
2874+ t.a.child (& node, node.children_count - 1 ), name, mut seen)
2875+ }
2876+
2877+ fn (mut t Transformer) array_map_block_value_retains_element_address (node flat.Node, before_idx int , id flat.NodeId, name string , mut seen map [string ]bool ) bool {
2878+ mut result_id := id
2879+ mut result := t.a.nodes[int (result_id)]
2880+ for result.kind in [.paren, .cast_expr, .as_expr, .dump_expr, .expr_stmt, .field_init] {
2881+ if result.children_count == 0 {
2882+ break
2883+ }
2884+ result_id = t.a.child (& result, 0 )
2885+ result = t.a.nodes[int (result_id)]
2886+ }
2887+ if result.kind != .ident || result.value.len == 0 {
2888+ return t.array_map_expr_result_retains_element_address (result_id, name)
2889+ }
2890+ if result.value in seen {
2891+ return false
2892+ }
2893+ seen[result.value] = true
2894+ for offset in 1 .. before_idx + 1 {
2895+ stmt_idx := before_idx - offset
2896+ stmt := t.a.child_node (& node, stmt_idx)
2897+ if stmt.kind == .decl_assign && stmt.children_count == 2 {
2898+ lhs := t.a.child_node (stmt, 0 )
2899+ if lhs.kind == .ident && lhs.value == result.value {
2900+ return t.array_map_block_value_retains_element_address (node, stmt_idx,
2901+ t.a.child (stmt, 1 ), name, mut seen)
2902+ }
2903+ }
2904+ if stmt.kind == .assign {
2905+ for i := 0 ; i + 1 < int (stmt.children_count); i + = 2 {
2906+ lhs := t.a.child_node (stmt, i)
2907+ if lhs.kind == .ident && lhs.value == result.value {
2908+ return t.array_map_block_value_retains_element_address (node, stmt_idx,
2909+ t.a.child (stmt, i + 1 ), name, mut seen)
2910+ }
2911+ }
2912+ }
2913+ }
2914+ return false
2915+ }
2916+
28702917fn (mut t Transformer) array_map_index_result_retains_element_address (node flat.Node, name string ) bool {
28712918 if node.children_count == 0 {
28722919 return false
@@ -3716,7 +3763,7 @@ fn (mut t Transformer) array_sort_less_expr(base flat.NodeId, elem_type string,
37163763 if int (cmp_id) > = 0 {
37173764 cmp_node := t.a.nodes[int (cmp_id)]
37183765 if cmp_node.kind == .lambda_expr && cmp_node.children_count > = 3 {
3719- if cmp := t.array_sort_lambda_expr (cmp_node, cur, prev, elem_type) {
3766+ if cmp := t.array_sort_lambda_expr (cmp_node, cur, prev, elem_type, elem_type ) {
37203767 return cmp
37213768 }
37223769 }
@@ -3801,13 +3848,15 @@ fn (mut t Transformer) array_sort_compare_less_expr(base flat.NodeId, elem_type
38013848 cur := t.make_index (base, t.make_ident (idx_name), elem_type)
38023849 prev := t.make_index (base, t.make_infix (.minus, t.make_ident (idx_name), t.make_int_literal (1 )),
38033850 elem_type)
3804- cmp_elem_type := t.array_sort_compare_arg_type (cmp, elem_type)
3805- cur_arg := if cmp_elem_type == elem_type { cur } else { t.make_prefix (.amp, cur) }
3806- prev_arg := if cmp_elem_type == elem_type { prev } else { t.make_prefix (.amp, prev) }
3851+ cmp_cur_type , cmp_prev_type := t.array_sort_compare_arg_types (cmp, elem_type)
3852+ cur_arg := if cmp_cur_type == elem_type { cur } else { t.make_prefix (.amp, cur) }
3853+ prev_arg := if cmp_prev_type == elem_type { prev } else { t.make_prefix (.amp, prev) }
38073854 if int (cmp) > = 0 {
38083855 cmp_node := t.a.nodes[int (cmp)]
38093856 if cmp_node.kind == .lambda_expr && cmp_node.children_count > = 3 {
3810- if call_value := t.array_sort_lambda_expr (cmp_node, cur_arg, prev_arg, cmp_elem_type) {
3857+ if call_value := t.array_sort_lambda_expr (cmp_node, cur_arg, prev_arg, cmp_cur_type,
3858+ cmp_prev_type)
3859+ {
38113860 return t.make_infix (.lt, call_value, t.make_int_literal (0 ))
38123861 }
38133862 }
@@ -3816,10 +3865,10 @@ fn (mut t Transformer) array_sort_compare_less_expr(base flat.NodeId, elem_type
38163865 return t.make_infix (.lt, call, t.make_int_literal (0 ))
38173866}
38183867
3819- fn (t &Transformer) array_sort_compare_arg_type (cmp flat.NodeId, elem_type string ) string {
3868+ fn (t &Transformer) array_sort_compare_arg_types (cmp flat.NodeId, elem_type string ) ( string , string ) {
38203869 default_type := '&${elem_type }'
38213870 if ! elem_type.starts_with ('&' ) || isnil (t.tc) || int (cmp) < 0 {
3822- return default_type
3871+ return default_type, default_type
38233872 }
38243873 cmp_node := t.a.nodes[int (cmp)]
38253874 raw_type := if cmp_node.kind == .ident {
@@ -3828,17 +3877,18 @@ fn (t &Transformer) array_sort_compare_arg_type(cmp flat.NodeId, elem_type strin
38283877 t.raw_checker_node_type (cmp)
38293878 }
38303879 if raw_type.len == 0 {
3831- return default_type
3880+ return default_type, default_type
38323881 }
38333882 cmp_type := types.unalias_type (t.tc.parse_type (raw_type))
3834- if cmp_type is types.FnType && cmp_type.params.len > = 2
3835- && cmp_type.params[0 ].name () == elem_type && cmp_type.params[1 ].name () == elem_type {
3836- return elem_type
3883+ if cmp_type is types.FnType && cmp_type.params.len > = 2 {
3884+ first_type := if cmp_type.params[0 ].name () == elem_type { elem_type } else { default_type }
3885+ second_type := if cmp_type.params[1 ].name () == elem_type { elem_type } else { default_type }
3886+ return first_type, second_type
38373887 }
3838- return default_type
3888+ return default_type, default_type
38393889}
38403890
3841- fn (mut t Transformer) array_sort_lambda_expr (node flat.Node, a_expr flat.NodeId, b_expr flat.NodeId, elem_type string ) ? flat.NodeId {
3891+ fn (mut t Transformer) array_sort_lambda_expr (node flat.Node, a_expr flat.NodeId, b_expr flat.NodeId, a_type string , b_type string ) ? flat.NodeId {
38423892 if node.kind != .lambda_expr || node.children_count < 3 {
38433893 return none
38443894 }
@@ -3851,8 +3901,8 @@ fn (mut t Transformer) array_sort_lambda_expr(node flat.Node, a_expr flat.NodeId
38513901 body_id := t.a.child (& node, node.children_count - 1 )
38523902 old_a := t.var_type (first.value)
38533903 old_b := t.var_type (second.value)
3854- t.set_var_type (first.value, elem_type )
3855- t.set_var_type (second.value, elem_type )
3904+ t.set_var_type (first.value, a_type )
3905+ t.set_var_type (second.value, b_type )
38563906 raw_cmp := t.substitute_array_sort_vars_named (body_id, first.value, second.value, a_expr,
38573907 b_expr)
38583908 cmp := t.transform_expr (raw_cmp)
0 commit comments