Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions vlib/v/gen/c/cgen.v
Original file line number Diff line number Diff line change
Expand Up @@ -8393,8 +8393,9 @@ fn (mut g Gen) lock_expr_mtx(expr ast.Expr) {
}

fn (mut g Gen) map_init(node ast.MapInit) {
unwrap_key_typ := g.unwrap_generic(node.key_type)
unwrap_val_typ := g.unwrap_generic(node.value_type).clear_flag(.result)
unwrap_key_typ, unwrap_val_typ_ := g.resolved_map_key_value_types(node.typ, node.key_type,
node.value_type)
unwrap_val_typ := unwrap_val_typ_.clear_flag(.result)
key_typ_str := g.styp(unwrap_key_typ)
value_typ_str := g.styp(unwrap_val_typ)
value_sym := g.table.sym(unwrap_val_typ)
Expand All @@ -8416,8 +8417,8 @@ fn (mut g Gen) map_init(node ast.MapInit) {
styp = g.styp(node.typ)
g.write('(${styp}*)builtin__memdup(ADDR(${styp}, ')
}
noscan_key := g.check_noscan(node.key_type)
noscan_value := g.check_noscan(node.value_type)
noscan_key := g.check_noscan(unwrap_key_typ)
noscan_value := g.check_noscan(unwrap_val_typ)
mut noscan := if noscan_key.len != 0 || noscan_value.len != 0 { '_noscan' } else { '' }
if noscan.len != 0 {
if noscan_key.len != 0 {
Expand Down
21 changes: 20 additions & 1 deletion vlib/v/gen/c/if.v
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,25 @@ module c

import v.ast

fn (mut g Gen) resolved_if_guard_expr_type(expr ast.Expr, default_type ast.Type) ast.Type {
if expr is ast.IndexExpr {
left_type := g.resolved_map_type_from_expr(expr.left, expr.left_type)
left_sym := g.table.final_sym(g.unwrap_generic(left_type))
if left_sym.kind == .map {
map_info := left_sym.map_info()
_, mut value_type := g.resolved_map_key_value_types(left_type, map_info.key_type,
map_info.value_type)
if default_type.has_flag(.option) && !value_type.has_flag(.option) {
value_type = value_type.set_flag(.option)
} else if default_type.has_flag(.result) && !value_type.has_flag(.result) {
value_type = value_type.set_flag(.result)
}
return value_type
}
}
return g.unwrap_generic(g.recheck_concrete_type(default_type))
}

fn (mut g Gen) if_guard_var_needs_gc_pin(scope &ast.Scope, name string) bool {
if g.pref.gc_mode !in [.boehm_full, .boehm_incr, .boehm_full_opt, .boehm_incr_opt] {
return false
Expand Down Expand Up @@ -509,7 +528,7 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
}
}
} else {
resolved := g.unwrap_generic(g.recheck_concrete_type(guard_expr_type))
resolved := g.resolved_if_guard_expr_type(branch.cond.expr, guard_expr_type)
if resolved != ast.void_type {
guard_expr_type = resolved
}
Expand Down
21 changes: 5 additions & 16 deletions vlib/v/gen/c/index.v
Original file line number Diff line number Diff line change
Expand Up @@ -689,14 +689,7 @@ fn (mut g Gen) index_of_fixed_array(node ast.IndexExpr, sym ast.TypeSymbol) {

fn (mut g Gen) index_of_map(node ast.IndexExpr, sym ast.TypeSymbol) {
gen_or := node.or_expr.kind != .absent || node.is_option
mut map_left_type := g.recheck_concrete_type(node.left_type)
resolved_left_type := g.recheck_concrete_type(g.resolved_expr_type(node.left, node.left_type))
if resolved_left_type != 0
&& (g.cur_concrete_types.len > 0 || map_left_type == 0 || map_left_type.has_flag(.generic)
|| g.type_has_unresolved_generic_parts(map_left_type)
|| g.unwrap_generic(resolved_left_type) != g.unwrap_generic(map_left_type)) {
map_left_type = resolved_left_type
}
map_left_type := g.resolved_map_type_from_expr(node.left, node.left_type)
mut left_is_ptr := map_left_type.is_ptr()
if !left_is_ptr && g.is_assign_lhs && node.left is ast.Ident
&& g.resolved_ident_is_auto_heap(node.left) {
Expand All @@ -712,14 +705,10 @@ fn (mut g Gen) index_of_map(node ast.IndexExpr, sym ast.TypeSymbol) {
} else {
sym.info as ast.Map
}
mut key_type := g.unwrap_generic(g.recheck_concrete_type(info.key_type))
mut val_type := g.unwrap_generic(g.recheck_concrete_type(info.value_type))
if key_type == 0 {
key_type = info.key_type
}
if val_type == 0 {
val_type = info.value_type
}
key_type_, val_type_ := g.resolved_map_key_value_types(map_left_type, info.key_type,
info.value_type)
mut key_type := key_type_
mut val_type := val_type_
if node.left is ast.Ident {
ident_key_type := g.resolved_ident_map_key_type(node.left)
if ident_key_type != 0 {
Expand Down
13 changes: 12 additions & 1 deletion vlib/v/gen/c/struct.v
Original file line number Diff line number Diff line change
Expand Up @@ -1087,7 +1087,18 @@ fn (mut g Gen) struct_init_field_value(sfield ast.StructInitField) {
expected_unwrap_typ := g.unwrap_generic(sfield.expected_type)
expected_unwrap_sym := g.table.final_sym(expected_unwrap_typ)
is_auto_deref_var := sfield.expr.is_auto_deref_var()
if expected_unwrap_sym.info is ast.ArrayFixed && sfield.expr is ast.ArrayInit
if expected_unwrap_sym.kind == .map && sfield.expr is ast.MapInit
&& !sfield.expected_type.has_option_or_result()
&& !sfield.expected_type.has_flag(.shared_f)
&& !sfield.expected_type.has_flag(.atomic_f) {
expected_map_info := expected_unwrap_sym.map_info()
g.map_init(ast.MapInit{
...sfield.expr
typ: expected_unwrap_typ
key_type: expected_map_info.key_type
value_type: expected_map_info.value_type
})
} else if expected_unwrap_sym.info is ast.ArrayFixed && sfield.expr is ast.ArrayInit
&& !sfield.expr.is_fixed && !sfield.expr.has_len && !sfield.expr.has_init
&& sfield.expr.exprs.len > 0 && !sfield.expected_type.has_flag(.option) {
fixed_array_expr := ast.ArrayInit{
Expand Down
46 changes: 46 additions & 0 deletions vlib/v/gen/c/utils.v
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,52 @@ fn (mut g Gen) resolved_ident_map_value_type(expr ast.Ident) ast.Type {
return 0
}

fn (mut g Gen) resolved_map_key_value_types(map_type ast.Type, fallback_key_type ast.Type, fallback_value_type ast.Type) (ast.Type, ast.Type) {
mut key_type := g.unwrap_generic(g.recheck_concrete_type(fallback_key_type))
mut value_type := g.unwrap_generic(g.recheck_concrete_type(fallback_value_type))
resolved_map_type := g.unwrap_generic(g.recheck_concrete_type(map_type))
map_sym := g.table.final_sym(resolved_map_type)
if map_sym.kind == .map {
map_info := map_sym.map_info()
resolved_key := g.unwrap_generic(g.recheck_concrete_type(map_info.key_type))
resolved_value := g.unwrap_generic(g.recheck_concrete_type(map_info.value_type))
if resolved_key != 0 {
key_type = resolved_key
}
if resolved_value != 0 {
value_type = resolved_value
}
if key_type == ast.usize_type || value_type == ast.usize_type {
name_key_type, name_value_type := g.resolved_map_types_from_name(map_sym.name)
if key_type == ast.usize_type && name_key_type != 0 {
key_type = name_key_type
}
if value_type == ast.usize_type && name_value_type != 0 {
value_type = name_value_type
}
}
}
if key_type == 0 {
key_type = fallback_key_type
}
if value_type == 0 {
value_type = fallback_value_type
}
return key_type, value_type
}

fn (mut g Gen) resolved_map_type_from_expr(expr ast.Expr, default_type ast.Type) ast.Type {
mut map_type := g.recheck_concrete_type(default_type)
resolved_type := g.recheck_concrete_type(g.resolved_expr_type(expr, default_type))
if resolved_type != 0
&& (g.cur_concrete_types.len > 0 || map_type == 0 || map_type.has_flag(.generic)
|| g.type_has_unresolved_generic_parts(map_type)
|| g.unwrap_generic(resolved_type) != g.unwrap_generic(map_type)) {
map_type = resolved_type
}
return map_type
}

fn (mut g Gen) resolved_array_elem_type_from_name(name string) ast.Type {
if !name.starts_with('[]') {
return 0
Expand Down
5 changes: 3 additions & 2 deletions vlib/v/generics/new_generics_regression_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,9 @@ fn run_new_generic_solver_tests(root_label string, test_cmd string, expected_sum
println('')
}

const expected_summsvc_generics = 'Summary for all V _test.v files: 114 failed, 180 passed, 294 total.'
const expected_summsvc_generics = 'Summary for all V _test.v files: 115 failed, 180 passed, 295 total.'
// The exact failure count varies slightly across compilers.
const expected_summary_generics = 'Summary for all V _test.v files: 110 failed, 183 passed, 293 total.'
const expected_summary_generics = 'Summary for all V _test.v files: 111 failed, 184 passed, 295 total.'
const expected_summsvc_vec = 'Summary for all V _test.v files: 3 failed, 3 total.'
const expected_summary_vec = 'Summary for all V _test.v files: 3 failed, 3 total.'
const expected_summsvc_flag = 'Summary for all V _test.v files: 21 passed, 21 total.'
Expand Down Expand Up @@ -155,6 +155,7 @@ const failing_tests = [
'vlib/v/tests/generics/generic_lambda_expr_test.v',
'vlib/v/tests/generics/generic_linked_list_ref_push_test.v',
'vlib/v/tests/generics/generic_map_alias_test.v',
'vlib/v/tests/generics/generic_map_value_in_generic_struct_method_test.v',
'vlib/v/tests/generics/generic_match_expr_test.v',
'vlib/v/tests/generics/generic_match_generic_interface_type_test.v',
'vlib/v/tests/generics/generic_method_fn_field_result_recheck_test.v',
Expand Down
Loading
Loading