mirror of
https://github.com/vlang/v.git
synced 2025-09-16 02:49:31 -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.ct_type_var = .field_var
|
||||||
left.obj.typ = c.comptime.comptime_for_field_type
|
left.obj.typ = c.comptime.comptime_for_field_type
|
||||||
} else if mut right is ast.CallExpr {
|
} 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 != unsafe { nil }
|
||||||
&& c.table.cur_fn.generic_names.len != 0
|
&& c.table.cur_fn.generic_names.len != 0
|
||||||
&& !right.comptime_ret_val
|
&& !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 {
|
if (left.is_map || left.is_farray) && left.is_setter {
|
||||||
left.recursive_mapset_is_setter(true)
|
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 {
|
if mut left is ast.InfixExpr {
|
||||||
c.error('cannot use infix expression on the left side of `${node.op}`',
|
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
|
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 {
|
} 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