diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 3d61ee1a54..e09c9a5377 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -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 } @@ -2163,7 +2163,7 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) table.Type { if last_expr.typ.is_int() || last_expr.typ.is_float() { node.typ = last_expr.typ continue - } + } } else { // node.typ == any_float if last_expr.typ.is_float() { node.typ = last_expr.typ @@ -2175,7 +2175,7 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) table.Type { if last_expr.typ == table.any_int_type { if node.typ.is_int() || node.typ.is_float() { continue - } + } } else { // expr_type == any_float if node.typ.is_float() { continue @@ -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 diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index 0190df883e..eb6ea874a5 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -29,6 +29,7 @@ pub fn (mut p Parser) call_expr(language table.Language, mod string) ast.CallExp if p.tok.kind == .lt { // `foo(10)` p.next() // `<` + p.expr_mod = '' generic_type = p.parse_type() p.check(.gt) // `>` p.table.register_fn_gen_type(fn_name, generic_type) diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index c67f25d3ab..ef4036eb69 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -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 } diff --git a/vlib/v/table/table.v b/vlib/v/table/table.v index 6694023d9e..aed23c6013 100644 --- a/vlib/v/table/table.v +++ b/vlib/v/table/table.v @@ -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 } diff --git a/vlib/v/tests/generics_test.v b/vlib/v/tests/generics_test.v index 0920e107e4..f897f2112d 100644 --- a/vlib/v/tests/generics_test.v +++ b/vlib/v/tests/generics_test.v @@ -40,12 +40,20 @@ fn test_foo() { fn create() { 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() {