diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 3b3c320dbb..5225b804e1 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -385,19 +385,18 @@ pub: attrs []Attr skip_gen bool // this function doesn't need to be generated (for example [if foo]) pub mut: - params []Param - stmts []Stmt - defer_stmts []DeferStmt - return_type Type - return_type_pos token.Position // `string` in `fn (u User) name() string` position - has_return bool - comments []Comment // comments *after* the header, but *before* `{`; used for InterfaceDecl - next_comments []Comment // coments that are one line after the decl; used for InterfaceDecl - source_file &File = 0 - scope &Scope - label_names []string - pos token.Position // function declaration position - cur_concrete_types []Type // current concrete types, e.g. + params []Param + stmts []Stmt + defer_stmts []DeferStmt + return_type Type + return_type_pos token.Position // `string` in `fn (u User) name() string` position + has_return bool + comments []Comment // comments *after* the header, but *before* `{`; used for InterfaceDecl + next_comments []Comment // coments that are one line after the decl; used for InterfaceDecl + source_file &File = 0 + scope &Scope + label_names []string + pos token.Position // function declaration position } // break, continue diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 69d0b5e21c..7a7ac75fd3 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -80,6 +80,7 @@ mut: timers &util.Timers = util.new_timers(false) comptime_fields_type map[string]ast.Type fn_scope &ast.Scope = voidptr(0) + cur_concrete_types []ast.Type // current concrete types, e.g. main_fn_decl_node ast.FnDecl match_exhaustive_cutoff_limit int = 10 // TODO: these are here temporarily and used for deprecations; remove soon @@ -634,7 +635,7 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) ast.Type { // Make sure the first letter is capital, do not allow e.g. `x := string{}`, // but `x := T{}` is ok. if !c.is_builtin_mod && !c.inside_unsafe && type_sym.language == .v - && c.cur_fn.cur_concrete_types.len == 0 { + && c.cur_concrete_types.len == 0 { pos := type_sym.name.last_index('.') or { -1 } first_letter := type_sym.name[pos + 1] if !first_letter.is_capital() { @@ -2162,7 +2163,7 @@ pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type { concrete_types << concrete_type } } - if !isnil(c.cur_fn) && c.cur_fn.cur_concrete_types.len == 0 && has_generic { + if !isnil(c.cur_fn) && c.cur_concrete_types.len == 0 && has_generic { c.error('generic fn using generic types cannot be called outside of generic fn', call_expr.pos) } @@ -2923,7 +2924,7 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) { mut expected_types := [expected_type] if expected_type_sym.info is ast.MultiReturn { expected_types = expected_type_sym.info.types - if c.cur_fn.cur_concrete_types.len > 0 { + if c.cur_concrete_types.len > 0 { expected_types = expected_types.map(c.unwrap_generic(it)) } } @@ -4426,7 +4427,7 @@ fn (mut c Checker) stmts(stmts []ast.Stmt) { pub fn (mut c Checker) unwrap_generic(typ ast.Type) ast.Type { if typ.has_flag(.generic) { - if t_typ := c.table.resolve_generic_to_concrete(typ, c.cur_fn.generic_names, c.cur_fn.cur_concrete_types, + if t_typ := c.table.resolve_generic_to_concrete(typ, c.cur_fn.generic_names, c.cur_concrete_types, false) { return t_typ @@ -6868,7 +6869,7 @@ fn (mut c Checker) post_process_generic_fns() { mut node := c.file.generic_fns[i] c.mod = node.mod for concrete_types in c.table.fn_generic_types[node.name] { - node.cur_concrete_types = concrete_types + c.cur_concrete_types = concrete_types c.fn_decl(mut node) if node.name in ['vweb.run_app', 'vweb.run'] { for ct in concrete_types { @@ -6878,13 +6879,13 @@ fn (mut c Checker) post_process_generic_fns() { } } } - node.cur_concrete_types = [] + c.cur_concrete_types = [] } } fn (mut c Checker) fn_decl(mut node ast.FnDecl) { c.returns = false - if node.generic_names.len > 0 && node.cur_concrete_types.len == 0 { + if node.generic_names.len > 0 && c.cur_concrete_types.len == 0 { // Just remember the generic function for now. // It will be processed later in c.post_process_generic_fns, // after all other normal functions are processed.