mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen, checker: fix indexexpr with sumtype of array types (#18515)
This commit is contained in:
parent
4c9c515f8b
commit
2abd2e2c2a
@ -4035,8 +4035,8 @@ fn (mut c Checker) type_error_for_operator(op_label string, types_label string,
|
||||
}
|
||||
|
||||
fn (mut c Checker) check_index(typ_sym &ast.TypeSymbol, index ast.Expr, index_type ast.Type, pos token.Pos, range_index bool, is_gated bool) {
|
||||
index_type_sym := c.table.sym(index_type)
|
||||
if typ_sym.kind in [.array, .array_fixed, .string] {
|
||||
index_type_sym := c.table.sym(index_type)
|
||||
if !(index_type.is_int() || index_type_sym.kind == .enum_
|
||||
|| (index_type_sym.kind == .alias
|
||||
&& (index_type_sym.info as ast.Alias).parent_type.is_int())
|
||||
@ -4102,10 +4102,17 @@ fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type {
|
||||
}
|
||||
else {}
|
||||
}
|
||||
is_aggregate_arr := typ_sym.kind == .aggregate
|
||||
&& (typ_sym.info as ast.Aggregate).types.filter(c.table.type_kind(it) !in [.array, .array_fixed, .string, .map]).len == 0
|
||||
if typ_sym.kind !in [.array, .array_fixed, .string, .map] && !typ.is_ptr()
|
||||
&& typ !in [ast.byteptr_type, ast.charptr_type] && !typ.has_flag(.variadic) {
|
||||
&& typ !in [ast.byteptr_type, ast.charptr_type] && !typ.has_flag(.variadic)
|
||||
&& !is_aggregate_arr {
|
||||
c.error('type `${typ_sym.name}` does not support indexing', node.pos)
|
||||
}
|
||||
if is_aggregate_arr {
|
||||
// treating indexexpr of sumtype of array types
|
||||
typ = (typ_sym.info as ast.Aggregate).types[0]
|
||||
}
|
||||
if typ.has_flag(.option) {
|
||||
if node.left is ast.Ident && (node.left as ast.Ident).or_expr.kind == .absent {
|
||||
c.error('type `?${typ_sym.name}` is an Option, it must be unwrapped first; use `var?[]` to do it',
|
||||
|
@ -48,6 +48,12 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
|
||||
g.write(')')
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if sym.kind == .aggregate
|
||||
&& (sym.info as ast.Aggregate).types.filter(g.table.type_kind(it) !in [.array, .array_fixed, .string, .map]).len == 0 {
|
||||
// treating sumtype of array types
|
||||
unwrapped_got_type := (sym.info as ast.Aggregate).types[g.aggregate_type_idx]
|
||||
g.index_expr(ast.IndexExpr{ ...node, left_type: unwrapped_got_type })
|
||||
} else {
|
||||
g.expr(node.left)
|
||||
g.write('[')
|
||||
@ -56,6 +62,7 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut g Gen) index_range_expr(node ast.IndexExpr, range ast.RangeExpr) {
|
||||
sym := g.table.final_sym(node.left_type)
|
||||
|
43
vlib/v/tests/match_sumtype_arr_test.v
Normal file
43
vlib/v/tests/match_sumtype_arr_test.v
Normal file
@ -0,0 +1,43 @@
|
||||
type MySumType = []MyStructA | []MyStructB
|
||||
type MySumTypePtr = []&MyStructA | []&MyStructB
|
||||
|
||||
struct ParentStruct {
|
||||
parent_field string
|
||||
}
|
||||
|
||||
struct MyStructA {
|
||||
ParentStruct
|
||||
}
|
||||
|
||||
struct MyStructB {
|
||||
ParentStruct
|
||||
}
|
||||
|
||||
fn check(mut t MySumType) {
|
||||
match mut t {
|
||||
[]MyStructA, []MyStructB {
|
||||
println(t[0].parent_field)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check2(mut t MySumTypePtr) {
|
||||
match mut t {
|
||||
[]&MyStructA, []&MyStructB {
|
||||
println(t[0].parent_field)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_main() {
|
||||
s := MyStructA{
|
||||
parent_field: 'common'
|
||||
}
|
||||
|
||||
mut t := MySumType([s])
|
||||
mut t2 := MySumTypePtr([&s])
|
||||
|
||||
check(mut t)
|
||||
check2(mut t2)
|
||||
assert true
|
||||
}
|
Loading…
Reference in New Issue
Block a user