mirror of
https://github.com/vlang/v.git
synced 2025-09-18 11:56:57 -04:00
ast, parser, fmt: fix alias array no cast init (#20898)
This commit is contained in:
parent
cf7dcfe287
commit
1733dab29b
@ -1492,6 +1492,7 @@ pub mut:
|
||||
elem_type Type // element type
|
||||
init_type Type // init: value type
|
||||
typ Type // array type
|
||||
alias_type Type // alias type
|
||||
}
|
||||
|
||||
pub struct ArrayDecompose {
|
||||
|
@ -1710,7 +1710,11 @@ pub fn (mut f Fmt) array_init(node ast.ArrayInit) {
|
||||
if node.exprs.len == 0 && node.typ != 0 && node.typ != ast.void_type {
|
||||
// `x := []string{}`
|
||||
f.mark_types_import_as_used(node.typ)
|
||||
if node.alias_type != ast.void_type {
|
||||
f.write(f.table.type_to_str_using_aliases(node.alias_type, f.mod2alias))
|
||||
} else {
|
||||
f.write(f.table.type_to_str_using_aliases(node.typ, f.mod2alias))
|
||||
}
|
||||
f.write('{')
|
||||
if node.has_len {
|
||||
f.write('len: ')
|
||||
|
@ -6,10 +6,9 @@ module parser
|
||||
import v.ast
|
||||
import v.token
|
||||
|
||||
fn (mut p Parser) array_init(is_option bool) ast.ArrayInit {
|
||||
fn (mut p Parser) array_init(is_option bool, alias_array_type ast.Type) ast.ArrayInit {
|
||||
first_pos := p.tok.pos()
|
||||
mut last_pos := p.tok.pos()
|
||||
p.check(.lsbr)
|
||||
mut array_type := ast.void_type
|
||||
mut elem_type := ast.void_type
|
||||
mut elem_type_pos := first_pos
|
||||
@ -22,13 +21,16 @@ fn (mut p Parser) array_init(is_option bool) ast.ArrayInit {
|
||||
mut has_init := false
|
||||
mut has_index := false
|
||||
mut init_expr := ast.empty_expr
|
||||
if alias_array_type == ast.void_type {
|
||||
p.check(.lsbr)
|
||||
if p.tok.kind == .rsbr {
|
||||
last_pos = p.tok.pos()
|
||||
// []typ => `[]` and `typ` must be on the same line
|
||||
line_nr := p.tok.line_nr
|
||||
p.next()
|
||||
// []string
|
||||
if p.tok.kind in [.name, .amp, .lsbr, .question, .key_shared] && p.tok.line_nr == line_nr {
|
||||
if p.tok.kind in [.name, .amp, .lsbr, .question, .key_shared]
|
||||
&& p.tok.line_nr == line_nr {
|
||||
elem_type_pos = p.tok.pos()
|
||||
elem_type = p.parse_type()
|
||||
// this is set here because it's a known type, others could be the
|
||||
@ -108,7 +110,8 @@ fn (mut p Parser) array_init(is_option bool) ast.ArrayInit {
|
||||
}
|
||||
if p.tok.kind == .not && p.tok.line_nr == p.prev_tok.line_nr {
|
||||
last_pos = p.tok.pos()
|
||||
p.error_with_pos('use e.g. `[1, 2, 3]!` instead of `[1, 2, 3]!!`', last_pos)
|
||||
p.error_with_pos('use e.g. `[1, 2, 3]!` instead of `[1, 2, 3]!!`',
|
||||
last_pos)
|
||||
p.next()
|
||||
}
|
||||
}
|
||||
@ -120,6 +123,11 @@ fn (mut p Parser) array_init(is_option bool) ast.ArrayInit {
|
||||
first_pos.extend(last_pos))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
array_type = (p.table.sym(alias_array_type).info as ast.Alias).parent_type
|
||||
elem_type = p.table.sym(array_type).array_info().elem_type
|
||||
p.next()
|
||||
}
|
||||
mut has_len := false
|
||||
mut has_cap := false
|
||||
mut len_expr := ast.empty_expr
|
||||
@ -170,6 +178,7 @@ fn (mut p Parser) array_init(is_option bool) ast.ArrayInit {
|
||||
mod: p.mod
|
||||
elem_type: elem_type
|
||||
typ: array_type
|
||||
alias_type: alias_array_type
|
||||
exprs: exprs
|
||||
ecmnts: ecmnts
|
||||
pre_cmnts: pre_cmnts
|
||||
|
@ -216,10 +216,10 @@ fn (mut p Parser) check_expr(precedence int) !ast.Expr {
|
||||
pos: pos
|
||||
}
|
||||
} else {
|
||||
node = p.array_init(false)
|
||||
node = p.array_init(false, ast.void_type)
|
||||
}
|
||||
} else {
|
||||
node = p.array_init(false)
|
||||
node = p.array_init(false, ast.void_type)
|
||||
}
|
||||
}
|
||||
.key_none {
|
||||
|
@ -2543,6 +2543,19 @@ fn (mut p Parser) is_generic_cast() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
fn (mut p Parser) alias_array_type() ast.Type {
|
||||
full_name := p.prepend_mod(p.tok.lit)
|
||||
if idx := p.table.type_idxs[full_name] {
|
||||
sym := p.table.sym(idx)
|
||||
if sym.info is ast.Alias {
|
||||
if p.table.sym(sym.info.parent_type).kind == .array {
|
||||
return idx
|
||||
}
|
||||
}
|
||||
}
|
||||
return ast.void_type
|
||||
}
|
||||
|
||||
@[direct_array_access]
|
||||
fn (mut p Parser) name_expr() ast.Expr {
|
||||
prev_tok_kind := p.prev_tok.kind
|
||||
@ -2840,7 +2853,13 @@ fn (mut p Parser) name_expr() ast.Expr {
|
||||
&& (!p.inside_match || (p.inside_select && prev_tok_kind == .arrow && lit0_is_capital))
|
||||
&& !p.inside_match_case && (!p.inside_if || p.inside_select)
|
||||
&& (!p.inside_for || p.inside_select) {
|
||||
return p.struct_init(p.mod + '.' + p.tok.lit, .normal, is_option) // short_syntax: false
|
||||
alias_array_type := p.alias_array_type()
|
||||
if alias_array_type != ast.void_type {
|
||||
return p.array_init(is_option, alias_array_type)
|
||||
} else {
|
||||
// `if a == Foo{} {...}` or `match foo { Foo{} {...} }`
|
||||
return p.struct_init(p.mod + '.' + p.tok.lit, .normal, is_option)
|
||||
}
|
||||
} else if p.peek_tok.kind == .lcbr
|
||||
&& ((p.inside_if && lit0_is_capital && p.tok.lit.len > 1 && !known_var && language == .v)
|
||||
|| (p.inside_match_case && p.tok.kind == .name && p.peek_tok.is_next_to(p.tok))) {
|
||||
@ -2957,7 +2976,7 @@ fn (mut p Parser) name_expr() ast.Expr {
|
||||
p.expr_mod = ''
|
||||
return node
|
||||
} else if is_option && p.tok.kind == .lsbr {
|
||||
return p.array_init(is_option)
|
||||
return p.array_init(is_option, ast.void_type)
|
||||
} else if !known_var && language == .v && p.peek_tok.kind == .dot && !p.pref.is_fmt {
|
||||
peek_tok2 := p.peek_token(2)
|
||||
peek_tok3 := p.peek_token(3)
|
||||
|
12
vlib/v/tests/alias_array_no_cast_init_test.v
Normal file
12
vlib/v/tests/alias_array_no_cast_init_test.v
Normal file
@ -0,0 +1,12 @@
|
||||
pub type Labels = [][]int
|
||||
|
||||
pub fn new_labels(width int, height int) Labels {
|
||||
mut labels := Labels{len: height, init: []int{len: width}}
|
||||
return labels
|
||||
}
|
||||
|
||||
fn test_alias_array_no_cast_init() {
|
||||
mut labels := new_labels(2, 2)
|
||||
println(labels)
|
||||
assert labels == [[0, 0], [0, 0]]
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user