From 31d03bb113e89025d46921b0d0f2f90871b94ab8 Mon Sep 17 00:00:00 2001 From: joe-conigliaro Date: Sat, 6 Jun 2020 12:24:27 +1000 Subject: [PATCH] checker/cgen: small generic fixes (mut arg return) --- vlib/v/checker/checker.v | 15 ++++----------- vlib/v/gen/fn.v | 2 +- vlib/v/tests/generics_test.v | 6 +++--- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 00e41a393f..5a103078a8 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1226,7 +1226,7 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) { if return_stmt.exprs.len == 0 { return } - expected_type := c.expected_type + expected_type := c.unwrap_generic(c.expected_type) expected_type_sym := c.table.get_type_symbol(expected_type) exp_is_optional := expected_type.has_flag(.optional) mut expected_types := [expected_type] @@ -1257,23 +1257,16 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) { return } for i, exp_type in expected_types { - got_typ := got_types[i] + got_typ := c.unwrap_generic(got_types[i]) if got_typ.has_flag(.optional) && (!exp_type.has_flag(.optional) || c.table.type_to_str(got_typ) != c.table.type_to_str(exp_type)) { pos := return_stmt.exprs[i].position() c.error('cannot use `${c.table.type_to_str(got_typ)}` as type `${c.table.type_to_str(exp_type)}` in return argument', pos) } - is_generic := exp_type == table.t_type - ok := if is_generic { c.check_types(got_typ, c.cur_generic_type) || got_typ == exp_type } else { c.check_types(got_typ, - exp_type) } - // ok := c.check_types(got_typ, exp_type) - if !ok { // !c.table.check(got_typ, exp_typ) { + if !c.check_types(got_typ, exp_type) { got_typ_sym := c.table.get_type_symbol(got_typ) mut exp_typ_sym := c.table.get_type_symbol(exp_type) pos := return_stmt.exprs[i].position() - if is_generic { - exp_typ_sym = c.table.get_type_symbol(c.cur_generic_type) - } if exp_typ_sym.kind == .interface_ { c.type_implements(got_typ, exp_type, return_stmt.pos) continue @@ -1747,7 +1740,7 @@ fn (mut c Checker) stmts(stmts []ast.Stmt) { c.expected_type = table.void_type } -pub fn (mut c Checker) unwrap_generic(typ table.Type) table.Type { +pub fn (c &Checker) unwrap_generic(typ table.Type) table.Type { if typ.idx() == table.t_type_idx { // return c.cur_generic_type // its more efficient to set the id rather than to copy flags/nr_muls diff --git a/vlib/v/gen/fn.v b/vlib/v/gen/fn.v index 6f97481ad2..2a4780e11c 100644 --- a/vlib/v/gen/fn.v +++ b/vlib/v/gen/fn.v @@ -328,7 +328,7 @@ fn (mut g Gen) call_expr(node ast.CallExpr) { } } -pub fn (mut g Gen) unwrap_generic(typ table.Type) table.Type { +pub fn (g &Gen) unwrap_generic(typ table.Type) table.Type { if typ.idx() == table.t_type_idx { // return g.cur_generic_type // its more efficient to set the id rather than to copy flags/nr_muls diff --git a/vlib/v/tests/generics_test.v b/vlib/v/tests/generics_test.v index c381e6a1b7..5ad70b2634 100644 --- a/vlib/v/tests/generics_test.v +++ b/vlib/v/tests/generics_test.v @@ -68,18 +68,18 @@ fn mut_arg(mut x T) { println(x.foo) // = 'foo' } -/* + fn mut_arg2(mut x T) T { println(x.foo) // = 'foo' return x } -*/ + fn test_create() { create() create() u := User{} mut_arg(mut u) - // mut_arg2(mut u) + mut_arg2(mut u) } /*