checker/cgen: return interfaces

pull/5142/head
Alexander Medvednikov 2020-05-30 19:54:16 +02:00
parent b74e1bb05d
commit 1ca7a607d3
3 changed files with 16 additions and 1 deletions

View File

@ -1232,6 +1232,10 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) {
if is_generic {
exp_typ_sym = c.table.get_type_symbol(c.cur_generic_type)
}
if exp_typ_sym.kind == .interface_ {
c.type_implements(got_typ, exp_type, return_stmt.pos)
continue
}
c.error('cannot use `$got_typ_sym.name` as type `$exp_typ_sym.name` in return argument',
pos)
}

View File

@ -2300,7 +2300,7 @@ fn (mut g Gen) return_statement(node ast.Return) {
if fn_return_is_optional && !node.types[0].flag_is(.optional) && return_sym.name !=
'Option' {
styp := g.base_type(g.fn_decl.return_type)
g.write('/*:)$return_sym.name*/opt_ok(&($styp[]) { ')
g.write('/*$return_sym.name*/opt_ok(&($styp[]) { ')
if !g.fn_decl.return_type.is_ptr() && node.types[0].is_ptr() {
// Automatic Dereference for optional
g.write('*')
@ -2314,7 +2314,13 @@ fn (mut g Gen) return_statement(node ast.Return) {
g.writeln(' }, sizeof($styp));')
return
}
if sym.kind == .interface_ {
g.interface_call(node.types[0], g.fn_decl.return_type)
}
g.expr_with_cast(node.exprs[0], node.types[0], g.fn_decl.return_type)
if sym.kind == .interface_ {
g.write(')')
}
}
g.writeln(';')
}

View File

@ -238,3 +238,8 @@ fn foo2(a Animal) int {
return 0
}
}
fn new_animal() Animal {
dog := Dog{}
return dog
}