mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen: fix nested generic fn call with reference argument (#15353)
This commit is contained in:
parent
4588bb44ab
commit
8d9af2e4a1
@ -1208,7 +1208,8 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
|
||||
if g.comptime_for_field_type != 0 && g.inside_comptime_for_field {
|
||||
name = g.generic_fn_name([g.comptime_for_field_type], name, false)
|
||||
} else {
|
||||
name = g.generic_fn_name(node.concrete_types, name, false)
|
||||
concrete_types := node.concrete_types.map(g.unwrap_generic(it))
|
||||
name = g.generic_fn_name(concrete_types, name, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1492,7 +1493,7 @@ fn (mut g Gen) call_args(node ast.CallExpr) {
|
||||
} else {
|
||||
node.args
|
||||
}
|
||||
mut expected_types := node.expected_arg_types
|
||||
mut expected_types := node.expected_arg_types.map(g.unwrap_generic(it))
|
||||
// unwrap generics fn/method arguments to concretes
|
||||
if node.concrete_types.len > 0 && node.concrete_types.all(!it.has_flag(.generic)) {
|
||||
if node.is_method {
|
||||
@ -1924,13 +1925,13 @@ fn (mut g Gen) keep_alive_call_postgen(node ast.CallExpr, tmp_cnt_save int) {
|
||||
|
||||
[inline]
|
||||
fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type ast.Type, lang ast.Language) {
|
||||
arg_typ := g.unwrap_generic(arg.typ)
|
||||
exp_is_ptr := expected_type.is_ptr() || expected_type.idx() in ast.pointer_type_idxs
|
||||
arg_is_ptr := arg.typ.is_ptr() || arg.typ.idx() in ast.pointer_type_idxs
|
||||
arg_is_ptr := arg_typ.is_ptr() || arg_typ.idx() in ast.pointer_type_idxs
|
||||
if expected_type == 0 {
|
||||
g.checker_bug('ref_or_deref_arg expected_type is 0', arg.pos)
|
||||
}
|
||||
exp_sym := g.table.sym(expected_type)
|
||||
arg_typ := g.unwrap_generic(arg.typ)
|
||||
mut needs_closing := false
|
||||
if arg.is_mut && !exp_is_ptr {
|
||||
g.write('&/*mut*/')
|
||||
|
@ -6,7 +6,7 @@ struct ContainerType<T> {
|
||||
typ &Type<T>
|
||||
}
|
||||
|
||||
fn (instance &ContainerType<T>) contains(typ Type<T>) bool {
|
||||
fn (instance &ContainerType<T>) contains(typ &Type<T>) bool {
|
||||
println(typ)
|
||||
if instance.typ == typ {
|
||||
return true
|
||||
|
23
vlib/v/tests/inout/dump_nested_generic_fn_call_ref_arg.out
Normal file
23
vlib/v/tests/inout/dump_nested_generic_fn_call_ref_arg.out
Normal file
@ -0,0 +1,23 @@
|
||||
[vlib/v/tests/inout/dump_nested_generic_fn_call_ref_arg.vv:19] '$T.name $input': int 1
|
||||
[vlib/v/tests/inout/dump_nested_generic_fn_call_ref_arg.vv:26] '$T.name $input': int 1
|
||||
[vlib/v/tests/inout/dump_nested_generic_fn_call_ref_arg.vv:36] next(1): 0
|
||||
[vlib/v/tests/inout/dump_nested_generic_fn_call_ref_arg.vv:19] '$T.name $input': f64 1.
|
||||
[vlib/v/tests/inout/dump_nested_generic_fn_call_ref_arg.vv:26] '$T.name $input': f64 1.
|
||||
[vlib/v/tests/inout/dump_nested_generic_fn_call_ref_arg.vv:37] next(1.0): 64.
|
||||
[vlib/v/tests/inout/dump_nested_generic_fn_call_ref_arg.vv:19] '$T.name $input': f64 11.1
|
||||
[vlib/v/tests/inout/dump_nested_generic_fn_call_ref_arg.vv:26] '$T.name $input': f64 11.1
|
||||
[vlib/v/tests/inout/dump_nested_generic_fn_call_ref_arg.vv:38] next(11.1): 64.
|
||||
[vlib/v/tests/inout/dump_nested_generic_fn_call_ref_arg.vv:15] '$T.name $input': Score Score{
|
||||
ave: 23.4
|
||||
}
|
||||
[vlib/v/tests/inout/dump_nested_generic_fn_call_ref_arg.vv:26] '$T.name $input': Score Score{
|
||||
ave: 23.4
|
||||
}
|
||||
[vlib/v/tests/inout/dump_nested_generic_fn_call_ref_arg.vv:42] next(ave): 23.4
|
||||
[vlib/v/tests/inout/dump_nested_generic_fn_call_ref_arg.vv:15] '$T.name $input': &Score &Score{
|
||||
ave: 23.4
|
||||
}
|
||||
[vlib/v/tests/inout/dump_nested_generic_fn_call_ref_arg.vv:26] '$T.name $input': &Score &Score{
|
||||
ave: 23.4
|
||||
}
|
||||
[vlib/v/tests/inout/dump_nested_generic_fn_call_ref_arg.vv:43] next(&ave): 23.4
|
44
vlib/v/tests/inout/dump_nested_generic_fn_call_ref_arg.vv
Normal file
44
vlib/v/tests/inout/dump_nested_generic_fn_call_ref_arg.vv
Normal file
@ -0,0 +1,44 @@
|
||||
interface Average {
|
||||
ave() f64
|
||||
}
|
||||
|
||||
struct Score {
|
||||
ave f64
|
||||
}
|
||||
|
||||
pub fn (s &Score) ave() f64 {
|
||||
return s.ave
|
||||
}
|
||||
|
||||
fn next<T>(input T) f64 {
|
||||
$if T is Average {
|
||||
dump('${T.name} $input')
|
||||
ret := next2<T>(input)
|
||||
return ret
|
||||
} $else {
|
||||
dump('${T.name} $input')
|
||||
ret := next2<T>(input)
|
||||
return ret
|
||||
}
|
||||
}
|
||||
|
||||
fn next2<T>(input T) f64 {
|
||||
dump('${T.name} $input')
|
||||
$if T is Average {
|
||||
return input.ave()
|
||||
} $else $if T is f64 {
|
||||
return 64.0
|
||||
}
|
||||
return 0.0
|
||||
}
|
||||
|
||||
fn main() {
|
||||
dump(next(1))
|
||||
dump(next(1.0))
|
||||
dump(next(11.1))
|
||||
ave := Score {
|
||||
ave: 23.4
|
||||
}
|
||||
dump(next(ave))
|
||||
dump(next(&ave))
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user