cgen: fix interface generic smartcast (#20609)

This commit is contained in:
Felipe Pena 2024-01-23 12:29:32 -03:00 committed by GitHub
parent 672fe9b8eb
commit 2874e7cac0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 50 additions and 2 deletions

View File

@ -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)}*)')

View 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
}