From 202585e1755d942293d0a79cc4f889b46014c593 Mon Sep 17 00:00:00 2001 From: shove Date: Sun, 18 Sep 2022 23:08:33 +0800 Subject: [PATCH] checker, parser, fmt: fix visibility of anon struct in different modules.(fix #15763) (#15787) --- vlib/v/checker/struct.v | 5 +++-- vlib/v/checker/tests/anon_structs_visibility.out | 1 + .../checker/tests/anon_structs_visibility/amod/amod.v | 9 +++++++++ vlib/v/checker/tests/anon_structs_visibility/main.v | 10 ++++++++++ vlib/v/fmt/struct.v | 2 +- vlib/v/parser/struct.v | 5 ++++- 6 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 vlib/v/checker/tests/anon_structs_visibility.out create mode 100644 vlib/v/checker/tests/anon_structs_visibility/amod/amod.v create mode 100644 vlib/v/checker/tests/anon_structs_visibility/main.v diff --git a/vlib/v/checker/struct.v b/vlib/v/checker/struct.v index fbfcaef141..5fe5689589 100644 --- a/vlib/v/checker/struct.v +++ b/vlib/v/checker/struct.v @@ -290,8 +290,9 @@ pub fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type { && c.table.cur_concrete_types.len == 0 { pos := type_sym.name.last_index('.') or { -1 } first_letter := type_sym.name[pos + 1] - if !first_letter.is_capital() && type_sym.kind != .placeholder - && !type_sym.name.starts_with('main._VAnonStruct') { + if !first_letter.is_capital() + && (type_sym.kind != .struct_ || !(type_sym.info as ast.Struct).is_anon) + && type_sym.kind != .placeholder { c.error('cannot initialize builtin type `$type_sym.name`', node.pos) } } diff --git a/vlib/v/checker/tests/anon_structs_visibility.out b/vlib/v/checker/tests/anon_structs_visibility.out new file mode 100644 index 0000000000..38577f164d --- /dev/null +++ b/vlib/v/checker/tests/anon_structs_visibility.out @@ -0,0 +1 @@ +foo.bar.baz == 1 diff --git a/vlib/v/checker/tests/anon_structs_visibility/amod/amod.v b/vlib/v/checker/tests/anon_structs_visibility/amod/amod.v new file mode 100644 index 0000000000..e2b4901573 --- /dev/null +++ b/vlib/v/checker/tests/anon_structs_visibility/amod/amod.v @@ -0,0 +1,9 @@ +module amod + +pub struct Foo { +pub mut: + bar struct { + pub mut: + baz int + } +} diff --git a/vlib/v/checker/tests/anon_structs_visibility/main.v b/vlib/v/checker/tests/anon_structs_visibility/main.v new file mode 100644 index 0000000000..99efe553e5 --- /dev/null +++ b/vlib/v/checker/tests/anon_structs_visibility/main.v @@ -0,0 +1,10 @@ +import v.checker.tests.anon_structs_visibility.amod + +fn main() { + foo := amod.Foo{ + bar: struct { + baz: 1 + } + } + println('foo.bar.baz == $foo.bar.baz') +} diff --git a/vlib/v/fmt/struct.v b/vlib/v/fmt/struct.v index 52e5fa1a51..898a87be6e 100644 --- a/vlib/v/fmt/struct.v +++ b/vlib/v/fmt/struct.v @@ -8,7 +8,7 @@ import v.ast pub fn (mut f Fmt) struct_decl(node ast.StructDecl, is_anon bool) { f.attrs(node.attrs) - if node.is_pub { + if node.is_pub && !is_anon { f.write('pub ') } if node.is_union { diff --git a/vlib/v/parser/struct.v b/vlib/v/parser/struct.v index 8617a400b1..4c28097eb2 100644 --- a/vlib/v/parser/struct.v +++ b/vlib/v/parser/struct.v @@ -14,10 +14,13 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl { attrs := p.attrs p.attrs = [] start_pos := p.tok.pos() - is_pub := p.tok.kind == .key_pub + mut is_pub := p.tok.kind == .key_pub if is_pub { p.next() } + if is_anon { + is_pub = true + } is_union := p.tok.kind == .key_union if p.tok.kind == .key_struct { p.next()