generics: more fixes
parent
8c753ddf8d
commit
5423a15f46
|
@ -586,7 +586,7 @@ fn (mut c Checker) fail_if_immutable(expr ast.Expr) {
|
|||
c.error('0 type in SelectorExpr', it.pos)
|
||||
return
|
||||
}
|
||||
typ_sym := c.table.get_type_symbol(it.expr_type)
|
||||
typ_sym := c.table.get_type_symbol(c.unwrap_generic(it.expr_type))
|
||||
match typ_sym.kind {
|
||||
.struct_ {
|
||||
struct_info := typ_sym.info as table.Struct
|
||||
|
@ -1120,7 +1120,7 @@ pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) table.T
|
|||
}
|
||||
selector_expr.expr_type = typ
|
||||
// println('sel expr line_nr=$selector_expr.pos.line_nr typ=$selector_expr.expr_type')
|
||||
typ_sym := c.table.get_type_symbol(typ)
|
||||
sym := c.table.get_type_symbol(c.unwrap_generic(typ))
|
||||
field_name := selector_expr.field_name
|
||||
// variadic
|
||||
if typ.flag_is(.variadic) {
|
||||
|
@ -1128,16 +1128,16 @@ pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) table.T
|
|||
return table.int_type
|
||||
}
|
||||
}
|
||||
if field := c.table.struct_find_field(typ_sym, field_name) {
|
||||
if typ_sym.mod != c.mod && !field.is_pub {
|
||||
c.error('field `${typ_sym.name}.$field_name` is not public', selector_expr.pos)
|
||||
if field := c.table.struct_find_field(sym, field_name) {
|
||||
if sym.mod != c.mod && !field.is_pub {
|
||||
c.error('field `${sym.name}.$field_name` is not public', selector_expr.pos)
|
||||
}
|
||||
return field.typ
|
||||
}
|
||||
if typ_sym.kind != .struct_ {
|
||||
c.error('`$typ_sym.name` is not a struct', selector_expr.pos)
|
||||
if sym.kind != .struct_ {
|
||||
c.error('`$sym.name` is not a struct', selector_expr.pos)
|
||||
} else {
|
||||
c.error('unknown field `${typ_sym.name}.$field_name`', selector_expr.pos)
|
||||
c.error('type `$sym.name` has no field or method `$field_name`', selector_expr.pos)
|
||||
}
|
||||
return table.void_type
|
||||
}
|
||||
|
@ -2410,7 +2410,8 @@ fn (mut c Checker) fn_decl(it ast.FnDecl) {
|
|||
// loop thru each generic type and generate a function
|
||||
for gen_type in c.table.fn_gen_types[it.name] {
|
||||
c.cur_generic_type = gen_type
|
||||
// println('\ncalling check for $it.name for type ' + gen_type.str())
|
||||
//sym:=c.table.get_type_symbol(gen_type)
|
||||
//println('\ncalling check for $it.name for type $sym.name')
|
||||
c.fn_decl(it)
|
||||
}
|
||||
c.cur_generic_type = 0
|
||||
|
|
|
@ -29,6 +29,7 @@ pub fn (mut p Parser) call_expr(language table.Language, mod string) ast.CallExp
|
|||
if p.tok.kind == .lt {
|
||||
// `foo<int>(10)`
|
||||
p.next() // `<`
|
||||
p.expr_mod = ''
|
||||
generic_type = p.parse_type()
|
||||
p.check(.gt) // `>`
|
||||
p.table.register_fn_gen_type(fn_name, generic_type)
|
||||
|
|
|
@ -165,7 +165,7 @@ pub fn (mut p Parser) parse_any_type(language table.Language, is_ptr bool) table
|
|||
name = '${p.imports[name]}.$p.tok.lit'
|
||||
} else if p.expr_mod != '' {
|
||||
name = p.expr_mod + '.' + name
|
||||
} else if p.mod !in ['builtin', 'main'] && name !in table.builtin_type_names {
|
||||
} else if p.mod !in ['builtin', 'main'] && name !in table.builtin_type_names && name.len > 1 {
|
||||
// `Foo` in module `mod` means `mod.Foo`
|
||||
name = p.mod + '.' + name
|
||||
}
|
||||
|
|
|
@ -453,15 +453,9 @@ pub fn (t &Table) value_type(typ Type) Type {
|
|||
[inline]
|
||||
pub fn (t &Table) mktyp(typ Type) Type {
|
||||
match typ {
|
||||
any_flt_type {
|
||||
return table.f64_type
|
||||
}
|
||||
any_int_type {
|
||||
return table.int_type
|
||||
}
|
||||
else {
|
||||
return typ
|
||||
}
|
||||
any_flt_type { return f64_type }
|
||||
any_int_type { return int_type }
|
||||
else { return typ }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -486,5 +480,7 @@ pub fn (table &Table) register_fn_gen_type(fn_name string, typ Type) {
|
|||
return
|
||||
}
|
||||
a << typ
|
||||
// sym := table.get_type_symbol(typ)
|
||||
// println('registering fn gen type $sym.name')
|
||||
table.fn_gen_types[fn_name] = a
|
||||
}
|
||||
|
|
|
@ -40,12 +40,20 @@ fn test_foo() {
|
|||
|
||||
fn create<T>() {
|
||||
a := T{}
|
||||
mut b := T{}
|
||||
b.foo = 'foo'
|
||||
println(b.foo)
|
||||
assert b.foo == 'foo'
|
||||
}
|
||||
|
||||
struct User {
|
||||
mut:
|
||||
foo string
|
||||
}
|
||||
|
||||
struct City {
|
||||
mut:
|
||||
foo string
|
||||
}
|
||||
|
||||
fn test_create() {
|
||||
|
|
Loading…
Reference in New Issue