1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

checker: optimize the position of the propagation error, where a fn needs to return an optional or result(fix #15780) (#15813)

This commit is contained in:
shove 2022-09-19 19:49:23 +08:00 committed by GitHub
parent 0ff53d18c1
commit 84bc170720
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 73 additions and 13 deletions

View File

@ -85,13 +85,19 @@ pub fn (mut app App) controller_get_all_task() ?vweb.Result {
for orm_stmt_kind in orm_stmt_kinds {
match orm_stmt_kind {
'insert' {
framework_platform[orm_stmt_kind] = insert_framework_benchmark_times().to_map()
framework_platform[orm_stmt_kind] = insert_framework_benchmark_times() or {
return error('')
}.to_map()
}
'select' {
framework_platform[orm_stmt_kind] = select_framework_benchmark_times().to_map()
framework_platform[orm_stmt_kind] = select_framework_benchmark_times() or {
return error('')
}.to_map()
}
'update' {
framework_platform[orm_stmt_kind] = update_framework_benchmark_times().to_map()
framework_platform[orm_stmt_kind] = update_framework_benchmark_times() or {
return error('')
}.to_map()
}
else {}
}
@ -109,7 +115,7 @@ pub fn (mut app App) controller_get_all_task() ?vweb.Result {
return $vweb.html()
}
fn insert_framework_benchmark_times() FrameworkPlatform {
fn insert_framework_benchmark_times() !FrameworkPlatform {
numbers := FrameworkPlatform{
v_sqlite_memory: v_sqlite_memory()!.insert
// v_sqlite_file: v_sqlite_file()!.insert
@ -119,7 +125,7 @@ fn insert_framework_benchmark_times() FrameworkPlatform {
return numbers
}
fn select_framework_benchmark_times() FrameworkPlatform {
fn select_framework_benchmark_times() !FrameworkPlatform {
numbers := FrameworkPlatform{
v_sqlite_memory: v_sqlite_memory()!.@select
// v_sqlite_file: v_sqlite_file()!.@select
@ -129,7 +135,7 @@ fn select_framework_benchmark_times() FrameworkPlatform {
return numbers
}
fn update_framework_benchmark_times() FrameworkPlatform {
fn update_framework_benchmark_times() !FrameworkPlatform {
numbers := FrameworkPlatform{
v_sqlite_memory: v_sqlite_memory()!.update
// v_sqlite_file: v_sqlite_file()!.@select

View File

@ -957,6 +957,7 @@ pub fn (mut c Checker) check_or_expr(node ast.OrExpr, ret_type ast.Type, expr_re
if node.kind == .propagate_option {
if c.table.cur_fn != unsafe { nil } && !c.table.cur_fn.return_type.has_flag(.optional)
&& c.table.cur_fn.name != 'main.main' && !c.inside_const {
c.add_instruction_for_optional_type()
c.error('to propagate the call, `$c.table.cur_fn.name` must return an optional type',
node.pos)
}
@ -974,7 +975,8 @@ pub fn (mut c Checker) check_or_expr(node ast.OrExpr, ret_type ast.Type, expr_re
if node.kind == .propagate_result {
if c.table.cur_fn != unsafe { nil } && !c.table.cur_fn.return_type.has_flag(.result)
&& c.table.cur_fn.name != 'main.main' && !c.inside_const {
c.error('to propagate the call, `$c.table.cur_fn.name` must return an result type',
c.add_instruction_for_result_type()
c.error('to propagate the call, `$c.table.cur_fn.name` must return a result type',
node.pos)
}
if !expr_return_type.has_flag(.result) {
@ -3686,6 +3688,20 @@ pub fn (mut c Checker) add_error_detail(s string) {
c.error_details << s
}
pub fn (mut c Checker) add_error_detail_with_pos(msg string, pos token.Pos) {
c.add_error_detail(util.formatted_error('details:', msg, c.file.path, pos))
}
pub fn (mut c Checker) add_instruction_for_optional_type() {
c.add_error_detail_with_pos('prepend ? before the declaration of the return type of `$c.table.cur_fn.name`',
c.table.cur_fn.return_type_pos)
}
pub fn (mut c Checker) add_instruction_for_result_type() {
c.add_error_detail_with_pos('prepend ! before the declaration of the return type of `$c.table.cur_fn.name`',
c.table.cur_fn.return_type_pos)
}
pub fn (mut c Checker) warn(s string, pos token.Pos) {
allow_warnings := !(c.pref.is_prod || c.pref.warns_are_errors) // allow warnings only in dev builds
c.warn_or_error(s, pos, allow_warnings)

View File

@ -466,13 +466,23 @@ pub fn (mut c Checker) call_expr(mut node ast.CallExpr) ast.Type {
c.expected_or_type = node.return_type.clear_flag(.optional)
c.stmts_ending_with_expression(node.or_block.stmts)
c.expected_or_type = ast.void_type
if node.or_block.kind == .propagate_option && c.table.cur_fn != unsafe { nil }
&& !c.table.cur_fn.return_type.has_flag(.optional) && !c.inside_const {
if !c.table.cur_fn.is_main {
if !c.inside_const && c.table.cur_fn != unsafe { nil } && !c.table.cur_fn.is_main {
// TODO: use just `if node.or_block.kind == .propagate_result && !c.table.cur_fn.return_type.has_flag(.result) {` after the deprecation for ?!Type
if node.or_block.kind == .propagate_result && !c.table.cur_fn.return_type.has_flag(.result)
&& !c.table.cur_fn.return_type.has_flag(.optional) {
c.add_instruction_for_result_type()
c.error('to propagate the result call, `$c.table.cur_fn.name` must return a result',
node.or_block.pos)
}
if node.or_block.kind == .propagate_option
&& !c.table.cur_fn.return_type.has_flag(.optional) {
c.add_instruction_for_optional_type()
c.error('to propagate the optional call, `$c.table.cur_fn.name` must return an optional',
node.or_block.pos)
}
}
return typ
}

View File

@ -5,6 +5,13 @@ vlib/v/checker/tests/optional_propagate_nested.vv:10:18: error: to propagate the
| ^
11 | return s
12 | }
Details: vlib/v/checker/tests/optional_propagate_nested.vv:9:14: details: prepend ? before the declaration of the return type of `xx_prop`
7 | }
8 |
9 | fn xx_prop() string {
| ~~~~~~
10 | s := ret(raise()?)
11 | return s
vlib/v/checker/tests/optional_propagate_nested.vv:28:21: error: to propagate the optional call, `aa_propagate` must return an optional
26 |
27 | fn (mut s St) aa_propagate() {
@ -12,3 +19,10 @@ vlib/v/checker/tests/optional_propagate_nested.vv:28:21: error: to propagate the
| ^
29 | s.z = 7.5
30 | println(f)
Details: vlib/v/checker/tests/optional_propagate_nested.vv:27:30: details: prepend ? before the declaration of the return type of `aa_propagate`
25 | }
26 |
27 | fn (mut s St) aa_propagate() {
| ^
28 | f := retf(s.raise()?)
29 | s.z = 7.5

View File

@ -1,14 +1,28 @@
vlib/v/checker/tests/wrong_propagate_ret_type.vv:10:17: error: to propagate the optional call, `opt_call` must return an optional
8 |
8 |
9 | fn opt_call() int {
10 | a := ret_none()?
| ^
11 | return a
12 | }
vlib/v/checker/tests/wrong_propagate_ret_type.vv:15:17: error: unexpected `!`, the function `ret_bool` does neither return an optional nor a result
13 |
Details: vlib/v/checker/tests/wrong_propagate_ret_type.vv:9:15: details: prepend ? before the declaration of the return type of `opt_call`
7 | }
8 |
9 | fn opt_call() int {
| ~~~
10 | a := ret_none()?
11 | return a
vlib/v/checker/tests/wrong_propagate_ret_type.vv:15:17: error: to propagate the result call, `res_call` must return a result
13 |
14 | fn res_call() bool {
15 | a := ret_bool()!
| ^
16 | return a
17 | }
Details: vlib/v/checker/tests/wrong_propagate_ret_type.vv:14:15: details: prepend ! before the declaration of the return type of `res_call`
12 | }
13 |
14 | fn res_call() bool {
| ~~~~
15 | a := ret_bool()!
16 | return a