checker: minor cleanup of return_stmt() (#10315)

pull/10354/head
yuyi 2021-06-05 19:06:48 +08:00 committed by GitHub
parent a716a00e38
commit 8af7558e0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 20 additions and 20 deletions

View File

@ -2975,7 +2975,7 @@ pub fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
}
// TODO: non deferred
pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) {
pub fn (mut c Checker) return_stmt(mut node ast.Return) {
c.expected_type = c.table.cur_fn.return_type
mut expected_type := c.unwrap_generic(c.expected_type)
if expected_type.has_flag(.generic) && c.table.get_type_symbol(expected_type).kind == .struct_ {
@ -2986,17 +2986,17 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) {
}
}
expected_type_sym := c.table.get_type_symbol(expected_type)
if return_stmt.exprs.len > 0 && c.table.cur_fn.return_type == ast.void_type {
c.error('unexpected argument, current function does not return anything', return_stmt.exprs[0].position())
if node.exprs.len > 0 && c.table.cur_fn.return_type == ast.void_type {
c.error('unexpected argument, current function does not return anything', node.exprs[0].position())
return
} else if return_stmt.exprs.len == 0 && !(c.expected_type == ast.void_type
} else if node.exprs.len == 0 && !(c.expected_type == ast.void_type
|| expected_type_sym.kind == .void) {
stype := c.table.type_to_str(expected_type)
arg := if expected_type_sym.kind == .multi_return { 'arguments' } else { 'argument' }
c.error('expected `$stype` $arg', return_stmt.pos)
c.error('expected `$stype` $arg', node.pos)
return
}
if return_stmt.exprs.len == 0 {
if node.exprs.len == 0 {
return
}
exp_is_optional := expected_type.has_flag(.optional)
@ -3008,7 +3008,7 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) {
}
}
mut got_types := []ast.Type{}
for expr in return_stmt.exprs {
for expr in node.exprs {
typ := c.expr(expr)
// Unpack multi return types
sym := c.table.get_type_symbol(typ)
@ -3020,7 +3020,7 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) {
got_types << typ
}
}
return_stmt.types = got_types
node.types = got_types
// allow `none` & `error` return types for function that returns optional
option_type_idx := c.table.type_idxs['Option']
got_types_0_idx := got_types[0].idx()
@ -3030,26 +3030,26 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) {
}
if expected_types.len > 0 && expected_types.len != got_types.len {
arg := if expected_types.len == 1 { 'argument' } else { 'arguments' }
c.error('expected $expected_types.len $arg, but got $got_types.len', return_stmt.pos)
c.error('expected $expected_types.len $arg, but got $got_types.len', node.pos)
return
}
for i, exp_type in expected_types {
got_typ := c.unwrap_generic(got_types[i])
if got_typ.has_flag(.optional) && (!exp_type.has_flag(.optional)
|| c.table.type_to_str(got_typ) != c.table.type_to_str(exp_type)) {
pos := return_stmt.exprs[i].position()
pos := node.exprs[i].position()
c.error('cannot use `${c.table.type_to_str(got_typ)}` as type `${c.table.type_to_str(exp_type)}` in return argument',
pos)
}
if !c.check_types(got_typ, exp_type) {
got_typ_sym := c.table.get_type_symbol(got_typ)
mut exp_typ_sym := c.table.get_type_symbol(exp_type)
pos := return_stmt.exprs[i].position()
if return_stmt.exprs[i].is_auto_deref_var() {
pos := node.exprs[i].position()
if node.exprs[i].is_auto_deref_var() {
continue
}
if exp_typ_sym.kind == .interface_ {
c.type_implements(got_typ, exp_type, return_stmt.pos)
c.type_implements(got_typ, exp_type, node.pos)
continue
}
c.error('cannot use `$got_typ_sym.name` as type `$exp_typ_sym.name` in return argument',
@ -3057,8 +3057,8 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) {
}
if (got_typ.is_ptr() || got_typ.is_pointer())
&& (!exp_type.is_ptr() && !exp_type.is_pointer()) {
pos := return_stmt.exprs[i].position()
if return_stmt.exprs[i].is_auto_deref_var() {
pos := node.exprs[i].position()
if node.exprs[i].is_auto_deref_var() {
continue
}
c.error('fn `$c.table.cur_fn.name` expects you to return a non reference type `${c.table.type_to_str(exp_type)}`, but you are returning `${c.table.type_to_str(got_typ)}` instead',
@ -3066,15 +3066,15 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) {
}
if (exp_type.is_ptr() || exp_type.is_pointer())
&& (!got_typ.is_ptr() && !got_typ.is_pointer()) && got_typ != ast.int_literal_type {
pos := return_stmt.exprs[i].position()
if return_stmt.exprs[i].is_auto_deref_var() {
pos := node.exprs[i].position()
if node.exprs[i].is_auto_deref_var() {
continue
}
c.error('fn `$c.table.cur_fn.name` expects you to return a reference type `${c.table.type_to_str(exp_type)}`, but you are returning `${c.table.type_to_str(got_typ)}` instead',
pos)
}
if exp_type.is_ptr() && got_typ.is_ptr() {
mut r_expr := &return_stmt.exprs[i]
mut r_expr := &node.exprs[i]
if mut r_expr is ast.Ident {
if mut r_expr.obj is ast.Var {
mut obj := unsafe { &r_expr.obj }
@ -3097,8 +3097,8 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) {
}
}
}
if exp_is_optional && return_stmt.exprs.len > 0 {
expr0 := return_stmt.exprs[0]
if exp_is_optional && node.exprs.len > 0 {
expr0 := node.exprs[0]
if expr0 is ast.CallExpr {
if expr0.or_block.kind == .propagate {
c.error('`?` is not needed, use `return ${expr0.name}()`', expr0.pos)