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)
|
c.error('0 type in SelectorExpr', it.pos)
|
||||||
return
|
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 {
|
match typ_sym.kind {
|
||||||
.struct_ {
|
.struct_ {
|
||||||
struct_info := typ_sym.info as table.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
|
selector_expr.expr_type = typ
|
||||||
// println('sel expr line_nr=$selector_expr.pos.line_nr typ=$selector_expr.expr_type')
|
// 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
|
field_name := selector_expr.field_name
|
||||||
// variadic
|
// variadic
|
||||||
if typ.flag_is(.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
|
return table.int_type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if field := c.table.struct_find_field(typ_sym, field_name) {
|
if field := c.table.struct_find_field(sym, field_name) {
|
||||||
if typ_sym.mod != c.mod && !field.is_pub {
|
if sym.mod != c.mod && !field.is_pub {
|
||||||
c.error('field `${typ_sym.name}.$field_name` is not public', selector_expr.pos)
|
c.error('field `${sym.name}.$field_name` is not public', selector_expr.pos)
|
||||||
}
|
}
|
||||||
return field.typ
|
return field.typ
|
||||||
}
|
}
|
||||||
if typ_sym.kind != .struct_ {
|
if sym.kind != .struct_ {
|
||||||
c.error('`$typ_sym.name` is not a struct', selector_expr.pos)
|
c.error('`$sym.name` is not a struct', selector_expr.pos)
|
||||||
} else {
|
} 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
|
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
|
// loop thru each generic type and generate a function
|
||||||
for gen_type in c.table.fn_gen_types[it.name] {
|
for gen_type in c.table.fn_gen_types[it.name] {
|
||||||
c.cur_generic_type = gen_type
|
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.fn_decl(it)
|
||||||
}
|
}
|
||||||
c.cur_generic_type = 0
|
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 {
|
if p.tok.kind == .lt {
|
||||||
// `foo<int>(10)`
|
// `foo<int>(10)`
|
||||||
p.next() // `<`
|
p.next() // `<`
|
||||||
|
p.expr_mod = ''
|
||||||
generic_type = p.parse_type()
|
generic_type = p.parse_type()
|
||||||
p.check(.gt) // `>`
|
p.check(.gt) // `>`
|
||||||
p.table.register_fn_gen_type(fn_name, generic_type)
|
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'
|
name = '${p.imports[name]}.$p.tok.lit'
|
||||||
} else if p.expr_mod != '' {
|
} else if p.expr_mod != '' {
|
||||||
name = p.expr_mod + '.' + name
|
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`
|
// `Foo` in module `mod` means `mod.Foo`
|
||||||
name = p.mod + '.' + name
|
name = p.mod + '.' + name
|
||||||
}
|
}
|
||||||
|
|
|
@ -453,15 +453,9 @@ pub fn (t &Table) value_type(typ Type) Type {
|
||||||
[inline]
|
[inline]
|
||||||
pub fn (t &Table) mktyp(typ Type) Type {
|
pub fn (t &Table) mktyp(typ Type) Type {
|
||||||
match typ {
|
match typ {
|
||||||
any_flt_type {
|
any_flt_type { return f64_type }
|
||||||
return table.f64_type
|
any_int_type { return int_type }
|
||||||
}
|
else { return typ }
|
||||||
any_int_type {
|
|
||||||
return table.int_type
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return typ
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,5 +480,7 @@ pub fn (table &Table) register_fn_gen_type(fn_name string, typ Type) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
a << typ
|
a << typ
|
||||||
|
// sym := table.get_type_symbol(typ)
|
||||||
|
// println('registering fn gen type $sym.name')
|
||||||
table.fn_gen_types[fn_name] = a
|
table.fn_gen_types[fn_name] = a
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,12 +40,20 @@ fn test_foo() {
|
||||||
|
|
||||||
fn create<T>() {
|
fn create<T>() {
|
||||||
a := T{}
|
a := T{}
|
||||||
|
mut b := T{}
|
||||||
|
b.foo = 'foo'
|
||||||
|
println(b.foo)
|
||||||
|
assert b.foo == 'foo'
|
||||||
}
|
}
|
||||||
|
|
||||||
struct User {
|
struct User {
|
||||||
|
mut:
|
||||||
|
foo string
|
||||||
}
|
}
|
||||||
|
|
||||||
struct City {
|
struct City {
|
||||||
|
mut:
|
||||||
|
foo string
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_create() {
|
fn test_create() {
|
||||||
|
|
Loading…
Reference in New Issue