mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: minor cleanup in return_stmt() (#17995)
This commit is contained in:
parent
adcd16b198
commit
eb410bf283
@ -131,14 +131,15 @@ fn (mut c Checker) return_stmt(mut node ast.Return) {
|
|||||||
if expected_types.len > 0 && expected_types.len != got_types.len {
|
if expected_types.len > 0 && expected_types.len != got_types.len {
|
||||||
// `fn foo() !(int, string) { return Err{} }`
|
// `fn foo() !(int, string) { return Err{} }`
|
||||||
if (exp_is_option || exp_is_result) && node.exprs.len == 1 {
|
if (exp_is_option || exp_is_result) && node.exprs.len == 1 {
|
||||||
got_typ := c.expr(node.exprs[0])
|
got_type := c.expr(node.exprs[0])
|
||||||
got_typ_sym := c.table.sym(got_typ)
|
got_type_sym := c.table.sym(got_type)
|
||||||
if got_typ_sym.kind == .struct_ && c.type_implements(got_typ, ast.error_type, node.pos) {
|
if got_type_sym.kind == .struct_
|
||||||
|
&& c.type_implements(got_type, ast.error_type, node.pos) {
|
||||||
node.exprs[0] = ast.CastExpr{
|
node.exprs[0] = ast.CastExpr{
|
||||||
expr: node.exprs[0]
|
expr: node.exprs[0]
|
||||||
typname: 'IError'
|
typname: 'IError'
|
||||||
typ: ast.error_type
|
typ: ast.error_type
|
||||||
expr_type: got_typ
|
expr_type: got_type
|
||||||
pos: node.pos
|
pos: node.pos
|
||||||
}
|
}
|
||||||
node.types[0] = ast.error_type
|
node.types[0] = ast.error_type
|
||||||
@ -161,24 +162,25 @@ fn (mut c Checker) return_stmt(mut node ast.Return) {
|
|||||||
c.error('should not unwrap option var on return, it could be none', node.pos)
|
c.error('should not unwrap option var on return, it could be none', node.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
got_typ := c.unwrap_generic(got_types[i])
|
got_type := c.unwrap_generic(got_types[i])
|
||||||
if got_typ.has_flag(.option) && got_typ.clear_flag(.option) != exp_type.clear_flag(.option) {
|
if got_type.has_flag(.option)
|
||||||
|
&& got_type.clear_flag(.option) != exp_type.clear_flag(.option) {
|
||||||
pos := node.exprs[expr_idxs[i]].pos()
|
pos := node.exprs[expr_idxs[i]].pos()
|
||||||
c.error('cannot use `${c.table.type_to_str(got_typ)}` as ${c.error_type_name(exp_type)} in return argument',
|
c.error('cannot use `${c.table.type_to_str(got_type)}` as ${c.error_type_name(exp_type)} in return argument',
|
||||||
pos)
|
pos)
|
||||||
}
|
}
|
||||||
if got_typ.has_flag(.result) && (!exp_type.has_flag(.result)
|
if got_type.has_flag(.result) && (!exp_type.has_flag(.result)
|
||||||
|| c.table.type_to_str(got_typ) != c.table.type_to_str(exp_type)) {
|
|| c.table.type_to_str(got_type) != c.table.type_to_str(exp_type)) {
|
||||||
pos := node.exprs[expr_idxs[i]].pos()
|
pos := node.exprs[expr_idxs[i]].pos()
|
||||||
c.error('cannot use `${c.table.type_to_str(got_typ)}` as ${c.error_type_name(exp_type)} in return argument',
|
c.error('cannot use `${c.table.type_to_str(got_type)}` as ${c.error_type_name(exp_type)} in return argument',
|
||||||
pos)
|
pos)
|
||||||
}
|
}
|
||||||
if node.exprs[expr_idxs[i]] !is ast.ComptimeCall {
|
if node.exprs[expr_idxs[i]] !is ast.ComptimeCall {
|
||||||
got_typ_sym := c.table.sym(got_typ)
|
got_type_sym := c.table.sym(got_type)
|
||||||
exp_typ_sym := c.table.sym(exp_type)
|
exp_type_sym := c.table.sym(exp_type)
|
||||||
pos := node.exprs[expr_idxs[i]].pos()
|
pos := node.exprs[expr_idxs[i]].pos()
|
||||||
if c.check_types(got_typ, exp_type) {
|
if c.check_types(got_type, exp_type) {
|
||||||
if exp_type.is_unsigned() && got_typ.is_int_literal() {
|
if exp_type.is_unsigned() && got_type.is_int_literal() {
|
||||||
if node.exprs[expr_idxs[i]] is ast.IntegerLiteral {
|
if node.exprs[expr_idxs[i]] is ast.IntegerLiteral {
|
||||||
var := (node.exprs[expr_idxs[i]] as ast.IntegerLiteral).val
|
var := (node.exprs[expr_idxs[i]] as ast.IntegerLiteral).val
|
||||||
if var[0] == `-` {
|
if var[0] == `-` {
|
||||||
@ -188,60 +190,58 @@ fn (mut c Checker) return_stmt(mut node ast.Return) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if exp_typ_sym.kind == .interface_ {
|
if exp_type_sym.kind == .interface_ {
|
||||||
if c.type_implements(got_typ, exp_type, node.pos) {
|
if c.type_implements(got_type, exp_type, node.pos) {
|
||||||
if !got_typ.is_ptr() && !got_typ.is_pointer()
|
if !got_type.is_ptr() && !got_type.is_pointer()
|
||||||
&& got_typ_sym.kind != .interface_ && !c.inside_unsafe {
|
&& got_type_sym.kind != .interface_ && !c.inside_unsafe {
|
||||||
c.mark_as_referenced(mut &node.exprs[expr_idxs[i]], true)
|
c.mark_as_referenced(mut &node.exprs[expr_idxs[i]], true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// `fn foo() !int { return Err{} }`
|
// `fn foo() !int { return Err{} }`
|
||||||
if got_typ_sym.kind == .struct_
|
if got_type_sym.kind == .struct_
|
||||||
&& c.type_implements(got_typ, ast.error_type, node.pos) {
|
&& c.type_implements(got_type, ast.error_type, node.pos) {
|
||||||
node.exprs[expr_idxs[i]] = ast.CastExpr{
|
node.exprs[expr_idxs[i]] = ast.CastExpr{
|
||||||
expr: node.exprs[expr_idxs[i]]
|
expr: node.exprs[expr_idxs[i]]
|
||||||
typname: 'IError'
|
typname: 'IError'
|
||||||
typ: ast.error_type
|
typ: ast.error_type
|
||||||
expr_type: got_typ
|
expr_type: got_type
|
||||||
pos: node.pos
|
pos: node.pos
|
||||||
}
|
}
|
||||||
node.types[expr_idxs[i]] = ast.error_type
|
node.types[expr_idxs[i]] = ast.error_type
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
got_typ_name := if got_typ_sym.kind == .function {
|
got_type_name := if got_type_sym.kind == .function {
|
||||||
'${c.table.type_to_str(got_typ)}'
|
'${c.table.type_to_str(got_type)}'
|
||||||
} else {
|
} else {
|
||||||
got_typ_sym.name
|
got_type_sym.name
|
||||||
}
|
}
|
||||||
c.error('cannot use `${got_typ_name}` as ${c.error_type_name(exp_type)} in return argument',
|
c.error('cannot use `${got_type_name}` as ${c.error_type_name(exp_type)} in return argument',
|
||||||
pos)
|
pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unaliased_exp_typ := c.table.unaliased_type(exp_type)
|
if got_type.is_real_pointer() && !exp_type.is_real_pointer()
|
||||||
if got_typ.is_real_pointer() && !exp_type.is_real_pointer()
|
&& !c.table.unaliased_type(exp_type).is_real_pointer() {
|
||||||
&& !unaliased_exp_typ.is_real_pointer() {
|
|
||||||
pos := node.exprs[expr_idxs[i]].pos()
|
pos := node.exprs[expr_idxs[i]].pos()
|
||||||
if node.exprs[expr_idxs[i]].is_auto_deref_var() {
|
if node.exprs[expr_idxs[i]].is_auto_deref_var() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
c.add_error_detail('use `return *pointer` instead of `return pointer`, and just `return value` instead of `return &value`')
|
c.add_error_detail('use `return *pointer` instead of `return pointer`, and just `return value` instead of `return &value`')
|
||||||
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',
|
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_type)}` instead',
|
||||||
pos)
|
pos)
|
||||||
}
|
}
|
||||||
unaliased_got_typ := c.table.unaliased_type(got_typ)
|
if exp_type.is_real_pointer() && !got_type.is_real_pointer()
|
||||||
if exp_type.is_real_pointer() && !got_typ.is_real_pointer()
|
&& !c.table.unaliased_type(got_type).is_real_pointer()
|
||||||
&& !unaliased_got_typ.is_real_pointer() && got_typ != ast.int_literal_type
|
&& got_type != ast.int_literal_type && !c.pref.translated && !c.file.is_translated {
|
||||||
&& !c.pref.translated && !c.file.is_translated {
|
|
||||||
pos := node.exprs[expr_idxs[i]].pos()
|
pos := node.exprs[expr_idxs[i]].pos()
|
||||||
if node.exprs[expr_idxs[i]].is_auto_deref_var() {
|
if node.exprs[expr_idxs[i]].is_auto_deref_var() {
|
||||||
continue
|
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',
|
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_type)}` instead',
|
||||||
pos)
|
pos)
|
||||||
}
|
}
|
||||||
if exp_type.is_ptr() && got_typ.is_ptr() {
|
if exp_type.is_ptr() && got_type.is_ptr() {
|
||||||
mut r_expr := &node.exprs[expr_idxs[i]]
|
mut r_expr := &node.exprs[expr_idxs[i]]
|
||||||
if mut r_expr is ast.Ident {
|
if mut r_expr is ast.Ident {
|
||||||
if mut r_expr.obj is ast.Var {
|
if mut r_expr.obj is ast.Var {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user