checker: check error for generic sumtype types (#14374)
parent
e93a8766e5
commit
f48f7014f0
|
@ -1166,6 +1166,7 @@ pub:
|
||||||
name string
|
name string
|
||||||
is_pub bool
|
is_pub bool
|
||||||
pos token.Pos
|
pos token.Pos
|
||||||
|
name_pos token.Pos
|
||||||
comments []Comment
|
comments []Comment
|
||||||
typ Type
|
typ Type
|
||||||
generic_types []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 {
|
} else if sym.kind == .struct_ && sym.language == .js {
|
||||||
c.error('sum type cannot hold an JS struct', variant.pos)
|
c.error('sum type cannot hold an JS struct', variant.pos)
|
||||||
} else if mut sym.info is ast.Struct {
|
} else if mut sym.info is ast.Struct {
|
||||||
if sym.info.is_generic && !variant.typ.has_flag(.generic) {
|
if sym.info.is_generic {
|
||||||
c.error('generic struct `$sym.name` must specify generic type names, e.g. Foo<T>',
|
if !variant.typ.has_flag(.generic) {
|
||||||
variant.pos)
|
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 {}
|
5 | struct Nothing {}
|
||||||
6 |
|
6 |
|
||||||
7 | type Maybe = Nothing | Just
|
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
|
generic_types: generic_types
|
||||||
attrs: p.attrs
|
attrs: p.attrs
|
||||||
pos: decl_pos
|
pos: decl_pos
|
||||||
|
name_pos: name_pos
|
||||||
comments: comments
|
comments: comments
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue