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:
@@ -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_sym := g.table.sym(got_deref_type)
|
||||||
deref_will_match := expected_type in [got_type, got_deref_type, deref_sym.parent_idx]
|
deref_will_match := expected_type in [got_type, got_deref_type, deref_sym.parent_idx]
|
||||||
got_is_opt := got_type.has_flag(.optional)
|
got_is_opt := got_type.has_flag(.optional)
|
||||||
if deref_will_match || got_is_opt || expr.is_auto_deref_var()
|
if deref_will_match || got_is_opt || expr.is_auto_deref_var() {
|
||||||
|| expected_type.has_flag(.generic) {
|
|
||||||
g.write('*')
|
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
|
// TODO2
|
||||||
// g.generate_tmp_autofree_arg_vars(node, name)
|
// g.generate_tmp_autofree_arg_vars(node, name)
|
||||||
if !node.receiver_type.is_ptr() && left_type.is_ptr() && node.name == 'str' {
|
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!!')
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user