From a7879ce77ecdd674f03602978de8789f8a56d31b Mon Sep 17 00:00:00 2001 From: joe-conigliaro Date: Wed, 16 Dec 2020 18:03:49 +1100 Subject: [PATCH] parser: differentiate recursive alias & existing type err + rune fix --- vlib/builtin/rune.v | 5 +++- vlib/v/parser/parser.v | 27 +++++++++---------- .../tests/type_alias_existing_type_err.out | 7 +++++ .../tests/type_alias_existing_type_err.vv | 7 +++++ .../parser/tests/type_alias_same_type_err.out | 10 +++---- .../parser/tests/type_alias_same_type_err.vv | 2 -- vlib/v/table/types.v | 14 +++++----- 7 files changed, 41 insertions(+), 31 deletions(-) create mode 100644 vlib/v/parser/tests/type_alias_existing_type_err.out create mode 100644 vlib/v/parser/tests/type_alias_existing_type_err.vv diff --git a/vlib/builtin/rune.v b/vlib/builtin/rune.v index a3272b232b..f8d447fcca 100644 --- a/vlib/builtin/rune.v +++ b/vlib/builtin/rune.v @@ -2,7 +2,10 @@ // Use of this source code is governed by an MIT license that can be found in the LICENSE file. module builtin -type rune = int +// This was never working correctly, the issue is now +// fixed however the type checks in checker need to be +// updated. if you uncomment it you will see the issue +// type rune = int pub fn (c rune) str() string { return utf32_to_str(u32(c)) diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 95dc05625d..9a60cc5e80 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -2064,34 +2064,31 @@ fn (mut p Parser) type_decl() ast.TypeDecl { } // type MyType = int parent_type := first_type - parent_name := p.table.get_type_symbol(parent_type).name - pid := parent_type.idx() - mut language := table.Language.v - if parent_name.len > 2 && parent_name.starts_with('C.') { - language = table.Language.c - p.check_for_impure_v(language, decl_pos) - } else if parent_name.len > 2 && parent_name.starts_with('JS.') { - language = table.Language.js - p.check_for_impure_v(language, decl_pos) - } + parent_sym := p.table.get_type_symbol(parent_type) + pidx := parent_type.idx() + p.check_for_impure_v(parent_sym.language, decl_pos) prepend_mod_name := p.prepend_mod(name) - p.table.register_type_symbol(table.TypeSymbol{ + idx := p.table.register_type_symbol(table.TypeSymbol{ kind: .alias name: prepend_mod_name cname: util.no_dots(prepend_mod_name) mod: p.mod - parent_idx: pid + parent_idx: pidx info: table.Alias{ parent_type: parent_type - language: language + language: parent_sym.language } is_public: is_pub }) - comments = p.eat_line_end_comments() - if prepend_mod_name == parent_name { + if idx == -1 { + p.error_with_pos('cannot register alias `$name`, another type with this name exists', decl_pos.extend(type_alias_pos)) + return ast.AliasTypeDecl{} + } + if idx == pidx { p.error_with_pos('a type alias can not refer to itself: $name', decl_pos.extend(type_alias_pos)) return ast.AliasTypeDecl{} } + comments = p.eat_line_end_comments() return ast.AliasTypeDecl{ name: name is_pub: is_pub diff --git a/vlib/v/parser/tests/type_alias_existing_type_err.out b/vlib/v/parser/tests/type_alias_existing_type_err.out new file mode 100644 index 0000000000..6ea695f473 --- /dev/null +++ b/vlib/v/parser/tests/type_alias_existing_type_err.out @@ -0,0 +1,7 @@ +vlib/v/parser/tests/type_alias_existing_type_err.vv:3:1: error: cannot register alias `Foo`, another type with this name exists + 1 | struct Foo{} + 2 | + 3 | type Foo = Foo + | ~~~~~~~~~~~~~~ + 4 | + 5 | fn main() { diff --git a/vlib/v/parser/tests/type_alias_existing_type_err.vv b/vlib/v/parser/tests/type_alias_existing_type_err.vv new file mode 100644 index 0000000000..c1aeeed296 --- /dev/null +++ b/vlib/v/parser/tests/type_alias_existing_type_err.vv @@ -0,0 +1,7 @@ +struct Foo{} + +type Foo = Foo + +fn main() { + +} diff --git a/vlib/v/parser/tests/type_alias_same_type_err.out b/vlib/v/parser/tests/type_alias_same_type_err.out index 1cdf5f45a0..c5b3797b05 100644 --- a/vlib/v/parser/tests/type_alias_same_type_err.out +++ b/vlib/v/parser/tests/type_alias_same_type_err.out @@ -1,7 +1,5 @@ -vlib/v/parser/tests/type_alias_same_type_err.vv:3:1: error: a type alias can not refer to itself: Foo - 1 | struct Foo{} - 2 | - 3 | type Foo = Foo +vlib/v/parser/tests/type_alias_same_type_err.vv:1:1: error: a type alias can not refer to itself: Foo + 1 | type Foo = Foo | ~~~~~~~~~~~~~~ - 4 | - 5 | fn main() { + 2 | + 3 | fn main() { diff --git a/vlib/v/parser/tests/type_alias_same_type_err.vv b/vlib/v/parser/tests/type_alias_same_type_err.vv index c1aeeed296..4cf7265fdf 100644 --- a/vlib/v/parser/tests/type_alias_same_type_err.vv +++ b/vlib/v/parser/tests/type_alias_same_type_err.vv @@ -1,5 +1,3 @@ -struct Foo{} - type Foo = Foo fn main() { diff --git a/vlib/v/table/types.v b/vlib/v/table/types.v index 6b95e0a222..13b0d16ca5 100644 --- a/vlib/v/table/types.v +++ b/vlib/v/table/types.v @@ -309,11 +309,11 @@ pub const ( none_type_idx = 17 string_type_idx = 18 ustring_type_idx = 19 - array_type_idx = 20 - map_type_idx = 21 - chan_type_idx = 22 - sizet_type_idx = 23 - rune_type_idx = 24 + rune_type_idx = 20 + array_type_idx = 21 + map_type_idx = 22 + chan_type_idx = 23 + sizet_type_idx = 24 any_type_idx = 25 any_flt_type_idx = 26 any_int_type_idx = 27 @@ -353,10 +353,10 @@ pub const ( none_type = new_type(none_type_idx) string_type = new_type(string_type_idx) ustring_type = new_type(ustring_type_idx) + rune_type = new_type(rune_type_idx) array_type = new_type(array_type_idx) map_type = new_type(map_type_idx) chan_type = new_type(chan_type_idx) - rune_type = new_type(rune_type_idx) any_type = new_type(any_type_idx) any_flt_type = new_type(any_flt_type_idx) any_int_type = new_type(any_int_type_idx) @@ -517,11 +517,11 @@ pub fn (mut t Table) register_builtin_type_symbols() { t.register_type_symbol(kind: .none_, name: 'none', cname: 'none', mod: 'builtin') t.register_type_symbol(kind: .string, name: 'string', cname: 'string', mod: 'builtin') t.register_type_symbol(kind: .ustring, name: 'ustring', cname: 'ustring', mod: 'builtin') + t.register_type_symbol(kind: .rune, name: 'rune', cname: 'rune', mod: 'builtin') t.register_type_symbol(kind: .array, name: 'array', cname: 'array', mod: 'builtin') t.register_type_symbol(kind: .map, name: 'map', cname: 'map', mod: 'builtin') t.register_type_symbol(kind: .chan, name: 'chan', cname: 'chan', mod: 'builtin') t.register_type_symbol(kind: .size_t, name: 'size_t', cname: 'size_t', mod: 'builtin') - t.register_type_symbol(kind: .rune, name: 'rune', cname: 'rune', mod: 'builtin') t.register_type_symbol(kind: .any, name: 'any', cname: 'any', mod: 'builtin') t.register_type_symbol( kind: .any_float