Skip to content

Commit cb19079

Browse files
authored
all: move cur_concrete_types to Table (#10269)
1 parent 9fc5b9d commit cb19079

File tree

5 files changed

+60
-63
lines changed

5 files changed

+60
-63
lines changed

vlib/v/ast/table.v

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,27 @@ import v.util
1010
[heap]
1111
pub struct Table {
1212
pub mut:
13-
type_symbols []TypeSymbol
14-
type_idxs map[string]int
15-
fns map[string]Fn
16-
dumps map[int]string // needed for efficiently generating all _v_dump_expr_TNAME() functions
17-
imports []string // List of all imports
18-
modules []string // Topologically sorted list of all modules registered by the application
19-
cflags []cflag.CFlag
20-
redefined_fns []string
21-
fn_generic_types map[string][][]Type // for generic functions
22-
interfaces map[int]InterfaceDecl
23-
cmod_prefix string // needed for ast.type_to_str(Type) while vfmt; contains `os.`
24-
is_fmt bool
25-
used_fns map[string]bool // filled in by the checker, when pref.skip_unused = true;
26-
used_consts map[string]bool // filled in by the checker, when pref.skip_unused = true;
27-
used_vweb_types []Type // vweb context types, filled in by checker, when pref.skip_unused = true;
28-
panic_handler FnPanicHandler = default_table_panic_handler
29-
panic_userdata voidptr = voidptr(0) // can be used to pass arbitrary data to panic_handler;
30-
panic_npanics int
31-
cur_fn &FnDecl = 0 // previously stored in Checker.cur_fn and Gen.cur_fn
32-
gostmts int // how many `go` statements there were in the parsed files.
13+
type_symbols []TypeSymbol
14+
type_idxs map[string]int
15+
fns map[string]Fn
16+
dumps map[int]string // needed for efficiently generating all _v_dump_expr_TNAME() functions
17+
imports []string // List of all imports
18+
modules []string // Topologically sorted list of all modules registered by the application
19+
cflags []cflag.CFlag
20+
redefined_fns []string
21+
fn_generic_types map[string][][]Type // for generic functions
22+
interfaces map[int]InterfaceDecl
23+
cmod_prefix string // needed for ast.type_to_str(Type) while vfmt; contains `os.`
24+
is_fmt bool
25+
used_fns map[string]bool // filled in by the checker, when pref.skip_unused = true;
26+
used_consts map[string]bool // filled in by the checker, when pref.skip_unused = true;
27+
used_vweb_types []Type // vweb context types, filled in by checker, when pref.skip_unused = true;
28+
panic_handler FnPanicHandler = default_table_panic_handler
29+
panic_userdata voidptr = voidptr(0) // can be used to pass arbitrary data to panic_handler;
30+
panic_npanics int
31+
cur_fn &FnDecl = 0 // previously stored in Checker.cur_fn and Gen.cur_fn
32+
cur_concrete_types []Type // current concrete types, e.g. <int, string>
33+
gostmts int // how many `go` statements there were in the parsed files.
3334
// When table.gostmts > 0, __VTHREADS__ is defined, which can be checked with `$if threads {`
3435
}
3536

vlib/v/checker/check_types.v

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -508,9 +508,9 @@ pub fn (mut c Checker) infer_fn_generic_types(f ast.Fn, mut call_expr ast.CallEx
508508
info := sym.info as ast.Struct
509509
if c.table.cur_fn.generic_names.len > 0 { // in generic fn
510510
if gt_name in c.table.cur_fn.generic_names
511-
&& c.table.cur_fn.generic_names.len == c.cur_concrete_types.len {
511+
&& c.table.cur_fn.generic_names.len == c.table.cur_concrete_types.len {
512512
idx := c.table.cur_fn.generic_names.index(gt_name)
513-
typ = c.cur_concrete_types[idx]
513+
typ = c.table.cur_concrete_types[idx]
514514
}
515515
} else { // in non-generic fn
516516
receiver_generic_names := info.generic_types.map(c.table.get_type_symbol(it).name)

vlib/v/checker/checker.v

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,13 @@ pub mut:
4949
error_lines []int // to avoid printing multiple errors for the same line
5050
expected_type ast.Type
5151
expected_or_type ast.Type // fn() or { 'this type' } eg. string. expected or block type
52-
// cur_fn &ast.FnDecl // current function
53-
const_decl string
54-
const_deps []string
55-
const_names []string
56-
global_names []string
57-
locked_names []string // vars that are currently locked
58-
rlocked_names []string // vars that are currently read-locked
59-
in_for_count int // if checker is currently in a for loop
52+
const_decl string
53+
const_deps []string
54+
const_names []string
55+
global_names []string
56+
locked_names []string // vars that are currently locked
57+
rlocked_names []string // vars that are currently read-locked
58+
in_for_count int // if checker is currently in a for loop
6059
// checked_ident string // to avoid infinite checker loops
6160
returns bool
6261
scope_returns bool
@@ -82,7 +81,6 @@ mut:
8281
timers &util.Timers = util.new_timers(false)
8382
comptime_fields_type map[string]ast.Type
8483
fn_scope &ast.Scope = voidptr(0)
85-
cur_concrete_types []ast.Type // current concrete types, e.g. <int, string>
8684
main_fn_decl_node ast.FnDecl
8785
match_exhaustive_cutoff_limit int = 10
8886
// TODO: these are here temporarily and used for deprecations; remove soon
@@ -689,7 +687,7 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) ast.Type {
689687
struct_sym := c.table.get_type_symbol(struct_init.typ)
690688
if struct_sym.info is ast.Struct {
691689
if struct_sym.info.generic_types.len > 0 && struct_sym.info.concrete_types.len == 0
692-
&& c.cur_concrete_types.len == 0 {
690+
&& c.table.cur_concrete_types.len == 0 {
693691
c.error('generic struct init must specify type parameter, e.g. Foo<int>',
694692
struct_init.pos)
695693
}
@@ -704,7 +702,7 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) ast.Type {
704702
return ast.void_type
705703
}
706704
}
707-
utyp := c.unwrap_generic_struct(struct_init.typ, c.table.cur_fn.generic_names, c.cur_concrete_types)
705+
utyp := c.unwrap_generic_struct(struct_init.typ, c.table.cur_fn.generic_names, c.table.cur_concrete_types)
708706
c.ensure_type_exists(utyp, struct_init.pos) or {}
709707
type_sym := c.table.get_type_symbol(utyp)
710708
if !c.inside_unsafe && type_sym.kind == .sum_type {
@@ -713,7 +711,7 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) ast.Type {
713711
// Make sure the first letter is capital, do not allow e.g. `x := string{}`,
714712
// but `x := T{}` is ok.
715713
if !c.is_builtin_mod && !c.inside_unsafe && type_sym.language == .v
716-
&& c.cur_concrete_types.len == 0 {
714+
&& c.table.cur_concrete_types.len == 0 {
717715
pos := type_sym.name.last_index('.') or { -1 }
718716
first_letter := type_sym.name[pos + 1]
719717
if !first_letter.is_capital() {
@@ -2220,7 +2218,7 @@ pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type {
22202218
concrete_types << concrete_type
22212219
}
22222220
}
2223-
if !isnil(c.table.cur_fn) && c.cur_concrete_types.len == 0 && has_generic {
2221+
if !isnil(c.table.cur_fn) && c.table.cur_concrete_types.len == 0 && has_generic {
22242222
c.error('generic fn using generic types cannot be called outside of generic fn',
22252223
call_expr.pos)
22262224
}
@@ -2981,7 +2979,7 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) {
29812979
mut expected_type := c.unwrap_generic(c.expected_type)
29822980
if expected_type.has_flag(.generic) && c.table.get_type_symbol(expected_type).kind == .struct_ {
29832981
if t_typ := c.table.resolve_generic_to_concrete(expected_type, c.table.cur_fn.generic_names,
2984-
c.cur_concrete_types, true)
2982+
c.table.cur_concrete_types, true)
29852983
{
29862984
expected_type = t_typ
29872985
}
@@ -3004,7 +3002,7 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) {
30043002
mut expected_types := [expected_type]
30053003
if expected_type_sym.info is ast.MultiReturn {
30063004
expected_types = expected_type_sym.info.types
3007-
if c.cur_concrete_types.len > 0 {
3005+
if c.table.cur_concrete_types.len > 0 {
30083006
expected_types = expected_types.map(c.unwrap_generic(it))
30093007
}
30103008
}
@@ -4561,7 +4559,7 @@ fn (mut c Checker) stmts(stmts []ast.Stmt) {
45614559
pub fn (mut c Checker) unwrap_generic(typ ast.Type) ast.Type {
45624560
if typ.has_flag(.generic) {
45634561
if t_typ := c.table.resolve_generic_to_concrete(typ, c.table.cur_fn.generic_names,
4564-
c.cur_concrete_types, false)
4562+
c.table.cur_concrete_types, false)
45654563
{
45664564
return t_typ
45674565
}
@@ -7063,7 +7061,7 @@ fn (mut c Checker) post_process_generic_fns() {
70637061
mut node := c.file.generic_fns[i]
70647062
c.mod = node.mod
70657063
for concrete_types in c.table.fn_generic_types[node.name] {
7066-
c.cur_concrete_types = concrete_types
7064+
c.table.cur_concrete_types = concrete_types
70677065
c.fn_decl(mut node)
70687066
if node.name == 'vweb.run' {
70697067
for ct in concrete_types {
@@ -7073,13 +7071,13 @@ fn (mut c Checker) post_process_generic_fns() {
70737071
}
70747072
}
70757073
}
7076-
c.cur_concrete_types = []
7074+
c.table.cur_concrete_types = []
70777075
}
70787076
}
70797077

70807078
fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
70817079
c.returns = false
7082-
if node.generic_names.len > 0 && c.cur_concrete_types.len == 0 {
7080+
if node.generic_names.len > 0 && c.table.cur_concrete_types.len == 0 {
70837081
// Just remember the generic function for now.
70847082
// It will be processed later in c.post_process_generic_fns,
70857083
// after all other normal functions are processed.

vlib/v/gen/c/cgen.v

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -124,22 +124,20 @@ mut:
124124
is_builtin_mod bool
125125
hotcode_fn_names []string
126126
embedded_files []ast.EmbeddedFile
127-
// cur_fn ast.FnDecl
128-
cur_concrete_types []ast.Type // current concrete types, e.g. <int, string>
129-
sql_i int
130-
sql_stmt_name string
131-
sql_bind_name string
132-
sql_idents []string
133-
sql_idents_types []ast.Type
134-
sql_left_type ast.Type
135-
sql_table_name string
136-
sql_fkey string
137-
sql_parent_id string
138-
sql_side SqlExprSide // left or right, to distinguish idents in `name == name`
139-
inside_vweb_tmpl bool
140-
inside_return bool
141-
inside_or_block bool
142-
strs_to_free0 []string // strings.Builder
127+
sql_i int
128+
sql_stmt_name string
129+
sql_bind_name string
130+
sql_idents []string
131+
sql_idents_types []ast.Type
132+
sql_left_type ast.Type
133+
sql_table_name string
134+
sql_fkey string
135+
sql_parent_id string
136+
sql_side SqlExprSide // left or right, to distinguish idents in `name == name`
137+
inside_vweb_tmpl bool
138+
inside_return bool
139+
inside_or_block bool
140+
strs_to_free0 []string // strings.Builder
143141
// strs_to_free []string // strings.Builder
144142
inside_call bool
145143
has_main bool

vlib/v/gen/c/fn.v

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,18 +141,18 @@ fn (mut g Gen) gen_fn_decl(node &ast.FnDecl, skip bool) {
141141
// if g.fileis('vweb.v') {
142142
// println('\ngen_fn_decl() $node.name $node.is_generic $g.cur_generic_type')
143143
// }
144-
if node.generic_names.len > 0 && g.cur_concrete_types.len == 0 { // need the cur_concrete_type check to avoid inf. recursion
144+
if node.generic_names.len > 0 && g.table.cur_concrete_types.len == 0 { // need the cur_concrete_type check to avoid inf. recursion
145145
// loop thru each generic type and generate a function
146146
for concrete_types in g.table.fn_generic_types[node.name] {
147147
if g.pref.is_verbose {
148148
syms := concrete_types.map(g.table.get_type_symbol(it))
149149
the_type := syms.map(node.name).join(', ')
150150
println('gen fn `$node.name` for type `$the_type`')
151151
}
152-
g.cur_concrete_types = concrete_types
152+
g.table.cur_concrete_types = concrete_types
153153
g.gen_fn_decl(node, skip)
154154
}
155-
g.cur_concrete_types = []
155+
g.table.cur_concrete_types = []
156156
return
157157
}
158158
cur_fn_save := g.table.cur_fn
@@ -190,11 +190,11 @@ fn (mut g Gen) gen_fn_decl(node &ast.FnDecl, skip bool) {
190190
name = c_name(name)
191191
}
192192
mut type_name := g.typ(node.return_type)
193-
if g.cur_concrete_types.len > 0 {
193+
if g.table.cur_concrete_types.len > 0 {
194194
// foo<T>() => foo_T_int(), foo_T_string() etc
195195
// Using _T_ to differentiate between get<string> and get_string
196196
name += '_T'
197-
for concrete_type in g.cur_concrete_types {
197+
for concrete_type in g.table.cur_concrete_types {
198198
gen_name := g.typ(concrete_type)
199199
name += '_' + gen_name
200200
}
@@ -504,7 +504,7 @@ fn (mut g Gen) call_expr(node ast.CallExpr) {
504504
pub fn (mut g Gen) unwrap_generic(typ ast.Type) ast.Type {
505505
if typ.has_flag(.generic) {
506506
if t_typ := g.table.resolve_generic_to_concrete(typ, g.table.cur_fn.generic_names,
507-
g.cur_concrete_types, false)
507+
g.table.cur_concrete_types, false)
508508
{
509509
return t_typ
510510
}

0 commit comments

Comments
 (0)