checker: check error for map of generic struct init (#13999)

pull/14008/head
yuyi 2022-04-11 15:07:23 +08:00 committed by GitHub
parent a0e7a46be4
commit fa66183f43
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 32 additions and 1 deletions

View File

@ -260,6 +260,22 @@ pub fn (mut c Checker) map_init(mut node ast.MapInit) ast.Type {
// `x := map[string]string` - set in parser
if node.typ != 0 {
info := c.table.sym(node.typ).map_info()
if info.value_type != 0 {
val_sym := c.table.sym(info.value_type)
if val_sym.kind == .struct_ {
val_info := val_sym.info as ast.Struct
if val_info.generic_types.len > 0 && val_info.concrete_types.len == 0
&& !info.value_type.has_flag(.generic) {
if c.table.cur_concrete_types.len == 0 {
c.error('generic struct `$val_sym.name` must specify type parameter, e.g. Foo<int>',
node.pos)
} else {
c.error('generic struct `$val_sym.name` must specify type parameter, e.g. Foo<T>',
node.pos)
}
}
}
}
c.ensure_type_exists(info.key_type, node.pos) or {}
c.ensure_type_exists(info.value_type, node.pos) or {}
node.key_type = info.key_type

View File

@ -0,0 +1,6 @@
vlib/v/checker/tests/map_of_generic_struct_init_err.vv:6:11: error: generic struct `Item` must specify type parameter, e.g. Foo<int>
4 |
5 | fn main() {
6 | mut m := map[string]Item{}
| ~~~~~~~~~~~~~~~~~
7 | }

View File

@ -0,0 +1,7 @@
struct Item<T>{
val T
}
fn main() {
mut m := map[string]Item{}
}

View File

@ -2140,10 +2140,12 @@ pub fn (mut p Parser) name_expr() ast.Expr {
p.expr_mod = ''
// `map[string]int` initialization
if p.tok.lit == 'map' && p.peek_tok.kind == .lsbr {
mut pos := p.tok.pos()
map_type := p.parse_map_type()
if p.tok.kind == .lcbr {
p.next()
if p.tok.kind == .rcbr {
pos = pos.extend(p.tok.pos())
p.next()
} else {
if p.pref.is_fmt {
@ -2156,7 +2158,7 @@ pub fn (mut p Parser) name_expr() ast.Expr {
}
return ast.MapInit{
typ: map_type
pos: p.prev_tok.pos()
pos: pos
}
}
// `chan typ{...}`