diff --git a/vlib/v/builder/builder.v b/vlib/v/builder/builder.v index 0f1aefb0c2..8d50248309 100644 --- a/vlib/v/builder/builder.v +++ b/vlib/v/builder/builder.v @@ -235,6 +235,9 @@ fn (b &Builder) print_warnings_and_errors() { kind := if b.pref.is_verbose { '$err.reporter warning #$b.checker.nr_warnings:' } else { 'warning:' } ferror := util.formatted_error(kind, err.message, err.file_path, err.pos) eprintln(ferror) + if err.details.len > 0 { + eprintln('details: $err.details') + } // eprintln('') if i > b.max_nr_errors { return @@ -250,6 +253,9 @@ fn (b &Builder) print_warnings_and_errors() { kind := if b.pref.is_verbose { '$err.reporter error #$b.checker.nr_errors:' } else { 'error:' } ferror := util.formatted_error(kind, err.message, err.file_path, err.pos) eprintln(ferror) + if err.details.len > 0 { + eprintln('details: $err.details') + } // eprintln('') if i > b.max_nr_errors { return diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index 3736530158..a2d54cbf1c 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -143,11 +143,9 @@ pub fn (c &Checker) check_matching_function_symbols(got_type_sym &table.TypeSymb exp_arg_is_ptr := exp_arg.typ.is_ptr() || exp_arg.typ.is_pointer() got_arg_is_ptr := got_arg.typ.is_ptr() || got_arg.typ.is_pointer() if exp_arg_is_ptr != got_arg_is_ptr { - $if debug_matching_function_symbols ? { - exp_arg_pointedness := if exp_arg_is_ptr { 'a pointer' } else { 'NOT a pointer' } - got_arg_pointedness := if got_arg_is_ptr { 'a pointer' } else { 'NOT a pointer' } - eprintln('`$exp_fn.name` expected fn argument: `$exp_arg.name` is $exp_arg_pointedness, but `$got_fn.name` actual fn argument: `$got_arg.name` is $got_arg_pointedness') - } + exp_arg_pointedness := if exp_arg_is_ptr { 'a pointer' } else { 'NOT a pointer' } + got_arg_pointedness := if got_arg_is_ptr { 'a pointer' } else { 'NOT a pointer' } + c.add_error_detail('`$exp_fn.name`\'s expected fn argument: `$exp_arg.name` is $exp_arg_pointedness, but the passed fn argument: `$got_arg.name` is $got_arg_pointedness') return false } if !c.check_basic(got_arg.typ, exp_arg.typ) { diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 2f9c04e354..1d0256e322 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -43,6 +43,7 @@ mut: expr_level int // to avoid infinit recursion segfaults due to compiler bugs inside_sql bool // to handle sql table fields pseudo variables cur_orm_ts table.TypeSymbol + error_details []string } pub fn new_checker(table &table.Table, pref &pref.Preferences) Checker { @@ -2812,6 +2813,10 @@ pub fn (mut c Checker) map_init(mut node ast.MapInit) table.Type { return map_type } +pub fn (mut c Checker) add_error_detail(s string) { + c.error_details << s +} + pub fn (mut c Checker) warn(s string, pos token.Position) { allow_warnings := !c.pref.is_prod // allow warnings only in dev builds c.warn_or_error(s, pos, allow_warnings) // allow warnings only in dev builds @@ -2829,6 +2834,11 @@ fn (mut c Checker) warn_or_error(message string, pos token.Position, warn bool) // if c.pref.is_verbose { // print_backtrace() // } + mut details := '' + if c.error_details.len > 0 { + details = c.error_details.join('\n') + c.error_details = [] + } if warn && !c.pref.skip_warnings { c.nr_warnings++ wrn := errors.Warning{ @@ -2836,6 +2846,7 @@ fn (mut c Checker) warn_or_error(message string, pos token.Position, warn bool) pos: pos file_path: c.file.path message: message + details: details } c.file.warnings << wrn c.warnings << wrn @@ -2849,6 +2860,7 @@ fn (mut c Checker) warn_or_error(message string, pos token.Position, warn bool) pos: pos file_path: c.file.path message: message + details: details } c.file.errors << err c.errors << err diff --git a/vlib/v/checker/tests/non_matching_functional_args.out b/vlib/v/checker/tests/non_matching_functional_args.out index 8c823c43e9..146cf0145f 100644 --- a/vlib/v/checker/tests/non_matching_functional_args.out +++ b/vlib/v/checker/tests/non_matching_functional_args.out @@ -5,6 +5,7 @@ vlib/v/checker/tests/non_matching_functional_args.v:27:2: error: cannot use anon | ~~~~~~~~~~~~~~~~~~~~~~ 28 | t.rename() 29 | println(t.name) +details: `main.MyFn`'s expected fn argument: `zzzz` is NOT a pointer, but the passed fn argument: `t` is a pointer vlib/v/checker/tests/non_matching_functional_args.v:31:2: error: cannot use fn `xxx` as function type `MyFn` in argument 1 to `sum` 29 | println(t.name) 30 | }) @@ -12,3 +13,4 @@ vlib/v/checker/tests/non_matching_functional_args.v:31:2: error: cannot use fn ` | ~~~~~~~~ 32 | sum(yyy) 33 | } +details: `main.MyFn`'s expected fn argument: `zzzz` is NOT a pointer, but the passed fn argument: `mytable` is a pointer diff --git a/vlib/v/checker/tests/non_matching_functional_args.vv b/vlib/v/checker/tests/non_matching_functional_args.vv index 59ac7d05ee..a0e90ffd5e 100644 --- a/vlib/v/checker/tests/non_matching_functional_args.vv +++ b/vlib/v/checker/tests/non_matching_functional_args.vv @@ -13,9 +13,9 @@ fn yyy(t Table) { println(t.name) } -fn xxx(mut t Table) { - t.rename() - println(t.name) +fn xxx(mut mytable Table) { + mytable.rename() + println(mytable.name) } fn sum(myfn MyFn) { diff --git a/vlib/v/errors/errors.v b/vlib/v/errors/errors.v index 5aadd9229e..6b342fd507 100644 --- a/vlib/v/errors/errors.v +++ b/vlib/v/errors/errors.v @@ -12,6 +12,7 @@ pub enum Reporter { pub struct Error { pub: message string + details string file_path string pos token.Position backtrace string @@ -21,6 +22,7 @@ pub: pub struct Warning { pub: message string + details string file_path string pos token.Position reporter Reporter