checker: make struct_init check more robust
parent
4d5fe14968
commit
e8b26b1b8d
|
@ -89,10 +89,26 @@ pub fn (c mut Checker) struct_init(struct_init mut ast.StructInit) table.Type {
|
||||||
}
|
}
|
||||||
mut inited_fields := []string
|
mut inited_fields := []string
|
||||||
for i, expr in struct_init.exprs {
|
for i, expr in struct_init.exprs {
|
||||||
|
if is_short_syntax && i >= info.fields.len {
|
||||||
|
// It doesn't make sense to check for fields that don't exist.
|
||||||
|
// We should just stop here.
|
||||||
|
break
|
||||||
|
}
|
||||||
// struct_field info.
|
// struct_field info.
|
||||||
field_name := if is_short_syntax { info.fields[i].name } else { struct_init.fields[i] }
|
field_name := if is_short_syntax { info.fields[i].name } else { struct_init.fields[i] }
|
||||||
mut field := info.fields[i]
|
if field_name in inited_fields {
|
||||||
|
c.error('struct init: duplicate field `$field_name` for struct `$typ_sym.name`', struct_init.pos)
|
||||||
|
continue
|
||||||
|
}
|
||||||
inited_fields << field_name
|
inited_fields << field_name
|
||||||
|
mut field := if is_short_syntax {
|
||||||
|
info.fields[i]
|
||||||
|
} else {
|
||||||
|
// There is no guarantee that `i` will not be out of bounds of `info.fields`
|
||||||
|
// So we just use an empty field as placeholder here.
|
||||||
|
table.Field{}
|
||||||
|
}
|
||||||
|
if !is_short_syntax {
|
||||||
mut found_field := false
|
mut found_field := false
|
||||||
for f in info.fields {
|
for f in info.fields {
|
||||||
if f.name == field_name {
|
if f.name == field_name {
|
||||||
|
@ -103,6 +119,8 @@ pub fn (c mut Checker) struct_init(struct_init mut ast.StructInit) table.Type {
|
||||||
}
|
}
|
||||||
if !found_field {
|
if !found_field {
|
||||||
c.error('struct init: no such field `$field_name` for struct `$typ_sym.name`', struct_init.pos)
|
c.error('struct init: no such field `$field_name` for struct `$typ_sym.name`', struct_init.pos)
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
c.expected_type = field.typ
|
c.expected_type = field.typ
|
||||||
expr_type := c.expr(expr)
|
expr_type := c.expr(expr)
|
||||||
|
|
Loading…
Reference in New Issue