mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen: fix generic with multi-nested generic method call ref argument (#15421)
This commit is contained in:
parent
672066b65b
commit
9734148f12
@ -2247,8 +2247,7 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ
|
||||
deref_sym := g.table.sym(got_deref_type)
|
||||
deref_will_match := expected_type in [got_type, got_deref_type, deref_sym.parent_idx]
|
||||
got_is_opt := got_type.has_flag(.optional)
|
||||
if deref_will_match || got_is_opt || expr.is_auto_deref_var()
|
||||
|| expected_type.has_flag(.generic) {
|
||||
if deref_will_match || got_is_opt || expr.is_auto_deref_var() {
|
||||
g.write('*')
|
||||
}
|
||||
}
|
||||
|
@ -980,7 +980,8 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
|
||||
}
|
||||
}
|
||||
}
|
||||
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)
|
||||
// TODO2
|
||||
// g.generate_tmp_autofree_arg_vars(node, name)
|
||||
if !node.receiver_type.is_ptr() && left_type.is_ptr() && node.name == 'str' {
|
||||
|
@ -0,0 +1,109 @@
|
||||
struct Wrapper<S> {
|
||||
mut:
|
||||
calc Calc<S>
|
||||
}
|
||||
|
||||
fn (mut w Wrapper<S>) next<T>(input T) f64 {
|
||||
$if S is TypeA || S is TypeB {
|
||||
$if T is f64 {
|
||||
return w.calc.next(input)
|
||||
} $else $if T is SecretCase {
|
||||
return w.calc.next(input)
|
||||
} $else {
|
||||
panic('"$T.name" is not supported')
|
||||
return -1
|
||||
}
|
||||
return -1
|
||||
} $else {
|
||||
panic('"$S.name" is not supported')
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
struct Calc<S> {
|
||||
mut:
|
||||
typ S
|
||||
inner InnerCalc
|
||||
}
|
||||
|
||||
struct InnerCalc {}
|
||||
|
||||
fn (mut c InnerCalc) next<T>(input T) f64 {
|
||||
$if T is f64 {
|
||||
return 64.2
|
||||
} $else {
|
||||
return 100.0
|
||||
}
|
||||
}
|
||||
|
||||
struct TypeA {}
|
||||
|
||||
struct TypeB {}
|
||||
|
||||
interface SecretCase {
|
||||
secret() f64
|
||||
}
|
||||
|
||||
interface SpecialCase {
|
||||
SecretCase
|
||||
}
|
||||
|
||||
struct SecretSkill {}
|
||||
|
||||
fn (s &SecretSkill) secret() f64 {
|
||||
return 101.0
|
||||
}
|
||||
|
||||
fn (mut c Calc<S>) next<T>(input T) f64 {
|
||||
$if S is TypeA || S is TypeB {
|
||||
$if T is f64 {
|
||||
return c.typ.next(input)
|
||||
} $else $if T is SpecialCase {
|
||||
return c.typ.next(input)
|
||||
} $else {
|
||||
panic('Unsupported type $T.name')
|
||||
}
|
||||
} $else {
|
||||
panic('Unsupported type $S.name')
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut t TypeA) next<T>(input T) f64 {
|
||||
return 10
|
||||
}
|
||||
|
||||
fn (mut t TypeB) next<T>(input T) f64 {
|
||||
return 11
|
||||
}
|
||||
|
||||
fn new<S>() Wrapper<S> {
|
||||
$if S is TypeA {
|
||||
return Wrapper<TypeA>{
|
||||
calc: Calc<TypeA>{
|
||||
typ: TypeA{}
|
||||
}
|
||||
}
|
||||
} $else $if S is TypeB {
|
||||
return Wrapper<TypeB>{
|
||||
calc: Calc<TypeB>{
|
||||
typ: TypeB{}
|
||||
}
|
||||
}
|
||||
} $else {
|
||||
panic('unknown type $S.name')
|
||||
}
|
||||
}
|
||||
|
||||
fn test_generics_with_multi_nested_generic_method_call_ref_arg() {
|
||||
{
|
||||
mut c := new<TypeA>()
|
||||
s := SecretSkill{}
|
||||
assert c.next(&s) == 10.0
|
||||
}
|
||||
{
|
||||
mut c := new<TypeB>()
|
||||
s := SecretSkill{}
|
||||
assert c.next(&s) == 11.0
|
||||
}
|
||||
println('OK!!')
|
||||
}
|
Loading…
Reference in New Issue
Block a user