mirror of
https://github.com/vlang/v.git
synced 2025-09-15 10:27:19 -04:00
checker: fix generic resolve comptime generic var (#22699)
This commit is contained in:
parent
0b2b06df3c
commit
6cfa84c991
@ -410,7 +410,7 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
|
||||
left.obj.ct_type_var = .field_var
|
||||
left.obj.typ = c.comptime.comptime_for_field_type
|
||||
} else if mut right is ast.CallExpr {
|
||||
if left.obj.ct_type_var == .no_comptime
|
||||
if left.obj.ct_type_var in [.generic_var, .no_comptime]
|
||||
&& c.table.cur_fn != unsafe { nil }
|
||||
&& c.table.cur_fn.generic_names.len != 0
|
||||
&& !right.comptime_ret_val
|
||||
@ -503,6 +503,10 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
|
||||
if (left.is_map || left.is_farray) && left.is_setter {
|
||||
left.recursive_mapset_is_setter(true)
|
||||
}
|
||||
|
||||
if right is ast.Ident && c.comptime.is_comptime_var(right) {
|
||||
right_type = c.comptime.get_comptime_var_type(right)
|
||||
}
|
||||
}
|
||||
if mut left is ast.InfixExpr {
|
||||
c.error('cannot use infix expression on the left side of `${node.op}`',
|
||||
|
@ -1884,6 +1884,12 @@ fn (mut c Checker) resolve_comptime_args(func &ast.Fn, node_ ast.CallExpr, concr
|
||||
comptime_args[k] = ctyp
|
||||
}
|
||||
}
|
||||
} else if call_arg.expr.obj.ct_type_var == .generic_var {
|
||||
mut ctyp := c.comptime.get_comptime_var_type(call_arg.expr)
|
||||
if ctyp.nr_muls() > 0 && param_typ.nr_muls() > 0 {
|
||||
ctyp = ctyp.set_nr_muls(0)
|
||||
}
|
||||
comptime_args[k] = ctyp
|
||||
}
|
||||
}
|
||||
} else if call_arg.expr is ast.PrefixExpr {
|
||||
|
50
vlib/v/tests/comptime/comptime_generic_container_test.v
Normal file
50
vlib/v/tests/comptime/comptime_generic_container_test.v
Normal file
@ -0,0 +1,50 @@
|
||||
module main
|
||||
|
||||
struct Decoder {
|
||||
json string
|
||||
}
|
||||
|
||||
pub fn decode[T](val string) !T {
|
||||
mut decoder := Decoder{
|
||||
json: val
|
||||
}
|
||||
|
||||
mut result := T{}
|
||||
decoder.decode_value(mut &result)!
|
||||
return result
|
||||
}
|
||||
|
||||
fn (mut decoder Decoder) decode_value[T](mut val T) ! {
|
||||
$if T is $array {
|
||||
mut array_element := create_array_element(val)
|
||||
|
||||
decoder.decode_value(mut array_element)!
|
||||
|
||||
val << array_element
|
||||
} $else $if T is $map {
|
||||
mut map_value := create_map_value(val)
|
||||
|
||||
decoder.decode_value(mut map_value)!
|
||||
|
||||
val['key'] = map_value
|
||||
}
|
||||
}
|
||||
|
||||
fn create_array_element[T](array []T) T {
|
||||
return T{}
|
||||
}
|
||||
|
||||
fn create_map_value[K, V](map_ map[K]V) V {
|
||||
return V{}
|
||||
}
|
||||
|
||||
fn test_main() {
|
||||
assert decode[[]int]('[1, 2, 3]')! == [0]
|
||||
assert decode[[]string]('["1", "2", "3"]')! == ['']
|
||||
assert decode[map[string]string]('{"val": "2"}')! == {
|
||||
'key': ''
|
||||
}
|
||||
assert decode[map[string]int]('{"a": 1}')! == {
|
||||
'key': 0
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user