Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cgen: fix comptime generic arg resolution #21682

Merged
merged 2 commits into from
Jun 15, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion vlib/v/checker/fn.v
Original file line number Diff line number Diff line change
Expand Up @@ -1595,10 +1595,10 @@ fn (mut c Checker) resolve_comptime_args(func ast.Fn, node_ ast.CallExpr, concre
} else {
func.params[offset + i]
}
k++
if !param.typ.has_flag(.generic) {
continue
}
k++
param_typ := param.typ
if call_arg.expr is ast.Ident {
if call_arg.expr.obj is ast.Var {
Expand Down
2 changes: 1 addition & 1 deletion vlib/v/gen/c/fn.v
Original file line number Diff line number Diff line change
Expand Up @@ -1186,10 +1186,10 @@ fn (mut g Gen) resolve_comptime_args(func ast.Fn, mut node_ ast.CallExpr, concre
} else {
func.params[offset + i]
}
k++
if !param.typ.has_flag(.generic) {
continue
}
k++
param_typ := param.typ
if mut call_arg.expr is ast.Ident {
if mut call_arg.expr.obj is ast.Var {
Expand Down
53 changes: 53 additions & 0 deletions vlib/v/tests/generic_comptime_arg_test.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import toml

struct Parent {
name string
child1 Child1
child2 Child2
}

struct Child1 {
name string
}

struct Child2 {
age int
}

fn decode[T](toml_str string) !T {
doc := toml.parse_text(toml_str)!

return decode_struct(doc.to_any(), &T{})
}

// `T` param serves here as a workaround to allow to infer types of nested struct fields.
fn decode_struct[T](doc toml.Any, typ &T) T {
mut res := T{}
$for field in T.fields {
val := doc.value(field.name)
$if field.typ is string {
res.$(field.name) = val.string()
} $else $if field.typ is int {
res.$(field.name) = val.int()
} $else $if field.is_struct {
typ_ := typ.$(field.name)
res.$(field.name) = decode_struct(val, &typ_)
}
}
return res
}

fn main() {
toml_str := 'name = "John"
child1 = { name = "abc" }
child2 = { age = 5 }'

a := dump(decode[Parent](toml_str)!)
assert a.name == 'John'
assert a.child1 == Child1{
name: 'abc'
}
assert a.child2 == Child2{
age: 5
}
}
Loading