table: properly detect duplicate types

pull/7264/head
joe-conigliaro 2020-12-11 17:39:51 +11:00
parent 8823430c71
commit 6f474913cf
No known key found for this signature in database
GPG Key ID: C12F7136C08206F1
3 changed files with 36 additions and 43 deletions

View File

@ -3603,15 +3603,20 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, type_sym table.TypeSymbol
}
agg_name.write(')')
name := agg_name.str()
expr_type = c.table.register_type_symbol(table.TypeSymbol{
name: name
cname: agg_cname.str()
kind: .aggregate
mod: c.mod
info: table.Aggregate{
types: expr_types.map(it.typ)
}
})
existing_idx := c.table.type_idxs[name]
if existing_idx > 0 {
expr_type = existing_idx
} else {
expr_type = c.table.register_type_symbol(table.TypeSymbol{
name: name
cname: agg_cname.str()
kind: .aggregate
mod: c.mod
info: table.Aggregate{
types: expr_types.map(it.typ)
}
})
}
} else {
expr_type = expr_types[0].typ
}

View File

@ -277,15 +277,10 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
is_public: is_pub
}
mut ret := 0
if p.builtin_mod && t.name in table.builtin_type_names {
// this allows overiding the builtins type
// with the real struct type info parsed from builtin
ret = p.table.register_builtin_type_symbol(t)
} else {
// println('reg type symbol $name mod=$p.mod')
ret = p.table.register_type_symbol(t)
}
if ret == -1 {
// println('reg type symbol $name mod=$p.mod')
ret = p.table.register_type_symbol(t)
// allow duplicate c struct declarations
if ret == -1 && language != .c {
p.error_with_pos('cannot register struct `$name`, another type with this name exists',
name_pos)
return ast.StructDecl{}

View File

@ -340,29 +340,6 @@ pub fn (t &Table) unalias_num_type(typ Type) Type {
return typ
}
// this will override or register builtin type
// allows prexisitng types added in register_builtins
// to be overriden with their real type info
[inline]
pub fn (mut t Table) register_builtin_type_symbol(typ TypeSymbol) int {
existing_idx := t.type_idxs[typ.name]
if existing_idx > 0 {
if existing_idx >= string_type_idx {
if existing_idx == string_type_idx {
existing_type := t.types[existing_idx]
t.types[existing_idx] = {
typ |
kind: existing_type.kind
}
} else {
t.types[existing_idx] = typ
}
}
return existing_idx
}
return t.register_type_symbol(typ)
}
[inline]
pub fn (mut t Table) register_type_symbol(typ TypeSymbol) int {
// println('register_type_symbol( $typ.name )')
@ -380,10 +357,21 @@ pub fn (mut t Table) register_type_symbol(typ TypeSymbol) int {
return existing_idx
}
else {
if ex_type.kind == typ.kind {
// builtin
// this will override the already registered builtin types
// with the actual v struct declaration in the source
if existing_idx >= string_type_idx && existing_idx <= map_type_idx {
if existing_idx == string_type_idx {
// existing_type := t.types[existing_idx]
t.types[existing_idx] = {
typ |
kind: ex_type.kind
}
} else {
t.types[existing_idx] = typ
}
return existing_idx
}
// panic('cannot register type `$typ.name`, another type with this name exists')
return -1
}
}
@ -608,6 +596,11 @@ pub fn (mut t Table) find_or_register_fn_type(mod string, f Fn, is_anon bool, ha
name := if f.name.len == 0 { 'fn ${t.fn_type_source_signature(f)}' } else { f.name.clone() }
cname := if f.name.len == 0 { 'anon_fn_${t.fn_type_signature(f)}' } else { util.no_dots(f.name.clone()) }
anon := f.name.len == 0 || is_anon
// existing
existing_idx := t.type_idxs[name]
if existing_idx > 0 && t.types[existing_idx].kind != .placeholder {
return existing_idx
}
return t.register_type_symbol(
kind: .function
name: name