mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker, cgen: fix infering type for comptimeselector when using ptr type (#18005)
This commit is contained in:
parent
3d50663bcf
commit
6f85384f7f
@ -905,7 +905,8 @@ fn (mut c Checker) infer_fn_generic_types(func ast.Fn, mut node ast.CallExpr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if arg.expr.is_auto_deref_var() {
|
if arg.expr.is_auto_deref_var() || (arg.expr is ast.ComptimeSelector
|
||||||
|
&& (arg.expr as ast.ComptimeSelector).left.is_auto_deref_var()) {
|
||||||
typ = typ.deref()
|
typ = typ.deref()
|
||||||
}
|
}
|
||||||
// resolve &T &&T ...
|
// resolve &T &&T ...
|
||||||
|
@ -1027,6 +1027,7 @@ fn (mut g Gen) change_comptime_args(func ast.Fn, mut node_ ast.CallExpr, concret
|
|||||||
if !param.typ.has_flag(.generic) {
|
if !param.typ.has_flag(.generic) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
param_typ := param.typ
|
||||||
if mut call_arg.expr is ast.Ident {
|
if mut call_arg.expr is ast.Ident {
|
||||||
if mut call_arg.expr.obj is ast.Var {
|
if mut call_arg.expr.obj is ast.Var {
|
||||||
node_.args[i].typ = call_arg.expr.obj.typ
|
node_.args[i].typ = call_arg.expr.obj.typ
|
||||||
@ -1034,7 +1035,6 @@ fn (mut g Gen) change_comptime_args(func ast.Fn, mut node_ ast.CallExpr, concret
|
|||||||
mut ctyp := g.get_comptime_var_type(call_arg.expr)
|
mut ctyp := g.get_comptime_var_type(call_arg.expr)
|
||||||
if ctyp != ast.void_type {
|
if ctyp != ast.void_type {
|
||||||
arg_sym := g.table.sym(ctyp)
|
arg_sym := g.table.sym(ctyp)
|
||||||
param_typ := param.typ
|
|
||||||
if arg_sym.kind == .array && param_typ.has_flag(.generic)
|
if arg_sym.kind == .array && param_typ.has_flag(.generic)
|
||||||
&& g.table.final_sym(param_typ).kind == .array {
|
&& g.table.final_sym(param_typ).kind == .array {
|
||||||
ctyp = (arg_sym.info as ast.Array).elem_type
|
ctyp = (arg_sym.info as ast.Array).elem_type
|
||||||
@ -1044,10 +1044,8 @@ fn (mut g Gen) change_comptime_args(func ast.Fn, mut node_ ast.CallExpr, concret
|
|||||||
} else if call_arg.expr.obj.ct_type_var == .generic_param {
|
} else if call_arg.expr.obj.ct_type_var == .generic_param {
|
||||||
mut ctyp := g.get_comptime_var_type(call_arg.expr)
|
mut ctyp := g.get_comptime_var_type(call_arg.expr)
|
||||||
if ctyp != ast.void_type {
|
if ctyp != ast.void_type {
|
||||||
param_typ := param.typ
|
|
||||||
arg_sym := g.table.final_sym(call_arg.typ)
|
arg_sym := g.table.final_sym(call_arg.typ)
|
||||||
param_typ_sym := g.table.sym(param_typ)
|
param_typ_sym := g.table.sym(param_typ)
|
||||||
|
|
||||||
if param_typ.has_flag(.variadic) {
|
if param_typ.has_flag(.variadic) {
|
||||||
ctyp = ast.mktyp(ctyp)
|
ctyp = ast.mktyp(ctyp)
|
||||||
comptime_args[i] = ctyp
|
comptime_args[i] = ctyp
|
||||||
@ -1098,6 +1096,12 @@ fn (mut g Gen) change_comptime_args(func ast.Fn, mut node_ ast.CallExpr, concret
|
|||||||
}
|
}
|
||||||
} else if mut call_arg.expr is ast.ComptimeSelector {
|
} else if mut call_arg.expr is ast.ComptimeSelector {
|
||||||
comptime_args[i] = g.comptime_for_field_type
|
comptime_args[i] = g.comptime_for_field_type
|
||||||
|
if call_arg.expr.left.is_auto_deref_var() {
|
||||||
|
comptime_args[i] = comptime_args[i].deref()
|
||||||
|
}
|
||||||
|
if param_typ.nr_muls() > 0 && comptime_args[i].nr_muls() > 0 {
|
||||||
|
comptime_args[i] = comptime_args[i].set_nr_muls(0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
46
vlib/v/tests/comptime_selector_ptr_test.v
Normal file
46
vlib/v/tests/comptime_selector_ptr_test.v
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
struct Encoder {}
|
||||||
|
|
||||||
|
struct Writer {}
|
||||||
|
|
||||||
|
struct APrice {}
|
||||||
|
|
||||||
|
struct Association {
|
||||||
|
association &Association = unsafe { nil }
|
||||||
|
price APrice
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_value_from_ref[T](val &T) T {
|
||||||
|
return *val
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (e &Encoder) encode_struct[U](val U, mut wr Writer) ! {
|
||||||
|
$for field in U.fields {
|
||||||
|
$if field.typ is &Association {
|
||||||
|
assert get_value_from_ref(val.$(field.name)) == Association{
|
||||||
|
association: unsafe { nil }
|
||||||
|
price: APrice{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_main() {
|
||||||
|
e := Encoder{}
|
||||||
|
mut sb := Writer{}
|
||||||
|
|
||||||
|
value := Association{
|
||||||
|
association: &Association{
|
||||||
|
price: APrice{}
|
||||||
|
}
|
||||||
|
price: APrice{}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert get_value_from_ref(&Association{
|
||||||
|
price: APrice{}
|
||||||
|
}) == Association{
|
||||||
|
association: unsafe { nil }
|
||||||
|
price: APrice{}
|
||||||
|
}
|
||||||
|
|
||||||
|
e.encode_struct(value, mut sb)!
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user