Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 569b52a

Browse files
committedJun 21, 2023
checker: abstract expr or block error
1 parent ee65ca6 commit 569b52a

File tree

4 files changed

+35
-42
lines changed

4 files changed

+35
-42
lines changed
 

‎vlib/v/checker/checker.v

+31-38
Original file line numberDiff line numberDiff line change
@@ -1026,6 +1026,28 @@ fn (mut c Checker) type_implements(typ ast.Type, interface_type ast.Type, pos to
10261026
return true
10271027
}
10281028

1029+
fn (mut c Checker) expr_or_block_err(kind ast.OrKind, expr_name string, pos token.Pos, is_field bool) {
1030+
obj_does_not_return_or_is_not := if is_field {
1031+
'field `${expr_name}` is not'
1032+
} else {
1033+
'function `${expr_name}` does not return'
1034+
}
1035+
match kind {
1036+
.absent {}
1037+
.block {
1038+
c.error('unexpected `or` block, the ${obj_does_not_return_or_is_not} an Option or a Result',
1039+
pos)
1040+
}
1041+
.propagate_option {
1042+
c.error('unexpected `?`, the ${obj_does_not_return_or_is_not} an Option',
1043+
pos)
1044+
}
1045+
.propagate_result {
1046+
c.error('unexpected `!`, the ${obj_does_not_return_or_is_not} a Result', pos)
1047+
}
1048+
}
1049+
}
1050+
10291051
// return the actual type of the expression, once the option is handled
10301052
fn (mut c Checker) check_expr_opt_call(expr ast.Expr, ret_type ast.Type) ast.Type {
10311053
if expr is ast.CallExpr {
@@ -1057,15 +1079,8 @@ fn (mut c Checker) check_expr_opt_call(expr ast.Expr, ret_type ast.Type) ast.Typ
10571079
}
10581080
}
10591081
return ret_type.clear_flag(.result)
1060-
} else if expr.or_block.kind == .block {
1061-
c.error('unexpected `or` block, the function `${expr.name}` does not return an Option or a Result',
1062-
expr.or_block.pos)
1063-
} else if expr.or_block.kind == .propagate_option {
1064-
c.error('unexpected `?`, the function `${expr.name}` does not return an Option',
1065-
expr.or_block.pos)
1066-
} else if expr.or_block.kind == .propagate_result {
1067-
c.error('unexpected `!`, the function `${expr.name}` does not return a Result',
1068-
expr.or_block.pos)
1082+
} else {
1083+
c.expr_or_block_err(expr.or_block.kind, expr.name, expr.or_block.pos, false)
10691084
}
10701085
} else if expr is ast.SelectorExpr && c.table.sym(ret_type).kind != .chan {
10711086
if expr.typ.has_flag(.option) || expr.typ.has_flag(.result) {
@@ -1089,14 +1104,9 @@ fn (mut c Checker) check_expr_opt_call(expr ast.Expr, ret_type ast.Type) ast.Typ
10891104
}
10901105
}
10911106
return ret_type.clear_flag(.result)
1092-
} else if expr.or_block.kind == .block {
1093-
c.error('unexpected `or` block, the field `${expr.field_name}` is neither an Option, nor a Result',
1094-
expr.or_block.pos)
1095-
} else if expr.or_block.kind == .propagate_option {
1096-
c.error('unexpected `?`, the field `${expr.field_name}` is not an Option',
1097-
expr.or_block.pos)
1098-
} else if expr.or_block.kind == .propagate_result {
1099-
c.error('unexpected `!`, Result fields are not supported', expr.or_block.pos)
1107+
} else {
1108+
c.expr_or_block_err(expr.or_block.kind, expr.field_name, expr.or_block.pos,
1109+
true)
11001110
}
11011111
} else if expr is ast.IndexExpr {
11021112
if expr.or_expr.kind != .absent {
@@ -2511,16 +2521,8 @@ pub fn (mut c Checker) expr(node_ ast.Expr) ast.Type {
25112521
}
25122522
}
25132523
if !ret_type.has_flag(.option) && !ret_type.has_flag(.result) {
2514-
if node.or_block.kind == .block {
2515-
c.error('unexpected `or` block, the function `${node.name}` does not return an Option or a Result',
2516-
node.or_block.pos)
2517-
} else if node.or_block.kind == .propagate_option {
2518-
c.error('unexpected `?`, the function `${node.name}` does not return an Option or a Result',
2519-
node.or_block.pos)
2520-
} else if node.or_block.kind == .propagate_result {
2521-
c.error('unexpected `!`, the function `${node.name}` does not return an Option or a Result',
2522-
node.or_block.pos)
2523-
}
2524+
c.expr_or_block_err(node.or_block.kind, node.name, node.or_block.pos,
2525+
false)
25242526
}
25252527
if node.or_block.kind != .absent {
25262528
if ret_type.has_flag(.option) {
@@ -2710,18 +2712,9 @@ pub fn (mut c Checker) expr(node_ ast.Expr) ast.Type {
27102712
if c.table.sym(ret_type).kind == .chan {
27112713
return ret_type
27122714
}
2713-
27142715
if !ret_type.has_flag(.option) && !ret_type.has_flag(.result) {
2715-
if node.or_block.kind == .block {
2716-
c.error('unexpected `or` block, the field `${node.field_name}` is neither an Option, nor a Result',
2717-
node.or_block.pos)
2718-
} else if node.or_block.kind == .propagate_option {
2719-
c.error('unexpected `?`, the field `${node.field_name}` is neither an Option, nor a Result',
2720-
node.or_block.pos)
2721-
} else if node.or_block.kind == .propagate_result {
2722-
c.error('unexpected `!`, the field `${node.field_name}` is neither an Option, nor a Result',
2723-
node.or_block.pos)
2724-
}
2716+
c.expr_or_block_err(node.or_block.kind, node.field_name, node.or_block.pos,
2717+
true)
27252718
}
27262719
if node.or_block.kind != .absent {
27272720
if ret_type.has_flag(.option) {

‎vlib/v/checker/tests/go_wait_or.out

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
vlib/v/checker/tests/go_wait_or.vv:11:16: error: unexpected `?`, the function `wait` does not return an Option or a Result
1+
vlib/v/checker/tests/go_wait_or.vv:11:16: error: unexpected `?`, the function `wait` does not return an Option
22
9 | spawn d(1)
33
10 | ]
44
11 | r := tg.wait()?
@@ -19,7 +19,7 @@ vlib/v/checker/tests/go_wait_or.vv:19:13: error: unexpected `or` block, the func
1919
| ~~~~~~~~~~~~~~~~~~~~~~~
2020
20 | tg2[0].wait()?
2121
21 | tg3 := [
22-
vlib/v/checker/tests/go_wait_or.vv:20:15: error: unexpected `?`, the function `wait` does not return an Option or a Result
22+
vlib/v/checker/tests/go_wait_or.vv:20:15: error: unexpected `?`, the function `wait` does not return an Option
2323
18 | ]
2424
19 | tg2.wait() or { panic('problem') }
2525
20 | tg2[0].wait()?

‎vlib/v/checker/tests/struct_field_option_err.out

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ vlib/v/checker/tests/struct_field_option_err.vv:16:19: error: last statement in
2626
| ^
2727
17 |
2828
18 | _ = f.baz?
29-
vlib/v/checker/tests/struct_field_option_err.vv:18:11: error: unexpected `?`, the field `baz` is neither an Option, nor a Result
29+
vlib/v/checker/tests/struct_field_option_err.vv:18:11: error: unexpected `?`, the field `baz` is not an Option
3030
16 | _ = f.bar or { _ = 1 }
3131
17 |
3232
18 | _ = f.baz?

‎vlib/v/checker/tests/unexpected_or_propagate.out

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
vlib/v/checker/tests/unexpected_or_propagate.vv:6:17: error: unexpected `?`, the function `ret_zero` does not return an Option or a Result
1+
vlib/v/checker/tests/unexpected_or_propagate.vv:6:17: error: unexpected `?`, the function `ret_zero` does not return an Option
22
4 |
33
5 | fn opt_fn() ?int {
44
6 | a := ret_zero()?

0 commit comments

Comments
 (0)
Please sign in to comment.