mirror of
https://github.com/vlang/v.git
synced 2025-09-13 09:25:45 -04:00
checker: turn the option/result split warning into an error; readme: better wording
This commit is contained in:
parent
5b1b2cc7c0
commit
773f961736
20
README.md
20
README.md
@ -41,20 +41,22 @@
|
|||||||
- C and JavaScript backends
|
- C and JavaScript backends
|
||||||
- Great for writing low-level software ([Vinix OS](https://github.com/vlang/vinix))
|
- Great for writing low-level software ([Vinix OS](https://github.com/vlang/vinix))
|
||||||
|
|
||||||
## Stability guarantee and future changes
|
## Stability, future changes, post 1.0 freeze
|
||||||
|
|
||||||
Despite being at an early development stage, the V language is relatively stable and has
|
Despite being at an early development stage, the V language is relatively stable, and doesn't
|
||||||
backwards compatibility guarantee, meaning that the code you write today is guaranteed
|
change often. But there will bechanges before 1.0.
|
||||||
to work a month, a year, or five years from now.
|
Most changes in the syntax are handled via vfmt automatically.
|
||||||
|
|
||||||
There still may be minor syntax changes before the 1.0 release, but they will be handled
|
The V core APIs (primarily the `os` module) will also have minor changes until
|
||||||
automatically via `vfmt`, as has been done in the past.
|
|
||||||
|
|
||||||
The V core APIs (primarily the `os` module) will still have minor changes until
|
|
||||||
they are stabilized in V 1.0. Of course the APIs will grow after that, but without breaking
|
they are stabilized in V 1.0. Of course the APIs will grow after that, but without breaking
|
||||||
existing code.
|
existing code.
|
||||||
|
|
||||||
Unlike many other languages, V is not going to be always changing, with new features
|
After the 1.0 release V is going to be in the "feature freeze" mode. That means no breaking changes
|
||||||
|
in the language, only bug fixes and performance improvements. Similar to Go.
|
||||||
|
|
||||||
|
Will there be V 2.0? Not within a decade after 1.0, perhaps not ever.
|
||||||
|
|
||||||
|
To sum it up, unlike many other languages, V is not going to be always changing, with new features
|
||||||
being introduced and old features modified. It is always going to be a small and simple
|
being introduced and old features modified. It is always going to be a small and simple
|
||||||
language, very similar to the way it is right now.
|
language, very similar to the way it is right now.
|
||||||
|
|
||||||
|
@ -121,10 +121,10 @@ fn (mut c Checker) return_stmt(mut node ast.Return) {
|
|||||||
result_type_idx := c.table.type_idxs['_result']
|
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_option && got_types_0_idx == ast.error_type_idx {
|
if exp_is_option && got_types_0_idx == ast.error_type_idx {
|
||||||
c.warn('Option and Result types have been split, use `!Foo` to return errors',
|
c.error('Option and Result types have been split, use `!Foo` to return errors',
|
||||||
node.pos)
|
node.pos)
|
||||||
} else if exp_is_result && got_types_0_idx == ast.none_type_idx {
|
} else if exp_is_result && got_types_0_idx == ast.none_type_idx {
|
||||||
c.warn('Option and Result types have been split, use `?` to return none', node.pos)
|
c.error('Option and Result types have been split, use `?` to return none', node.pos)
|
||||||
}
|
}
|
||||||
if (exp_is_option
|
if (exp_is_option
|
||||||
&& 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])
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
vlib/v/checker/tests/option_fn_return_error.vv:2:2: warning: Option and Result types have been split, use `!Foo` to return errors
|
vlib/v/checker/tests/option_fn_return_error.vv:2:2: error: Option and Result types have been split, use `!Foo` to return errors
|
||||||
1 | fn func() ?int {
|
1 | fn func() ?int {
|
||||||
2 | return error('Some error')
|
2 | return error('Some error')
|
||||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -1,21 +1,14 @@
|
|||||||
vlib/v/checker/tests/void_fn_multiple_ret_err.vv:6:2: warning: Option and Result types have been split, use `?` to return none
|
|
||||||
4 |
|
|
||||||
5 | fn foo_result_2() ! {
|
|
||||||
6 | return none
|
|
||||||
| ~~~~~~~~~~~
|
|
||||||
7 | }
|
|
||||||
8 |
|
|
||||||
vlib/v/checker/tests/void_fn_multiple_ret_err.vv:2:9: error: functions with Result-only return types can only return an error
|
vlib/v/checker/tests/void_fn_multiple_ret_err.vv:2:9: error: functions with Result-only return types can only return an error
|
||||||
1 | fn foo_result_1() ! {
|
1 | fn foo_result_1() ! {
|
||||||
2 | return none, 100
|
2 | return none, 100
|
||||||
| ~~~~
|
| ~~~~
|
||||||
3 | }
|
3 | }
|
||||||
4 |
|
4 |
|
||||||
vlib/v/checker/tests/void_fn_multiple_ret_err.vv:6:9: error: cannot use `none` as Result type in return argument
|
vlib/v/checker/tests/void_fn_multiple_ret_err.vv:6:2: error: Option and Result types have been split, use `?` to return none
|
||||||
4 |
|
4 |
|
||||||
5 | fn foo_result_2() ! {
|
5 | fn foo_result_2() ! {
|
||||||
6 | return none
|
6 | return none
|
||||||
| ~~~~
|
| ~~~~~~~~~~~
|
||||||
7 | }
|
7 | }
|
||||||
8 |
|
8 |
|
||||||
vlib/v/checker/tests/void_fn_multiple_ret_err.vv:14:9: error: cannot use `int literal` as Result type in return argument
|
vlib/v/checker/tests/void_fn_multiple_ret_err.vv:14:9: error: cannot use `int literal` as Result type in return argument
|
||||||
|
10
vlib/v/gen/c/testdata/for_in.vv
vendored
10
vlib/v/gen/c/testdata/for_in.vv
vendored
@ -4,12 +4,14 @@ mut:
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn new_custom_iter() CustomIter {
|
fn new_custom_iter() CustomIter {
|
||||||
return CustomIter{ idx: 0 }
|
return CustomIter{
|
||||||
|
idx: 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut a CustomIter) next() ?int {
|
fn (mut a CustomIter) next() ?int {
|
||||||
if a.idx == 4 {
|
if a.idx == 4 {
|
||||||
return error('')
|
return none
|
||||||
} else {
|
} else {
|
||||||
a.idx++
|
a.idx++
|
||||||
return a.idx * 2
|
return a.idx * 2
|
||||||
@ -18,10 +20,10 @@ fn (mut a CustomIter) next() ?int {
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
for x in new_custom_iter() {
|
for x in new_custom_iter() {
|
||||||
println('a.$x')
|
println('a.${x}')
|
||||||
}
|
}
|
||||||
for ix, val in new_custom_iter() {
|
for ix, val in new_custom_iter() {
|
||||||
println('b.$ix=$val')
|
println('b.${ix}=${val}')
|
||||||
}
|
}
|
||||||
println('end')
|
println('end')
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,7 @@ fn (it Companies) method() int {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn error_if_even(num int) ?int {
|
fn error_if_even(num int) !int {
|
||||||
if num % 2 == 0 {
|
if num % 2 == 0 {
|
||||||
return error('number is even')
|
return error('number is even')
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
module main
|
module main
|
||||||
|
|
||||||
fn test(f fn () ?) ? {
|
fn test(f fn () !) ! {
|
||||||
return error('test')
|
return error('test')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test1() ? {
|
fn test1() ! {
|
||||||
return error('test1')
|
return error('test1')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,7 +175,7 @@ fn option_str() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn return_error_with_freed_expr() ?string {
|
fn return_error_with_freed_expr() !string {
|
||||||
if true {
|
if true {
|
||||||
msg := 'oops'
|
msg := 'oops'
|
||||||
return error('hm ${msg}')
|
return error('hm ${msg}')
|
||||||
@ -357,7 +357,7 @@ fn return_sb_str() string {
|
|||||||
return sb.str() // sb should be freed, but only after .str() is called
|
return sb.str() // sb should be freed, but only after .str() is called
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_header0(s string) ?string {
|
fn parse_header0(s string) !string {
|
||||||
if !s.contains(':') {
|
if !s.contains(':') {
|
||||||
return error('missing colon in header')
|
return error('missing colon in header')
|
||||||
}
|
}
|
||||||
@ -366,7 +366,7 @@ fn parse_header0(s string) ?string {
|
|||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_header1(s string) ?string {
|
fn parse_header1(s string) !string {
|
||||||
if !s.contains(':') {
|
if !s.contains(':') {
|
||||||
return error('missing colon in header')
|
return error('missing colon in header')
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// TODO: remove this after the deprecation period for `?Type` representing both Result and Option passes.
|
// TODO: remove this after the deprecation period for `?Type` representing both Result and Option passes.
|
||||||
fn opt_err_with_code(code int) ?string {
|
fn opt_err_with_code(code int) !string {
|
||||||
return error_with_code('hi', code)
|
return error_with_code('hi', code)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ fn test_err_with_code() {
|
|||||||
_ := v
|
_ := v
|
||||||
}
|
}
|
||||||
|
|
||||||
fn opt_err() ?string {
|
fn opt_err() !string {
|
||||||
return error('hi')
|
return error('hi')
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ fn test_err() {
|
|||||||
println(v) // suppress not used error
|
println(v) // suppress not used error
|
||||||
}
|
}
|
||||||
|
|
||||||
fn err_call(ok bool) ?int {
|
fn err_call(ok bool) !int {
|
||||||
if !ok {
|
if !ok {
|
||||||
return error('Not ok!')
|
return error('Not ok!')
|
||||||
}
|
}
|
||||||
@ -79,7 +79,7 @@ fn test_if_else_opt() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn for_opt_default() ?string {
|
fn for_opt_default() !string {
|
||||||
return error('awww')
|
return error('awww')
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,7 +137,7 @@ fn or_return_val() int {
|
|||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
fn or_return_error() ?int {
|
fn or_return_error() !int {
|
||||||
a := ret_none() or { return error('Nope') }
|
a := ret_none() or { return error('Nope') }
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
@ -282,7 +282,7 @@ fn test_option_val_with_empty_or() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn test_option_void_return_types_of_anon_fn() {
|
fn test_option_void_return_types_of_anon_fn() {
|
||||||
f := fn (i int) ? {
|
f := fn (i int) ! {
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
return error('0')
|
return error('0')
|
||||||
}
|
}
|
||||||
@ -297,12 +297,12 @@ fn test_option_void_return_types_of_anon_fn() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Foo {
|
struct Foo {
|
||||||
f fn (int) ?
|
f fn (int) !
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_option_void_return_types_of_anon_fn_in_struct() {
|
fn test_option_void_return_types_of_anon_fn_in_struct() {
|
||||||
foo := Foo{
|
foo := Foo{
|
||||||
f: fn (i int) ? {
|
f: fn (i int) ! {
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
return error('0')
|
return error('0')
|
||||||
}
|
}
|
||||||
@ -327,7 +327,7 @@ struct CC {
|
|||||||
str string
|
str string
|
||||||
}
|
}
|
||||||
|
|
||||||
fn option_sum_type(a int) ?AA {
|
fn option_sum_type(a int) !AA {
|
||||||
match a {
|
match a {
|
||||||
1 {
|
1 {
|
||||||
return BB{'Test'}
|
return BB{'Test'}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user