checker: check error for map of generic struct init (#13999)
parent
a0e7a46be4
commit
fa66183f43
|
@ -260,6 +260,22 @@ pub fn (mut c Checker) map_init(mut node ast.MapInit) ast.Type {
|
||||||
// `x := map[string]string` - set in parser
|
// `x := map[string]string` - set in parser
|
||||||
if node.typ != 0 {
|
if node.typ != 0 {
|
||||||
info := c.table.sym(node.typ).map_info()
|
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.key_type, node.pos) or {}
|
||||||
c.ensure_type_exists(info.value_type, node.pos) or {}
|
c.ensure_type_exists(info.value_type, node.pos) or {}
|
||||||
node.key_type = info.key_type
|
node.key_type = info.key_type
|
||||||
|
|
|
@ -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 | }
|
|
@ -0,0 +1,7 @@
|
||||||
|
struct Item<T>{
|
||||||
|
val T
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
mut m := map[string]Item{}
|
||||||
|
}
|
|
@ -2140,10 +2140,12 @@ pub fn (mut p Parser) name_expr() ast.Expr {
|
||||||
p.expr_mod = ''
|
p.expr_mod = ''
|
||||||
// `map[string]int` initialization
|
// `map[string]int` initialization
|
||||||
if p.tok.lit == 'map' && p.peek_tok.kind == .lsbr {
|
if p.tok.lit == 'map' && p.peek_tok.kind == .lsbr {
|
||||||
|
mut pos := p.tok.pos()
|
||||||
map_type := p.parse_map_type()
|
map_type := p.parse_map_type()
|
||||||
if p.tok.kind == .lcbr {
|
if p.tok.kind == .lcbr {
|
||||||
p.next()
|
p.next()
|
||||||
if p.tok.kind == .rcbr {
|
if p.tok.kind == .rcbr {
|
||||||
|
pos = pos.extend(p.tok.pos())
|
||||||
p.next()
|
p.next()
|
||||||
} else {
|
} else {
|
||||||
if p.pref.is_fmt {
|
if p.pref.is_fmt {
|
||||||
|
@ -2156,7 +2158,7 @@ pub fn (mut p Parser) name_expr() ast.Expr {
|
||||||
}
|
}
|
||||||
return ast.MapInit{
|
return ast.MapInit{
|
||||||
typ: map_type
|
typ: map_type
|
||||||
pos: p.prev_tok.pos()
|
pos: pos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// `chan typ{...}`
|
// `chan typ{...}`
|
||||||
|
|
Loading…
Reference in New Issue