checker: fix returning error on reference results (#14313)

Daniel Däschle 2022-05-05 16:02:49 +02:00 committed by Jef Roosens
parent 3afb88c4e8
commit 84086bb7a3
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
2 changed files with 14 additions and 3 deletions

View File

@ -24,6 +24,7 @@ pub fn (mut c Checker) return_stmt(mut node ast.Return) {
return return
} }
exp_is_optional := expected_type.has_flag(.optional) exp_is_optional := expected_type.has_flag(.optional)
exp_is_result := expected_type.has_flag(.result)
mut expected_types := [expected_type] mut expected_types := [expected_type]
if expected_type_sym.info is ast.MultiReturn { if expected_type_sym.info is ast.MultiReturn {
expected_types = expected_type_sym.info.types expected_types = expected_type_sym.info.types
@ -72,11 +73,13 @@ pub fn (mut c Checker) return_stmt(mut node ast.Return) {
} }
} }
} }
// allow `none` & `error` return types for function that returns optional // allow `none` & `error` return types for function that returns option or result
option_type_idx := c.table.type_idxs['Option'] option_type_idx := c.table.type_idxs['Option']
result_type_idx := c.table.type_idxs['_result']
got_types_0_idx := got_types[0].idx() got_types_0_idx := got_types[0].idx()
if exp_is_optional if (exp_is_optional
&& got_types_0_idx in [ast.none_type_idx, ast.error_type_idx, option_type_idx] { && got_types_0_idx in [ast.none_type_idx, ast.error_type_idx, option_type_idx])
|| (exp_is_result && got_types_0_idx in [ast.error_type_idx, result_type_idx]) {
if got_types_0_idx == ast.none_type_idx && expected_type == ast.ovoid_type { if got_types_0_idx == ast.none_type_idx && expected_type == ast.ovoid_type {
c.error('returning `none` in functions, that have a `?` result type is not allowed anymore, either `return error(message)` or just `return` instead', c.error('returning `none` in functions, that have a `?` result type is not allowed anymore, either `return error(message)` or just `return` instead',
node.pos) node.pos)

View File

@ -73,3 +73,11 @@ fn unsafe_return_error() !int {
fn test_unsafe_return_error() { fn test_unsafe_return_error() {
unsafe_return_error() or { assert err.msg() == 'abc' } unsafe_return_error() or { assert err.msg() == 'abc' }
} }
fn return_reference_type(path string) !&string {
if path.len == 0 {
return error('vfopen called with ""')
}
str := ''
return &str
}