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 { for orm_stmt_kind in orm_stmt_kinds {
match orm_stmt_kind { match orm_stmt_kind {
'insert' { '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' { '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' { '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 {} else {}
} }
@ -109,7 +115,7 @@ pub fn (mut app App) controller_get_all_task() ?vweb.Result {
return $vweb.html() return $vweb.html()
} }
fn insert_framework_benchmark_times() FrameworkPlatform { fn insert_framework_benchmark_times() !FrameworkPlatform {
numbers := FrameworkPlatform{ numbers := FrameworkPlatform{
v_sqlite_memory: v_sqlite_memory()!.insert v_sqlite_memory: v_sqlite_memory()!.insert
// v_sqlite_file: v_sqlite_file()!.insert // v_sqlite_file: v_sqlite_file()!.insert
@ -119,7 +125,7 @@ fn insert_framework_benchmark_times() FrameworkPlatform {
return numbers return numbers
} }
fn select_framework_benchmark_times() FrameworkPlatform { fn select_framework_benchmark_times() !FrameworkPlatform {
numbers := FrameworkPlatform{ numbers := FrameworkPlatform{
v_sqlite_memory: v_sqlite_memory()!.@select v_sqlite_memory: v_sqlite_memory()!.@select
// v_sqlite_file: v_sqlite_file()!.@select // v_sqlite_file: v_sqlite_file()!.@select
@ -129,7 +135,7 @@ fn select_framework_benchmark_times() FrameworkPlatform {
return numbers return numbers
} }
fn update_framework_benchmark_times() FrameworkPlatform { fn update_framework_benchmark_times() !FrameworkPlatform {
numbers := FrameworkPlatform{ numbers := FrameworkPlatform{
v_sqlite_memory: v_sqlite_memory()!.update v_sqlite_memory: v_sqlite_memory()!.update
// v_sqlite_file: v_sqlite_file()!.@select // 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 node.kind == .propagate_option {
if c.table.cur_fn != unsafe { nil } && !c.table.cur_fn.return_type.has_flag(.optional) 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.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', c.error('to propagate the call, `$c.table.cur_fn.name` must return an optional type',
node.pos) 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 node.kind == .propagate_result {
if c.table.cur_fn != unsafe { nil } && !c.table.cur_fn.return_type.has_flag(.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.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) node.pos)
} }
if !expr_return_type.has_flag(.result) { 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 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) { 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 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) 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.expected_or_type = node.return_type.clear_flag(.optional)
c.stmts_ending_with_expression(node.or_block.stmts) c.stmts_ending_with_expression(node.or_block.stmts)
c.expected_or_type = ast.void_type 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.inside_const && c.table.cur_fn != unsafe { nil } && !c.table.cur_fn.is_main {
if !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', c.error('to propagate the optional call, `$c.table.cur_fn.name` must return an optional',
node.or_block.pos) node.or_block.pos)
} }
} }
return typ 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 11 | return s
12 | } 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 vlib/v/checker/tests/optional_propagate_nested.vv:28:21: error: to propagate the optional call, `aa_propagate` must return an optional
26 | 26 |
27 | fn (mut s St) aa_propagate() { 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 29 | s.z = 7.5
30 | println(f) 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 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 { 9 | fn opt_call() int {
10 | a := ret_none()? 10 | a := ret_none()?
| ^ | ^
11 | return a 11 | return a
12 | } 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 Details: vlib/v/checker/tests/wrong_propagate_ret_type.vv:9:15: details: prepend ? before the declaration of the return type of `opt_call`
13 | 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 { 14 | fn res_call() bool {
15 | a := ret_bool()! 15 | a := ret_bool()!
| ^ | ^
16 | return a 16 | return a
17 | } 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