checker: make using err.msg and err.code produce an *actual* notice, even with the present compatibility hack (will be *removed* in 2022-06-01)

pull/14006/head
Delyan Angelov 2022-04-12 13:38:40 +03:00
parent 4c7cdd2a2d
commit 8788512c4d
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
28 changed files with 107 additions and 100 deletions

View File

@ -77,7 +77,7 @@ fn (context Context) bname_and_bytes(file string) ?(string, []byte) {
fname := os.file_name(file)
fname_escaped := fname.replace_each(['.', '_', '-', '_'])
byte_name := '$context.prefix$fname_escaped'.to_lower()
fbytes := os.read_bytes(file) or { return error('Error: $err.msg') }
fbytes := os.read_bytes(file) or { return error('Error: $err.msg()') }
return byte_name, fbytes
}
@ -108,7 +108,7 @@ fn main() {
exit(0)
}
files := fp.finalize() or {
eprintln('Error: $err.msg')
eprintln('Error: $err.msg()')
exit(1)
}
real_files := files.filter(it != 'bin2v')
@ -123,7 +123,7 @@ fn main() {
mut file_byte_map := map[string][]byte{}
for file in real_files {
bname, fbytes := context.bname_and_bytes(file) or {
eprintln(err.msg)
eprintln(err.msg())
exit(1)
}
file_byte_map[bname] = fbytes

View File

@ -66,8 +66,9 @@ fn main() {
}
target_path := os.join_path(tfolder, texe)
os.mv_by_cp(tpath, target_path) or {
if !err.msg.contains('vbuild-tools') && !err.msg.contains('vtest-all') {
eprintln('error while moving $tpath to $target_path: $err.msg')
emsg := err.msg()
if !emsg.contains('vbuild-tools') && !emsg.contains('vtest-all') {
eprintln('error while moving $tpath to $target_path: $emsg')
}
continue
}

View File

@ -244,8 +244,8 @@ fn (vd VDoc) get_readme(path string) string {
fn (vd VDoc) emit_generate_err(err IError) {
cfg := vd.cfg
mut err_msg := err.msg
if err.code == 1 {
mut err_msg := err.msg()
if err.code() == 1 {
mod_list := get_modules_list(cfg.input_path, []string{})
println('Available modules:\n==================')
for mod in mod_list {
@ -467,7 +467,7 @@ fn parse_arguments(args []string) Config {
exit(1)
}
selected_platform := doc.platform_from_string(platform_str) or {
eprintln(err.msg)
eprintln(err.msg())
exit(1)
}
cfg.platform = selected_platform

View File

@ -82,7 +82,7 @@ fn main() {
eprintln('vfmt possible_files: ' + possible_files.str())
}
files := util.find_all_v_files(possible_files) or {
verror(err.msg)
verror(err.msg())
return
}
if os.is_atty(0) == 0 && files.len == 0 {

View File

@ -211,7 +211,7 @@ fn generate_screenshots(mut opt Options, output_path string) ? {
app_config.screenshots_path = screenshot_path
app_config.screenshots = take_screenshots(opt, app_config) or {
return error('Failed taking screenshots of `$app_path`:\n$err.msg')
return error('Failed taking screenshots of `$app_path`:\n$err.msg()')
}
}
}

View File

@ -485,7 +485,7 @@ fn vpm_remove(module_names []string) {
println('Removing module "$name" ...')
verbose_println('removing folder $final_module_path')
os.rmdir_all(final_module_path) or {
verbose_println('error while removing "$final_module_path": $err.msg')
verbose_println('error while removing "$final_module_path": $err.msg()')
}
// delete author directory if it is empty
author := name.split('.')[0]
@ -496,7 +496,7 @@ fn vpm_remove(module_names []string) {
if os.is_dir_empty(author_dir) {
verbose_println('removing author folder $author_dir')
os.rmdir(author_dir) or {
verbose_println('error while removing "$author_dir": $err.msg')
verbose_println('error while removing "$author_dir": $err.msg()')
}
}
}

View File

@ -30,7 +30,7 @@ fn main() {
// The user just wants an independent copy of v, and so we are done.
return
}
backup_old_version_and_rename_newer(short_v_name) or { panic(err.msg) }
backup_old_version_and_rename_newer(short_v_name) or { panic(err.msg()) }
println('V built successfully as executable "$vexe_name".')
}
@ -71,17 +71,17 @@ fn backup_old_version_and_rename_newer(short_v_name string) ?bool {
list_folder(short_v_name, 'before:', 'removing $bak_file ...')
if os.exists(bak_file) {
os.rm(bak_file) or { errors << 'failed removing $bak_file: $err.msg' }
os.rm(bak_file) or { errors << 'failed removing $bak_file: $err.msg()' }
}
list_folder(short_v_name, '', 'moving $v_file to $bak_file ...')
os.mv(v_file, bak_file) or { errors << err.msg }
os.mv(v_file, bak_file) or { errors << err.msg() }
list_folder(short_v_name, '', 'removing $v_file ...')
os.rm(v_file) or {}
list_folder(short_v_name, '', 'moving $v2_file to $v_file ...')
os.mv_by_cp(v2_file, v_file) or { panic(err.msg) }
os.mv_by_cp(v2_file, v_file) or { panic(err.msg()) }
list_folder(short_v_name, 'after:', '')

View File

@ -106,7 +106,7 @@ fn setup_symlink_windows(vexe string) {
println('Symlink $vsymlink to $vexe created.')
println('Checking system %PATH%...')
reg_sys_env_handle := get_reg_sys_env_handle() or {
warn_and_exit(err.msg)
warn_and_exit(err.msg())
return
}
// TODO: Fix defers inside ifs
@ -133,7 +133,7 @@ fn setup_symlink_windows(vexe string) {
println('Adding symlink directory to system %PATH%...')
set_reg_value(reg_sys_env_handle, 'Path', new_sys_env_path) or {
C.RegCloseKey(reg_sys_env_handle)
warn_and_exit(err.msg)
warn_and_exit(err.msg())
}
println('Done.')
}

View File

@ -121,7 +121,7 @@ fn process_cli_args() &Context {
exit(0)
}
context.all_paths = fp.finalize() or {
context.error(err.msg)
context.error(err.msg())
exit(1)
}
if !context.is_worker && context.all_paths.len == 0 {

View File

@ -124,9 +124,9 @@ fn (app App) show_current_v_version() {
fn (app App) backup(file string) {
backup_file := '${file}_old.exe'
if os.exists(backup_file) {
os.rm(backup_file) or { eprintln('failed removing $backup_file: $err.msg') }
os.rm(backup_file) or { eprintln('failed removing $backup_file: $err.msg()') }
}
os.mv(file, backup_file) or { eprintln('failed moving $file: $err.msg') }
os.mv(file, backup_file) or { eprintln('failed moving $file: $err.msg()') }
}
fn (app App) git_command(command string) {

View File

@ -1863,7 +1863,7 @@ import os
fn read_log() {
mut ok := false
mut f := os.open('log.txt') or { panic(err.msg) }
mut f := os.open('log.txt') or { panic(err) }
defer {
f.close()
}
@ -3452,7 +3452,7 @@ to break from the current block.
Note that `break` and `continue` can only be used inside a `for` loop.
V does not have a way to forcibly "unwrap" an optional (as other languages do,
for instance Rust's `unwrap()` or Swift's `!`). To do this, use `or { panic(err.msg) }` instead.
for instance Rust's `unwrap()` or Swift's `!`). To do this, use `or { panic(err) }` instead.
---
The third method is to provide a default value at the end of the `or` block.
@ -5536,7 +5536,7 @@ eprintln('file: ' + @FILE + ' | line: ' + @LINE + ' | fn: ' + @MOD + '.' + @FN)
Another example, is if you want to embed the version/name from v.mod *inside* your executable:
```v ignore
import v.vmod
vm := vmod.decode( @VMOD_FILE ) or { panic(err.msg) }
vm := vmod.decode( @VMOD_FILE ) or { panic(err) }
eprintln('$vm.name $vm.version\n $vm.description')
```

View File

@ -13,14 +13,14 @@ mkdir('v_script_dir') ?
println("\nEntering into v_script_dir and listing it's files.")
chdir('v_script_dir') ?
files := ls('.') or { panic(err.msg) }
files := ls('.') or { panic(err) }
println(files)
println('\nCreating foo.txt')
create('foo.txt') ?
println('\nFiles:')
again_ls := ls('.') or { panic(err.msg) }
again_ls := ls('.') or { panic(err) }
println(again_ls)
println('\nRemoving foo.txt and v_script_dir')

View File

@ -170,7 +170,7 @@ fn new_key_from_seed_generic(mut privatekey []byte, seed []byte) {
mut h := sha512.sum512(seed)
mut s := edwards25519.new_scalar()
s.set_bytes_with_clamping(h[..32]) or { panic(err.msg) }
s.set_bytes_with_clamping(h[..32]) or { panic(err) }
mut aa := edwards25519.Point{}
aa.scalar_base_mult(mut s)

View File

@ -8,11 +8,11 @@ import crypto.ed25519
fn main() {
msg := 'Hello Girl'
publ, priv := ed25519.generate_key() or { panic(err.msg) }
publ, priv := ed25519.generate_key() ?
m := msg.bytes()
sig := ed25519.sign(priv, m) or { panic(err.msg) }
sig := ed25519.sign(priv, m) ?
println('=== Message ===')
println('Msg: $msg \nHash: $m')
@ -31,7 +31,7 @@ fn main() {
println('signature: R=${sig[0..32].hex()} s=${sig[32..64].hex()}')
println(' signature (Base64)=${base64.encode(sig)}')
rtn := ed25519.verify(publ, m, sig) or { panic(err.msg) }
rtn := ed25519.verify(publ, m, sig) ?
if rtn {
println('Signature verified :$rtn')

View File

@ -85,10 +85,10 @@ fn works_check_on_sign_input_string(item string) bool {
return false
}
// assert parts.len == 5
privbytes := hex.decode(parts[0]) or { panic(err.msg) }
pubkey := hex.decode(parts[1]) or { panic(err.msg) }
msg := hex.decode(parts[2]) or { panic(err.msg) }
mut sig := hex.decode(parts[3]) or { panic(err.msg) }
privbytes := hex.decode(parts[0]) or { panic(err) }
pubkey := hex.decode(parts[1]) or { panic(err) }
msg := hex.decode(parts[2]) or { panic(err) }
mut sig := hex.decode(parts[3]) or { panic(err) }
if pubkey.len != ed25519.public_key_size {
return false
@ -100,12 +100,12 @@ fn works_check_on_sign_input_string(item string) bool {
copy(mut priv[..], privbytes)
copy(mut priv[32..], pubkey)
sig2 := ed25519.sign(priv[..], msg) or { panic(err.msg) }
sig2 := ed25519.sign(priv[..], msg) or { panic(err) }
if sig != sig2[..] {
return false
}
res := ed25519.verify(pubkey, msg, sig2) or { panic(err.msg) }
res := ed25519.verify(pubkey, msg, sig2) or { panic(err) }
// assert res == true
if !res {
return false
@ -150,7 +150,7 @@ mut:
// so, maybe need a long time to finish.
// be quiet and patient
fn test_input_from_djb_ed25519_crypto_sign_input_with_syncpool() ? {
// contents := os.read_lines('testdata/sign.input') or { panic(err.msg) } //[]string
// contents := os.read_lines('testdata/sign.input') or { panic(err) } //[]string
mut pool_s := pool.new_pool_processor(
callback: worker_for_string_content
maxjobs: 4
@ -165,7 +165,7 @@ fn test_input_from_djb_ed25519_crypto_sign_input_with_syncpool() ? {
// same as above, but without sync.pool
/*
fn test_input_from_djb_ed25519_crypto_sign_input_without_syncpool() ? {
// contents := os.read_lines('testdata/sign.input') or { panic(err.msg) } //[]string
// contents := os.read_lines('testdata/sign.input') or { panic(err) } //[]string
for i, item in ed25519.contents {
parts := item.split(':') // []string
// println(parts)

View File

@ -387,11 +387,11 @@ fn test_bytes_big_equivalence() ? {
mut fe := el.generate_element()
mut fe1 := el.generate_element()
fe.set_bytes(inp) or { panic(err.msg) }
fe.set_bytes(inp) or { panic(err) }
inp[inp.len - 1] &= (1 << 7) - 1 // mask the most significant bit
mut b := big.integer_from_bytes(swap_endianness(mut inp)) // need swap_endianness
fe1.from_big_integer(b) or { panic(err.msg) } // do swap_endianness internally
fe1.from_big_integer(b) or { panic(err) } // do swap_endianness internally
assert fe == fe1

View File

@ -67,20 +67,20 @@ fn test_bytes_montgomery_infinity() {
const (
loworder_string = '26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85'
loworder_bytes = hex.decode(loworder_string) or { panic(err.msg) }
loworder_bytes = hex.decode(loworder_string) or { panic(err) }
)
fn fn_cofactor(mut data []byte) bool {
if data.len != 64 {
panic('err.msg')
panic('data.len should be 64')
}
mut loworder := Point{}
loworder.set_bytes(edwards25519.loworder_bytes) or { panic(err.msg) }
loworder.set_bytes(edwards25519.loworder_bytes) or { panic(err) }
mut s := new_scalar()
mut p := Point{}
mut p8 := Point{}
s.set_uniform_bytes(data) or { panic(err.msg) }
s.set_uniform_bytes(data) or { panic(err) }
p.scalar_base_mult(mut s)
p8.mult_by_cofactor(p)
@ -128,8 +128,8 @@ fn invert_works(mut xinv Scalar, x NotZeroScalar) bool {
}
fn test_scalar_invert() {
nsc := generate_notzero_scalar(5) or { panic(err.msg) }
mut xsc := generate_scalar(5) or { panic(err.msg) }
nsc := generate_notzero_scalar(5) or { panic(err) }
mut xsc := generate_scalar(5) or { panic(err) }
assert invert_works(mut xsc, nsc) == true
mut zero := new_scalar()
@ -140,9 +140,9 @@ fn test_scalar_invert() {
fn test_multiscalarmultmatchesbasemult() {
for i in 0 .. 6 {
x := generate_scalar(100) or { panic(err.msg) }
y := generate_scalar(5) or { panic(err.msg) }
z := generate_scalar(2) or { panic(err.msg) }
x := generate_scalar(100) or { panic(err) }
y := generate_scalar(5) or { panic(err) }
z := generate_scalar(2) or { panic(err) }
assert multiscalarmultmatchesbasemult(x, y, z) == true
}
}
@ -196,9 +196,9 @@ fn vartime_multiscala_rmultmatches_basemult(xx Scalar, yy Scalar, zz Scalar) boo
fn test_vartimemultiscalarmultmatchesbasemult() {
for i in 0 .. 5 {
x := generate_scalar(100) or { panic(err.msg) }
y := generate_scalar(5) or { panic(err.msg) }
z := generate_scalar(2) or { panic(err.msg) }
x := generate_scalar(100) or { panic(err) }
y := generate_scalar(5) or { panic(err) }
z := generate_scalar(2) or { panic(err) }
assert vartime_multiscala_rmultmatches_basemult(x, y, z) == true
}
}

View File

@ -10,12 +10,12 @@ const (
gen_bytes = [byte(0x58), 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x66, 0x66, 0x66, 0x66, 0x66]
d_const = d_const_generate() or { panic(err.msg) }
d2_const = d2_const_generate() or { panic(err.msg) }
d_const = d_const_generate() or { panic(err) }
d2_const = d2_const_generate() or { panic(err) }
// id_point is the point at infinity.
id_point = id_point_generate() or { panic(err.msg) }
id_point = id_point_generate() or { panic(err) }
// generator point
gen_point = generator() or { panic(err.msg) }
gen_point = generator() or { panic(err) }
)
fn d_const_generate() ?Element {

View File

@ -58,8 +58,8 @@ fn addlike_subneg(x Scalar, y Scalar) bool {
fn test_scalar_add_like_subneg() {
for i in 0 .. 15 {
x := generate_scalar(1000) or { panic(err.msg) }
y := generate_scalar(1000) or { panic(err.msg) }
x := generate_scalar(1000) or { panic(err) }
y := generate_scalar(1000) or { panic(err) }
assert addlike_subneg(x, y) == true
}
}
@ -70,7 +70,7 @@ fn fg(sc Scalar) bool {
fn test_scalar_generate() ? {
for i in 0 .. 15 {
sc := generate_scalar(1000) or { panic(err.msg) }
sc := generate_scalar(1000) or { panic(err) }
assert fg(sc) == true
}
@ -79,10 +79,10 @@ fn test_scalar_generate() ? {
//
fn test_scalar_set_canonical_bytes() ? {
for i in 0 .. 10 {
mut buf := rand.bytes(32) or { panic(err.msg) }
mut sc := generate_scalar(1000) or { panic(err.msg) }
mut buf := rand.bytes(32) or { panic(err) }
mut sc := generate_scalar(1000) or { panic(err) }
buf[buf.len - 1] &= (1 << 4) - 1
sc = sc.set_canonical_bytes(buf) or { panic(err.msg) }
sc = sc.set_canonical_bytes(buf) or { panic(err) }
assert buf[..] == sc.bytes()
assert is_reduced(sc)
@ -93,7 +93,7 @@ fn test_scalar_set_canonical_bytes_round_trip() ? {
for i in 0 .. 10 {
mut sc1 := generate_scalar(2) ?
mut sc2 := generate_scalar(6) ?
sc2.set_canonical_bytes(sc1.bytes()) or { panic(err.msg) }
sc2.set_canonical_bytes(sc1.bytes()) or { panic(err) }
assert sc1 == sc2
}
@ -152,10 +152,10 @@ fn test_scalar_set_bytes_with_clamping() {
t.Errorf("random: got %q, want %q", got, want)
}*/
random := '633d368491364dc9cd4c1bf891b1d59460face1644813240a313e61f2c88216e'
random_bytes := hex.decode(random) or { panic(err.msg) }
random_bytes := hex.decode(random) or { panic(err) }
mut s0 := Scalar{}
s0.set_bytes_with_clamping(random_bytes) or { panic(err.msg) }
s0.set_bytes_with_clamping(random_bytes) or { panic(err) }
mut p0 := Point{}
p0.scalar_base_mult(mut s0)
@ -167,8 +167,8 @@ fn test_scalar_set_bytes_with_clamping() {
zero := '0000000000000000000000000000000000000000000000000000000000000000'
mut s1 := Scalar{}
zero_bytes := hex.decode(zero) or { panic(err.msg) }
s1.set_bytes_with_clamping(zero_bytes) or { panic(err.msg) }
zero_bytes := hex.decode(zero) or { panic(err) }
s1.set_bytes_with_clamping(zero_bytes) or { panic(err) }
mut p1 := Point{}
p1.scalar_base_mult(mut s1)
@ -178,8 +178,8 @@ fn test_scalar_set_bytes_with_clamping() {
one := 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
mut s2 := Scalar{}
mut one_bytes := hex.decode(one) or { panic(err.msg) }
s2.set_bytes_with_clamping(one_bytes) or { panic(err.msg) }
mut one_bytes := hex.decode(one) or { panic(err) }
s2.set_bytes_with_clamping(one_bytes) or { panic(err) }
mut p2 := Point{}
p2.scalar_base_mult(mut s2)

View File

@ -10,7 +10,7 @@ const (
fn dalek_scalar_basepoint() Point {
mut p := Point{}
p.set_bytes(edwards25519.dsc_basepoint) or { panic(err.msg) }
p.set_bytes(edwards25519.dsc_basepoint) or { panic(err) }
return p
}
@ -70,8 +70,8 @@ fn test_vartime_double_basemult_vs_dalek() {
}
fn test_scalar_mult_distributes_over_add() {
mut x := generate_scalar(100) or { panic(err.msg) }
mut y := generate_scalar(100) or { panic(err.msg) }
mut x := generate_scalar(100) or { panic(err) }
mut y := generate_scalar(100) or { panic(err) }
mut z := Scalar{}
z.add(x, y)
@ -142,7 +142,7 @@ fn test_basepoint_table_generation() {
}
fn test_scalar_mult_matches_base_mult() {
mut x := generate_scalar(100) or { panic(err.msg) }
mut x := generate_scalar(100) or { panic(err) }
b := new_generator_point()
mut p := Point{}
mut q := Point{}
@ -165,8 +165,8 @@ fn test_basepoint_naf_table_generation() {
}
fn test_vartime_double_scalar_base_mult() {
mut x := generate_scalar(100) or { panic(err.msg) }
mut y := generate_scalar(100) or { panic(err.msg) }
mut x := generate_scalar(100) or { panic(err) }
mut y := generate_scalar(100) or { panic(err) }
b := new_generator_point()
mut p := Point{}

View File

@ -74,7 +74,7 @@ fn select_with_retry(handle int, test Select, timeout time.Duration) ?bool {
mut retries := 10
for retries > 0 {
ready := @select(handle, test, timeout) or {
if err.code == 4 {
if err.code() == 4 {
// signal! lets retry max 10 times
// suspend thread with sleep to let the gc get
// cycles in the case the Bohem gc is interupting

View File

@ -15,7 +15,7 @@ fn (mut ws Client) socket_read(mut buffer []byte) ?int {
} else {
for {
r := ws.conn.read(mut buffer) or {
if err.code == net.err_timed_out_code {
if err.code() == net.err_timed_out_code {
continue
}
return err
@ -39,7 +39,7 @@ fn (mut ws Client) socket_read_ptr(buf_ptr &byte, len int) ?int {
} else {
for {
r := ws.conn.read_ptr(buf_ptr, len) or {
if err.code == net.err_timed_out_code {
if err.code() == net.err_timed_out_code {
continue
}
return err
@ -63,7 +63,7 @@ fn (mut ws Client) socket_write(bytes []byte) ?int {
} else {
for {
n := ws.conn.write(bytes) or {
if err.code == net.err_timed_out_code {
if err.code() == net.err_timed_out_code {
continue
}
return err

View File

@ -21,7 +21,7 @@ fn test_signal_opt_invalid_argument() {
}
os.signal_opt(.kill, default_handler) or {
assert err.msg() == 'Invalid argument'
assert err.code == 22
assert err.code() == 22
}
}

View File

@ -82,6 +82,7 @@ pub mut:
returns bool
scope_returns bool
is_builtin_mod bool // true inside the 'builtin', 'os' or 'strconv' modules; TODO: remove the need for special casing this
is_just_builtin_mod bool // true only inside 'builtin'
is_generated bool // true for `[generated] module xyz` .v files
inside_unsafe bool // true inside `unsafe {}` blocks
inside_const bool // true inside `const ( ... )` blocks
@ -149,6 +150,7 @@ fn (mut c Checker) reset_checker_state_at_start_of_new_file() {
c.scope_returns = false
c.mod = ''
c.is_builtin_mod = false
c.is_just_builtin_mod = false
c.inside_unsafe = false
c.inside_const = false
c.inside_anon_fn = false
@ -1721,6 +1723,21 @@ pub 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 {
if sym.mod != c.mod && !field.is_pub && sym.language != .c {
unwrapped_sym := c.table.sym(c.unwrap_generic(typ))
@ -1758,19 +1775,6 @@ pub fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
c.error(suggestion.say(unknown_field_msg), node.pos)
return ast.void_type
}
// >> Hack to allow old style custom error implementations
// TODO: remove once deprecation period for `IError` methods has ended
if sym.name == 'IError' && (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, use `.${field_name}()` instead.',
node.pos)
return method.return_type
}
// <<<
if c.smartcast_mut_pos != token.Pos{} {
c.note('smartcasting requires either an immutable value, or an explicit mut keyword before the value',
c.smartcast_mut_pos)
@ -2041,7 +2045,8 @@ fn (mut c Checker) stmt(node_ ast.Stmt) {
}
ast.Module {
c.mod = node.name
c.is_builtin_mod = node.name in ['builtin', 'os', 'strconv']
c.is_just_builtin_mod = node.name == 'builtin'
c.is_builtin_mod = c.is_just_builtin_mod || node.name in ['os', 'strconv']
c.check_valid_snake_case(node.name, 'module name', node.pos)
}
ast.Return {

View File

@ -4,7 +4,7 @@ fn test_error_can_be_converted_to_string() {
fn test_error_can_be_assigned_to_a_variable() {
f := error('an error')
assert 'an error' == f.msg
assert 'an error' == f.msg()
}
fn test_error_can_be_printed() {

View File

@ -8,11 +8,11 @@ fn test_err_with_code() {
_ := w
} else {
assert err.msg() == 'hi'
assert err.code == 137
assert err.code() == 137
}
v := opt_err_with_code() or {
assert err.msg() == 'hi'
assert err.code == 137
assert err.code() == 137
return
}
assert false

View File

@ -5,7 +5,7 @@ pub mut:
fn delete_secret_v1() API_error {
response := req_do() or {
match err.msg {
match err.msg() {
'dial_tcp failed' {
return API_error{
errors: ['Vault server not started']
@ -13,7 +13,7 @@ fn delete_secret_v1() API_error {
}
else {
return API_error{
errors: [err.msg]
errors: [err.msg()]
}
}
}

View File

@ -393,7 +393,8 @@ pub struct RunParams {
[manualfree]
pub fn run_at<T>(global_app &T, params RunParams) ? {
mut l := net.listen_tcp(params.family, '$params.host:$params.port') or {
return error('failed to listen $err.code $err')
ecode := err.code()
return error('failed to listen $ecode $err')
}
// Parsing methods attributes