checker: check error for generic sumtype types (#14374)
parent
4eb5aacd20
commit
d09c84f46f
|
@ -1166,6 +1166,7 @@ pub:
|
|||
name string
|
||||
is_pub bool
|
||||
pos token.Pos
|
||||
name_pos token.Pos
|
||||
comments []Comment
|
||||
typ Type
|
||||
generic_types []Type
|
||||
|
|
|
@ -493,9 +493,26 @@ pub fn (mut c Checker) sum_type_decl(node ast.SumTypeDecl) {
|
|||
} else if sym.kind == .struct_ && sym.language == .js {
|
||||
c.error('sum type cannot hold an JS struct', variant.pos)
|
||||
} else if mut sym.info is ast.Struct {
|
||||
if sym.info.is_generic && !variant.typ.has_flag(.generic) {
|
||||
c.error('generic struct `$sym.name` must specify generic type names, e.g. Foo<T>',
|
||||
variant.pos)
|
||||
if sym.info.is_generic {
|
||||
if !variant.typ.has_flag(.generic) {
|
||||
c.error('generic struct `$sym.name` must specify generic type names, e.g. Foo<T>',
|
||||
variant.pos)
|
||||
}
|
||||
if node.generic_types.len == 0 {
|
||||
c.error('generic sumtype `$node.name` must specify generic type names, e.g. Foo<T>',
|
||||
node.name_pos)
|
||||
} else {
|
||||
for typ in sym.info.generic_types {
|
||||
if typ !in node.generic_types {
|
||||
sumtype_type_names := node.generic_types.map(c.table.type_to_str(it)).join(', ')
|
||||
generic_sumtype_name := '$node.name<$sumtype_type_names>'
|
||||
variant_type_names := sym.info.generic_types.map(c.table.type_to_str(it)).join(', ')
|
||||
generic_variant_name := '$sym.name<$variant_type_names>'
|
||||
c.error('generic type name `${c.table.sym(typ).name}` of generic struct `$generic_variant_name` is not mentioned in sumtype `$generic_sumtype_name`',
|
||||
variant.pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
vlib/v/checker/tests/generic_sumtype_decl_err.vv:7:24: error: generic struct `Just` must specify generic type names, e.g. Foo<T>
|
||||
vlib/v/checker/tests/generic_sumtype_decl_err_a.vv:7:24: error: generic struct `Just` must specify generic type names, e.g. Foo<T>
|
||||
5 | struct Nothing {}
|
||||
6 |
|
||||
7 | type Maybe = Nothing | Just
|
|
@ -0,0 +1,7 @@
|
|||
vlib/v/checker/tests/generic_sumtype_decl_err_b.vv:7:6: error: generic sumtype `Maybe` must specify generic type names, e.g. Foo<T>
|
||||
5 | struct Nothing {}
|
||||
6 |
|
||||
7 | type Maybe = Nothing | Just<T>
|
||||
| ~~~~~
|
||||
8 |
|
||||
9 | fn main() {
|
|
@ -0,0 +1,10 @@
|
|||
struct Just<T> {
|
||||
value T
|
||||
}
|
||||
|
||||
struct Nothing {}
|
||||
|
||||
type Maybe = Nothing | Just<T>
|
||||
|
||||
fn main() {
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
vlib/v/checker/tests/generic_sumtype_decl_err_c.vv:7:27: error: generic type name `T` of generic struct `Just<T>` is not mentioned in sumtype `Maybe<B>`
|
||||
5 | struct Nothing {}
|
||||
6 |
|
||||
7 | type Maybe<B> = Nothing | Just<T>
|
||||
| ~~~~~~~
|
||||
8 |
|
||||
9 | fn main() {
|
|
@ -0,0 +1,10 @@
|
|||
struct Just<T> {
|
||||
value T
|
||||
}
|
||||
|
||||
struct Nothing {}
|
||||
|
||||
type Maybe<B> = Nothing | Just<T>
|
||||
|
||||
fn main() {
|
||||
}
|
|
@ -3672,6 +3672,7 @@ fn (mut p Parser) type_decl() ast.TypeDecl {
|
|||
generic_types: generic_types
|
||||
attrs: p.attrs
|
||||
pos: decl_pos
|
||||
name_pos: name_pos
|
||||
comments: comments
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue