cgen: interface fix + add more interface tests (#7776)
parent
d5b510df80
commit
82162b8ff8
|
@ -4196,6 +4196,10 @@ fn (mut g Gen) return_statement(node ast.Return) {
|
|||
if !g.fn_decl.return_type.is_ptr() && node.types[0].is_ptr() {
|
||||
// Automatic Dereference for optional
|
||||
g.write('*')
|
||||
// Fixes returning a mutable receiver with interface as return type
|
||||
if node.exprs[0] is ast.Ident && !g.is_amp {
|
||||
g.write('&')
|
||||
}
|
||||
}
|
||||
for i, expr in node.exprs {
|
||||
g.expr(expr)
|
||||
|
|
|
@ -788,7 +788,9 @@ fn (mut g Gen) call_args(node ast.CallExpr) {
|
|||
exp_sym := g.table.get_type_symbol(expected_types[i])
|
||||
// exp_styp := g.typ(expected_types[arg_no]) // g.table.get_type_symbol(expected_types[arg_no])
|
||||
// styp := g.typ(arg.typ) // g.table.get_type_symbol(arg.typ)
|
||||
if exp_sym.kind == .interface_ {
|
||||
// NB: the second check avoids casting the interface into itself
|
||||
// aka avoid 'I__Speaker_to_Interface_Speaker' thing for example
|
||||
if exp_sym.kind == .interface_ && expected_types[i] != arg.typ {
|
||||
g.interface_call(arg.typ, expected_types[i])
|
||||
is_interface = true
|
||||
}
|
||||
|
|
|
@ -188,6 +188,52 @@ fn test_register() {
|
|||
interface Speaker2 {
|
||||
name() string
|
||||
speak()
|
||||
return_speaker() Speaker2
|
||||
return_speaker2() ?Speaker2
|
||||
}
|
||||
|
||||
struct Boss {
|
||||
mut:
|
||||
name string
|
||||
}
|
||||
|
||||
fn (b Boss) name() string {
|
||||
return b.name
|
||||
}
|
||||
|
||||
fn (b Boss) speak() {
|
||||
println("i'm $b.name")
|
||||
}
|
||||
|
||||
fn (b &Boss) return_speaker() Speaker2 {
|
||||
return b
|
||||
}
|
||||
|
||||
fn (mut b Boss) return_speaker2() ?Speaker2 {
|
||||
if b.name == 'richard' {
|
||||
return none
|
||||
}
|
||||
b.name = 'boss'
|
||||
return b
|
||||
}
|
||||
|
||||
fn return_speaker2(sp Speaker2) Speaker2 {
|
||||
s := sp.return_speaker()
|
||||
s2 := sp.return_speaker2() or {
|
||||
return sp
|
||||
}
|
||||
s.speak()
|
||||
s2.speak()
|
||||
return s2
|
||||
}
|
||||
|
||||
fn test_interface_returning_interface() {
|
||||
mut b := Boss{'bob'}
|
||||
assert b.name == 'bob'
|
||||
s2 := return_speaker2(b)
|
||||
if s2 is Boss {
|
||||
assert s2.name == 'boss'
|
||||
}
|
||||
}
|
||||
|
||||
struct Foo {
|
||||
|
|
Loading…
Reference in New Issue