mirror of
https://github.com/vlang/v.git
synced 2025-09-08 14:51:53 -04:00
cgen: fix interface generic smartcast (#20609)
This commit is contained in:
parent
672fe9b8eb
commit
2874e7cac0
@ -4649,7 +4649,7 @@ fn (mut g Gen) ident(node ast.Ident) {
|
||||
g.write('(*(')
|
||||
}
|
||||
if node.obj.smartcasts.len > 0 {
|
||||
obj_sym := g.table.sym(node.obj.typ)
|
||||
obj_sym := g.table.sym(g.unwrap_generic(node.obj.typ))
|
||||
if !prevent_sum_type_unwrapping_once {
|
||||
for _, typ in node.obj.smartcasts {
|
||||
is_option_unwrap := is_option && typ == node.obj.typ.clear_flag(.option)
|
||||
@ -4665,7 +4665,9 @@ fn (mut g Gen) ident(node ast.Ident) {
|
||||
g.write('*')
|
||||
}
|
||||
} else if (g.inside_interface_deref && g.table.is_interface_var(node.obj))
|
||||
|| node.obj.ct_type_var == .smartcast {
|
||||
|| node.obj.ct_type_var == .smartcast
|
||||
|| (obj_sym.kind == .interface_
|
||||
&& g.table.type_kind(node.obj.typ) == .any) {
|
||||
g.write('*')
|
||||
} else if is_option {
|
||||
g.write('*(${g.base_type(node.obj.typ)}*)')
|
||||
|
46
vlib/v/tests/generic_smartcast_test.v
Normal file
46
vlib/v/tests/generic_smartcast_test.v
Normal file
@ -0,0 +1,46 @@
|
||||
fn cast_interface[T, U](u U) T {
|
||||
$if U is $interface {
|
||||
if u is T {
|
||||
return u
|
||||
} else {
|
||||
panic('expected t to be ${typeof[T]().name}, got ${typeof[U]().name}')
|
||||
}
|
||||
} $else {
|
||||
$compile_error('not an interface')
|
||||
}
|
||||
}
|
||||
|
||||
interface Foo {
|
||||
f()
|
||||
}
|
||||
|
||||
struct Bar {}
|
||||
|
||||
fn (bar Bar) f() {}
|
||||
|
||||
struct Baz {}
|
||||
|
||||
fn (baz Baz) f() {}
|
||||
|
||||
fn (_ Bar) g() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
fn (_ Baz) g() int {
|
||||
return 1
|
||||
}
|
||||
|
||||
fn f(foo Foo) int {
|
||||
if foo is Bar {
|
||||
return cast_interface[Bar, Foo](foo).g()
|
||||
}
|
||||
if foo is Baz {
|
||||
return cast_interface[Baz, Foo](foo).g()
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
fn test_main() {
|
||||
assert f(Bar{}) == 0
|
||||
assert f(Baz{}) == 1
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user