1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

table, checker: fix sumtype array appending aggregate type values (fix #11197) (#11258)

This commit is contained in:
yuyi 2021-08-21 22:18:01 +08:00 committed by GitHub
parent 02d823fa6e
commit 0d81d0c0c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 88 additions and 3 deletions

View File

@ -1139,9 +1139,20 @@ pub fn (t &Table) sumtype_has_variant(parent Type, variant Type) bool {
parent_sym := t.get_type_symbol(parent)
if parent_sym.kind == .sum_type {
parent_info := parent_sym.info as SumType
for v in parent_info.variants {
if v.idx() == variant.idx() {
return true
var_sym := t.get_type_symbol(variant)
if var_sym.kind == .aggregate {
var_info := var_sym.info as Aggregate
for var_type in var_info.types {
if !t.sumtype_has_variant(parent, var_type) {
return false
}
}
return true
} else {
for v in parent_info.variants {
if v.idx() == variant.idx() {
return true
}
}
}
}

View File

@ -1555,6 +1555,10 @@ pub fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
}
return ast.void_type
}
if left_value_sym.kind == .sum_type
&& c.table.sumtype_has_variant(left_value_type, right_type) {
return ast.void_type
}
// []T << T or []T << []T
unwrapped_right_type := c.unwrap_generic(right_type)
if c.check_types(unwrapped_right_type, left_value_type)

View File

@ -0,0 +1,7 @@
vlib/v/checker/tests/sumtype_mismatch_of_aggregate_err.vv:7:11: error: cannot use `(i8 | i16 | int | i64)` as type `SimpleInt` in return argument
5 | match s {
6 | i8, i16, int, i64 {
7 | return s
| ^
8 | }
9 | }

View File

@ -0,0 +1,13 @@
type SimpleInt = i64 | int
type SuperInt = i16 | i64 | i8 | int
fn ret_super(s SuperInt) SimpleInt {
match s {
i8, i16, int, i64 {
return s
}
}
}
fn main() {
}

View File

@ -0,0 +1,29 @@
struct StructA {
value int
}
struct StructB {
value int
offset int
}
type AB = StructA | StructB
fn test_sumtype_array_append_aggregate_type() {
mut arr := []AB{}
arr << StructA{0}
arr << StructB{0, 1}
mut arr2 := []AB{}
for a_or_b in arr {
match a_or_b {
StructA, StructB {
arr2 << a_or_b
}
}
}
println(arr2)
assert arr2.len == 2
}

View File

@ -0,0 +1,21 @@
struct Foo {}
struct Bar {}
struct Baz {}
type Sum = Bar | Baz | Foo
fn foo(s Sum) Sum {
match s {
Foo, Bar { return s }
Baz { return Baz{} }
}
}
fn test_match_sumtype_var_aggregate() {
a := Foo{}
ret := foo(a)
println(ret)
assert '$ret' == 'Sum(Foo{})'
}