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)',
|
||||
stmt.expr.pos())
|
||||
} 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)
|
||||
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`',
|
||||
@ -1070,7 +1074,9 @@ fn (mut c Checker) check_or_last_stmt(stmt ast.Stmt, ret_type ast.Type, expr_ret
|
||||
return
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -382,11 +382,34 @@ fn test_return_or() {
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user