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(')') agg_name.write(')')
name := agg_name.str() name := agg_name.str()
expr_type = c.table.register_type_symbol(table.TypeSymbol{ existing_idx := c.table.type_idxs[name]
name: name if existing_idx > 0 {
cname: agg_cname.str() expr_type = existing_idx
kind: .aggregate } else {
mod: c.mod expr_type = c.table.register_type_symbol(table.TypeSymbol{
info: table.Aggregate{ name: name
types: expr_types.map(it.typ) cname: agg_cname.str()
} kind: .aggregate
}) mod: c.mod
info: table.Aggregate{
types: expr_types.map(it.typ)
}
})
}
} else { } else {
expr_type = expr_types[0].typ expr_type = expr_types[0].typ
} }

View File

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

View File

@ -340,29 +340,6 @@ pub fn (t &Table) unalias_num_type(typ Type) Type {
return typ 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] [inline]
pub fn (mut t Table) register_type_symbol(typ TypeSymbol) int { pub fn (mut t Table) register_type_symbol(typ TypeSymbol) int {
// println('register_type_symbol( $typ.name )') // println('register_type_symbol( $typ.name )')
@ -380,10 +357,21 @@ pub fn (mut t Table) register_type_symbol(typ TypeSymbol) int {
return existing_idx return existing_idx
} }
else { 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 return existing_idx
} }
// panic('cannot register type `$typ.name`, another type with this name exists')
return -1 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() } 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()) } 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 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( return t.register_type_symbol(
kind: .function kind: .function
name: name name: name