checker: fix generic resolve comptime generic var (#22699)

This commit is contained in:
Felipe Pena 2024-10-30 21:22:13 -03:00 committed by GitHub
parent 0b2b06df3c
commit 6cfa84c991
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 61 additions and 1 deletions

View File

@ -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}`',

View File

@ -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 {

View 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
}
}