Skip to content

Commit

Permalink
all: remove the obsolete .code and .msg fields of IError
Browse files Browse the repository at this point in the history
  • Loading branch information
yuyi98 committed Aug 17, 2024
1 parent ee16f6f commit ec50929
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 75 deletions.
14 changes: 1 addition & 13 deletions vlib/builtin/js/builtin.v
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ pub fn panic(s string) {

// IError holds information about an error instance
pub interface IError {
// >> Hack to allow old style custom error implementations
// TODO: remove once deprecation period for `IError` methods has ended
msg string
code int // <<
msg() string
code() int
}
Expand All @@ -35,15 +31,7 @@ pub fn (err IError) str() string {
err.str()
}
else {
// >> Hack to allow old style custom error implementations
// TODO: remove once deprecation period for `IError` methods has ended
old_error_style := unsafe { voidptr(&err.msg.str) != voidptr(&err.code.str) } // if fields are not defined (new style) they don't have an offset between them
if old_error_style {
'${err.type_name()}: ${err.msg}'
} else {
// <<
'${err.type_name()}: ${err.msg()}'
}
'${err.type_name()}: ${err.msg()}'
}
}
}
Expand Down
36 changes: 2 additions & 34 deletions vlib/v/checker/checker.v
Original file line number Diff line number Diff line change
Expand Up @@ -1098,16 +1098,6 @@ fn (mut c Checker) type_implements(typ ast.Type, interface_type ast.Type, pos to
// Verify methods
for imethod in imethods {
method := c.table.find_method_with_embeds(typ_sym, imethod.name) or {
// >> Hack to allow old style custom error implementations
// TODO: remove once deprecation period for `IError` methods has ended
if inter_sym.idx == ast.error_type_idx
&& (imethod.name == 'msg' || imethod.name == 'code') {
c.note("`${styp}` doesn't implement method `${imethod.name}` of interface `${inter_sym.name}`. The usage of fields is being deprecated in favor of methods.",
pos)
return false
}
// <<

typ_sym.find_method_with_generic_parent(imethod.name) or {
c.error("`${styp}` doesn't implement method `${imethod.name}` of interface `${inter_sym.name}`",
pos)
Expand Down Expand Up @@ -1150,16 +1140,8 @@ fn (mut c Checker) type_implements(typ ast.Type, interface_type ast.Type, pos to
}
// voidptr is an escape hatch, it should be allowed to be passed
if utyp != ast.voidptr_type && utyp != ast.nil_type {
// >> Hack to allow old style custom error implementations
// TODO: remove once deprecation period for `IError` methods has ended
if inter_sym.idx == ast.error_type_idx
&& (ifield.name == 'msg' || ifield.name == 'code') {
// do nothing, necessary warnings are already printed
} else {
// <<
c.error("`${styp}` doesn't implement field `${ifield.name}` of interface `${inter_sym.name}`",
pos)
}
c.error("`${styp}` doesn't implement field `${ifield.name}` of interface `${inter_sym.name}`",
pos)
}
}
if utyp != ast.voidptr_type && utyp != ast.nil_type && utyp != ast.none_type
Expand Down Expand Up @@ -1648,20 +1630,6 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
}
}

// >> Hack to allow old style custom error implementations
// TODO: remove once deprecation period for `IError` methods has ended
if sym.idx == ast.error_type_idx && !c.is_just_builtin_mod
&& (field_name == 'msg' || field_name == 'code') {
method := c.table.find_method(sym, field_name) or {
c.error('invalid `IError` interface implementation: ${err}', node.pos)
return ast.void_type
}
c.note('the `.${field_name}` field on `IError` is deprecated, and will be removed after 2022-06-01, use `.${field_name}()` instead.',
node.pos)
return method.return_type
}
// <<<

if has_field {
is_used_outside := sym.mod != c.mod
if is_used_outside && !field.is_pub && sym.language != .c {
Expand Down
12 changes: 9 additions & 3 deletions vlib/v/checker/tests/cast_to_interface_err.out
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
vlib/v/checker/tests/cast_to_interface_err.vv:20:9: notice: `CustomError` doesn't implement method `msg` of interface `IError`. The usage of fields is being deprecated in favor of methods.
18 |
vlib/v/checker/tests/cast_to_interface_err.vv:20:9: error: `CustomError` doesn't implement method `msg` of interface `IError`
18 |
19 | fn my_error() IError {
20 | return IError(CustomError{})
| ~~~~~~~~~~~~~~~~~~~~~
21 | }
vlib/v/checker/tests/cast_to_interface_err.vv:20:9: error: `CustomError` doesn't implement method `code` of interface `IError`
18 |
19 | fn my_error() IError {
20 | return IError(CustomError{})
| ~~~~~~~~~~~~~~~~~~~~~
21 | }
vlib/v/checker/tests/cast_to_interface_err.vv:20:9: error: `CustomError` does not implement interface `IError`, cannot cast `CustomError` to interface `IError`
18 |
18 |
19 | fn my_error() IError {
20 | return IError(CustomError{})
| ~~~~~~~~~~~~~~~~~~~~~
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,38 @@
vlib/v/checker/tests/infix_is_notis_interface_unimplemented_err.vv:8:14: notice: `int` doesn't implement method `msg` of interface `IError`. The usage of fields is being deprecated in favor of methods.
vlib/v/checker/tests/infix_is_notis_interface_unimplemented_err.vv:8:14: error: `int` doesn't implement method `msg` of interface `IError`
6 | if _ := f() {
7 | } else {
8 | _ = err is int
| ~~~
9 | }
10 |
vlib/v/checker/tests/infix_is_notis_interface_unimplemented_err.vv:12:14: notice: `int` doesn't implement method `msg` of interface `IError`. The usage of fields is being deprecated in favor of methods.
10 |
11 | _ = f() or {
12 | _ = err is int
vlib/v/checker/tests/infix_is_notis_interface_unimplemented_err.vv:8:14: error: `int` doesn't implement method `code` of interface `IError`
6 | if _ := f() {
7 | } else {
8 | _ = err is int
| ~~~
13 | 0
14 | }
9 | }
10 |
vlib/v/checker/tests/infix_is_notis_interface_unimplemented_err.vv:8:14: error: `int` doesn't implement interface `IError`
6 | if _ := f() {
7 | } else {
8 | _ = err is int
| ~~~
9 | }
10 |
vlib/v/checker/tests/infix_is_notis_interface_unimplemented_err.vv:12:14: error: `int` doesn't implement method `msg` of interface `IError`
10 |
11 | _ = f() or {
12 | _ = err is int
| ~~~
13 | 0
14 | }
vlib/v/checker/tests/infix_is_notis_interface_unimplemented_err.vv:12:14: error: `int` doesn't implement method `code` of interface `IError`
10 |
11 | _ = f() or {
12 | _ = err is int
| ~~~
13 | 0
14 | }
vlib/v/checker/tests/infix_is_notis_interface_unimplemented_err.vv:12:14: error: `int` doesn't implement interface `IError`
10 |
11 | _ = f() or {
Expand Down
31 changes: 22 additions & 9 deletions vlib/v/checker/tests/mut_receiver_wrong_return_type.out
Original file line number Diff line number Diff line change
@@ -1,25 +1,38 @@
vlib/v/checker/tests/mut_receiver_wrong_return_type.vv:4:2: notice: `&Test` doesn't implement method `msg` of interface `IError`. The usage of fields is being deprecated in favor of methods.
2 |
vlib/v/checker/tests/mut_receiver_wrong_return_type.vv:4:2: error: `&Test` doesn't implement method `msg` of interface `IError`
2 |
3 | fn (mut test Test) test() ?int {
4 | return test
| ~~~~~~~~~~~
5 | }
6 |
vlib/v/checker/tests/mut_receiver_wrong_return_type.vv:8:2: notice: `&Test` doesn't implement method `msg` of interface `IError`. The usage of fields is being deprecated in favor of methods.
6 |
7 | fn (mut test Test) test2() int {
8 | return test
vlib/v/checker/tests/mut_receiver_wrong_return_type.vv:4:2: error: `&Test` doesn't implement method `code` of interface `IError`
2 |
3 | fn (mut test Test) test() ?int {
4 | return test
| ~~~~~~~~~~~
9 | }
5 | }
6 |
vlib/v/checker/tests/mut_receiver_wrong_return_type.vv:4:9: error: cannot use `Test` as type `?int` in return argument
2 |
2 |
3 | fn (mut test Test) test() ?int {
4 | return test
| ~~~~
5 | }
6 |
vlib/v/checker/tests/mut_receiver_wrong_return_type.vv:8:2: error: `&Test` doesn't implement method `msg` of interface `IError`
6 |
7 | fn (mut test Test) test2() int {
8 | return test
| ~~~~~~~~~~~
9 | }
vlib/v/checker/tests/mut_receiver_wrong_return_type.vv:8:2: error: `&Test` doesn't implement method `code` of interface `IError`
6 |
7 | fn (mut test Test) test2() int {
8 | return test
| ~~~~~~~~~~~
9 | }
vlib/v/checker/tests/mut_receiver_wrong_return_type.vv:8:9: error: cannot use `Test` as type `int` in return argument
6 |
6 |
7 | fn (mut test Test) test2() int {
8 | return test
| ~~~~
Expand Down
9 changes: 0 additions & 9 deletions vlib/v/gen/c/cgen.v
Original file line number Diff line number Diff line change
Expand Up @@ -7873,15 +7873,6 @@ static inline __shared__${interface_name} ${shared_fn_name}(__shared__${cctype}*
}
}

// >> Hack to allow old style custom error implementations
// TODO: remove once deprecation period for `IError` methods has ended
// fix MSVC not handling empty struct inits
if methods.len == 0 && isym.idx == ast.error_type_idx {
methods_struct.writeln('\t\t._method_msg = NULL,')
methods_struct.writeln('\t\t._method_code = NULL,')
}
// <<

if g.pref.build_mode != .build_module {
methods_struct.writeln('\t},')
}
Expand Down

0 comments on commit ec50929

Please sign in to comment.