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 { if is_generic {
exp_typ_sym = c.table.get_type_symbol(c.cur_generic_type) 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', c.error('cannot use `$got_typ_sym.name` as type `$exp_typ_sym.name` in return argument',
pos) 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 != if fn_return_is_optional && !node.types[0].flag_is(.optional) && return_sym.name !=
'Option' { 'Option' {
styp := g.base_type(g.fn_decl.return_type) 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() { if !g.fn_decl.return_type.is_ptr() && node.types[0].is_ptr() {
// Automatic Dereference for optional // Automatic Dereference for optional
g.write('*') g.write('*')
@ -2314,7 +2314,13 @@ fn (mut g Gen) return_statement(node ast.Return) {
g.writeln(' }, sizeof($styp));') g.writeln(' }, sizeof($styp));')
return 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) g.expr_with_cast(node.exprs[0], node.types[0], g.fn_decl.return_type)
if sym.kind == .interface_ {
g.write(')')
}
} }
g.writeln(';') g.writeln(';')
} }

View File

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