Skip to content

Commit 9828cd8

Browse files
committed
parser: show where another declaration is located (fixes #26483)
1 parent 7ad51d4 commit 9828cd8

3 files changed

Lines changed: 42 additions & 2 deletions

File tree

vlib/v/parser/struct.v

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
module parser
55

66
import v.ast
7+
import v.errors
78
import v.token
89
import v.util
910

@@ -479,8 +480,35 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
479480
}
480481
// allow duplicate c struct declarations
481482
if ret == -1 && language != .c && !p.pref.is_fmt {
482-
p.error_with_pos('cannot register struct `${name}`, another type with this name exists',
483-
name_pos)
483+
msg := 'cannot register struct `${name}`, another type with this name exists'
484+
mut existing_sym, mut existing_idx := p.table.find_sym_and_type_idx(name)
485+
if existing_idx <= 0 && name.starts_with('main.') {
486+
existing_sym, existing_idx = p.table.find_sym_and_type_idx(name.trim_string_left('main.'))
487+
}
488+
if existing_idx > 0 {
489+
if existing_name_pos := existing_sym.info.get_name_pos() {
490+
existing_file_path := if existing_name_pos.file_idx < 0 {
491+
p.file_path
492+
} else {
493+
p.table.filelist[existing_name_pos.file_idx]
494+
}
495+
error_file_path := if name_pos.file_idx < 0 {
496+
p.file_path
497+
} else {
498+
p.table.filelist[name_pos.file_idx]
499+
}
500+
p.error_with_error(errors.Error{
501+
file_path: error_file_path
502+
pos: name_pos
503+
reporter: .parser
504+
message: msg
505+
details: util.formatted_error('details:', 'another declaration was found here',
506+
existing_file_path, existing_name_pos)
507+
})
508+
return ast.StructDecl{}
509+
}
510+
}
511+
p.error_with_pos(msg, name_pos)
484512
return ast.StructDecl{}
485513
}
486514
p.expr_mod = ''

vlib/v/parser/tests/duplicate_type_b.out

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,8 @@ vlib/v/parser/tests/duplicate_type_b.vv:3:8: error: cannot register struct `Foo`
33
2 |
44
3 | struct Foo {}
55
| ~~~
6+
Details: vlib/v/parser/tests/duplicate_type_b.vv:1:1: details: another declaration was found here
7+
1 | interface Foo {}
8+
| ^
9+
2 |
10+
3 | struct Foo {}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
11
vlib/v/parser/tests/prohibit_redeclaration_of_builtin_types.vv:1:8: error: cannot register struct `Option`, another type with this name exists
22
1 | struct Option {}
33
| ~~~~~~
4+
Details: vlib/builtin/chan_option_result.v:142:8: details: another declaration was found here
5+
140 |
6+
141 | // Option is the base of V's internal option return system.
7+
142 | struct Option {
8+
| ~~~~~~
9+
143 | state u8 // 0 - ok; 2 - none; 1 - ?
10+
144 | err IError = none__

0 commit comments

Comments
 (0)