mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: allow get_ref() or { unsafe{nil} }
, as well as fn get_ref() ?&Type { return unsafe { nil } }
(fix: #16062) (#16063)
This commit is contained in:
parent
51a9e89c4a
commit
aabda5a525
@ -1030,6 +1030,10 @@ fn (mut c Checker) check_or_last_stmt(stmt ast.Stmt, ret_type ast.Type, expr_ret
|
|||||||
c.error('`or` block must provide a default value of type `$expected_type_name`, or return/continue/break or call a [noreturn] function like panic(err) or exit(1)',
|
c.error('`or` block must provide a default value of type `$expected_type_name`, or return/continue/break or call a [noreturn] function like panic(err) or exit(1)',
|
||||||
stmt.expr.pos())
|
stmt.expr.pos())
|
||||||
} else {
|
} else {
|
||||||
|
if ret_type.is_ptr() && last_stmt_typ.is_pointer()
|
||||||
|
&& c.table.sym(last_stmt_typ).kind == .voidptr {
|
||||||
|
return
|
||||||
|
}
|
||||||
type_name := c.table.type_to_str(last_stmt_typ)
|
type_name := c.table.type_to_str(last_stmt_typ)
|
||||||
expected_type_name := c.table.type_to_str(ret_type.clear_flag(.optional).clear_flag(.result))
|
expected_type_name := c.table.type_to_str(ret_type.clear_flag(.optional).clear_flag(.result))
|
||||||
c.error('wrong return type `$type_name` in the `or {}` block, expected `$expected_type_name`',
|
c.error('wrong return type `$type_name` in the `or {}` block, expected `$expected_type_name`',
|
||||||
@ -1070,7 +1074,9 @@ fn (mut c Checker) check_or_last_stmt(stmt ast.Stmt, ret_type ast.Type, expr_ret
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if c.check_types(stmt.typ, expr_return_type) {
|
if c.check_types(stmt.typ, expr_return_type) {
|
||||||
if stmt.typ.is_ptr() == expr_return_type.is_ptr() {
|
if stmt.typ.is_ptr() == expr_return_type.is_ptr()
|
||||||
|
|| (expr_return_type.is_ptr() && stmt.typ.is_pointer()
|
||||||
|
&& c.table.sym(stmt.typ).kind == .voidptr) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -382,11 +382,34 @@ fn test_return_or() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For issue #16058: cgen error: exists spaces in the name of the ?&C.struct
|
// For issue #16058: cgen error: exists spaces in the name of the ?&C.struct
|
||||||
fn bar() ?&C.stat {
|
fn get_opt_pointer_to_c_struct() ?&C.stat {
|
||||||
return none
|
return none
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_optional_ref_c_struct_gen() {
|
fn test_optional_ref_c_struct_gen() {
|
||||||
_ := bar() or { &C.stat{} }
|
_ := get_opt_pointer_to_c_struct() or { &C.stat{} }
|
||||||
|
}
|
||||||
|
|
||||||
|
// For issue #16062: checker disallow the return of voidptr(nil) in or block
|
||||||
|
struct Bar {}
|
||||||
|
|
||||||
|
fn get_bar(should_return_value bool) ?&Bar {
|
||||||
|
if should_return_value {
|
||||||
|
return unsafe { nil }
|
||||||
|
}
|
||||||
|
return none
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_() {
|
||||||
|
a := get_bar(true)?
|
||||||
|
assert a == unsafe { nil }
|
||||||
|
//
|
||||||
|
x := get_bar(false) or {
|
||||||
|
assert true
|
||||||
|
unsafe { nil }
|
||||||
|
}
|
||||||
|
assert x == unsafe { nil }
|
||||||
|
//
|
||||||
|
get_bar(false) or { unsafe { nil } }
|
||||||
assert true
|
assert true
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user