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

checker: add hint to sumtype cannot hold reference types error (#18486)

This commit is contained in:
Turiiya 2023-06-20 10:54:57 +02:00 committed by GitHub
parent 0232f074a8
commit a7f00e7594
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 18 deletions

View File

@ -566,11 +566,15 @@ fn (mut c Checker) sum_type_decl(node ast.SumTypeDecl) {
c.check_valid_pascal_case(node.name, 'sum type', node.pos)
mut names_used := []string{}
for variant in node.variants {
if variant.typ.is_ptr() {
c.error('sum type cannot hold a reference type', variant.pos)
}
c.ensure_type_exists(variant.typ, variant.pos) or {}
sym := c.table.sym(variant.typ)
if variant.typ.is_ptr() {
variant_name := sym.name.all_after_last('.')
lb, rb := if sym.kind == .struct_ { '{', '}' } else { '(', ')' }
c.add_error_detail('declare the sum type with non-reference types: `${node.name} = ${variant_name} | ...`
and use a reference to the sum type instead: `var := &${node.name}(${variant_name}${lb}val${rb})`')
c.error('sum type cannot hold a reference type', variant.pos)
}
if sym.name in names_used {
c.error('sum type ${node.name} cannot hold the type `${sym.name}` more than once',
variant.pos)

View File

@ -1,18 +1,33 @@
vlib/v/checker/tests/sum_type_ref_variant_err.vv:7:33: error: sum type cannot hold a reference type
5 | foo string
vlib/v/checker/tests/sum_type_ref_variant_err.vv:8:33: error: sum type cannot hold a reference type
6 | }
7 | type Alphabet1 = Abc | string | &Xyz
7 | type AliasType = string
8 | type Alphabet1 = Abc | string | &Xyz
| ~~~~
8 | type Alphabet2 = Abc | &Xyz | string
9 | type Alphabet3 = &Xyz | Abc | string
vlib/v/checker/tests/sum_type_ref_variant_err.vv:8:24: error: sum type cannot hold a reference type
6 | }
7 | type Alphabet1 = Abc | string | &Xyz
8 | type Alphabet2 = Abc | &Xyz | string
9 | type Alphabet2 = Abc | &Xyz | string
10 | type Alphabet3 = &Xyz | Abc | string
Details: declare the sum type with non-reference types: `Alphabet1 = Xyz | ...`
and use a reference to the sum type instead: `var := &Alphabet1(Xyz{val})`
vlib/v/checker/tests/sum_type_ref_variant_err.vv:9:24: error: sum type cannot hold a reference type
7 | type AliasType = string
8 | type Alphabet1 = Abc | string | &Xyz
9 | type Alphabet2 = Abc | &Xyz | string
| ~~~~
9 | type Alphabet3 = &Xyz | Abc | string
vlib/v/checker/tests/sum_type_ref_variant_err.vv:9:18: error: sum type cannot hold a reference type
7 | type Alphabet1 = Abc | string | &Xyz
8 | type Alphabet2 = Abc | &Xyz | string
9 | type Alphabet3 = &Xyz | Abc | string
10 | type Alphabet3 = &Xyz | Abc | string
11 | type Alphabet4 = Xyz | Abc | &AliasType
Details: declare the sum type with non-reference types: `Alphabet2 = Xyz | ...`
and use a reference to the sum type instead: `var := &Alphabet2(Xyz{val})`
vlib/v/checker/tests/sum_type_ref_variant_err.vv:10:18: error: sum type cannot hold a reference type
8 | type Alphabet1 = Abc | string | &Xyz
9 | type Alphabet2 = Abc | &Xyz | string
10 | type Alphabet3 = &Xyz | Abc | string
| ~~~~
11 | type Alphabet4 = Xyz | Abc | &AliasType
Details: declare the sum type with non-reference types: `Alphabet3 = Xyz | ...`
and use a reference to the sum type instead: `var := &Alphabet3(Xyz{val})`
vlib/v/checker/tests/sum_type_ref_variant_err.vv:11:30: error: sum type cannot hold a reference type
9 | type Alphabet2 = Abc | &Xyz | string
10 | type Alphabet3 = &Xyz | Abc | string
11 | type Alphabet4 = Xyz | Abc | &AliasType
| ~~~~~~~~~~
Details: declare the sum type with non-reference types: `Alphabet4 = AliasType | ...`
and use a reference to the sum type instead: `var := &Alphabet4(AliasType(val))`

View File

@ -4,6 +4,8 @@ struct Abc {
struct Xyz {
foo string
}
type AliasType = string
type Alphabet1 = Abc | string | &Xyz
type Alphabet2 = Abc | &Xyz | string
type Alphabet3 = &Xyz | Abc | string
type Alphabet3 = &Xyz | Abc | string
type Alphabet4 = Xyz | Abc | &AliasType