all: move cur_concrete_types to Table (#10269)
parent
9fc5b9dc54
commit
cb19079d53
|
@ -29,6 +29,7 @@ pub mut:
|
||||||
panic_userdata voidptr = voidptr(0) // can be used to pass arbitrary data to panic_handler;
|
panic_userdata voidptr = voidptr(0) // can be used to pass arbitrary data to panic_handler;
|
||||||
panic_npanics int
|
panic_npanics int
|
||||||
cur_fn &FnDecl = 0 // previously stored in Checker.cur_fn and Gen.cur_fn
|
cur_fn &FnDecl = 0 // previously stored in Checker.cur_fn and Gen.cur_fn
|
||||||
|
cur_concrete_types []Type // current concrete types, e.g. <int, string>
|
||||||
gostmts int // how many `go` statements there were in the parsed files.
|
gostmts int // how many `go` statements there were in the parsed files.
|
||||||
// When table.gostmts > 0, __VTHREADS__ is defined, which can be checked with `$if threads {`
|
// When table.gostmts > 0, __VTHREADS__ is defined, which can be checked with `$if threads {`
|
||||||
}
|
}
|
||||||
|
|
|
@ -508,9 +508,9 @@ pub fn (mut c Checker) infer_fn_generic_types(f ast.Fn, mut call_expr ast.CallEx
|
||||||
info := sym.info as ast.Struct
|
info := sym.info as ast.Struct
|
||||||
if c.table.cur_fn.generic_names.len > 0 { // in generic fn
|
if c.table.cur_fn.generic_names.len > 0 { // in generic fn
|
||||||
if gt_name in c.table.cur_fn.generic_names
|
if gt_name in c.table.cur_fn.generic_names
|
||||||
&& c.table.cur_fn.generic_names.len == c.cur_concrete_types.len {
|
&& c.table.cur_fn.generic_names.len == c.table.cur_concrete_types.len {
|
||||||
idx := c.table.cur_fn.generic_names.index(gt_name)
|
idx := c.table.cur_fn.generic_names.index(gt_name)
|
||||||
typ = c.cur_concrete_types[idx]
|
typ = c.table.cur_concrete_types[idx]
|
||||||
}
|
}
|
||||||
} else { // in non-generic fn
|
} else { // in non-generic fn
|
||||||
receiver_generic_names := info.generic_types.map(c.table.get_type_symbol(it).name)
|
receiver_generic_names := info.generic_types.map(c.table.get_type_symbol(it).name)
|
||||||
|
|
|
@ -49,7 +49,6 @@ pub mut:
|
||||||
error_lines []int // to avoid printing multiple errors for the same line
|
error_lines []int // to avoid printing multiple errors for the same line
|
||||||
expected_type ast.Type
|
expected_type ast.Type
|
||||||
expected_or_type ast.Type // fn() or { 'this type' } eg. string. expected or block type
|
expected_or_type ast.Type // fn() or { 'this type' } eg. string. expected or block type
|
||||||
// cur_fn &ast.FnDecl // current function
|
|
||||||
const_decl string
|
const_decl string
|
||||||
const_deps []string
|
const_deps []string
|
||||||
const_names []string
|
const_names []string
|
||||||
|
@ -82,7 +81,6 @@ mut:
|
||||||
timers &util.Timers = util.new_timers(false)
|
timers &util.Timers = util.new_timers(false)
|
||||||
comptime_fields_type map[string]ast.Type
|
comptime_fields_type map[string]ast.Type
|
||||||
fn_scope &ast.Scope = voidptr(0)
|
fn_scope &ast.Scope = voidptr(0)
|
||||||
cur_concrete_types []ast.Type // current concrete types, e.g. <int, string>
|
|
||||||
main_fn_decl_node ast.FnDecl
|
main_fn_decl_node ast.FnDecl
|
||||||
match_exhaustive_cutoff_limit int = 10
|
match_exhaustive_cutoff_limit int = 10
|
||||||
// TODO: these are here temporarily and used for deprecations; remove soon
|
// 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 {
|
||||||
struct_sym := c.table.get_type_symbol(struct_init.typ)
|
struct_sym := c.table.get_type_symbol(struct_init.typ)
|
||||||
if struct_sym.info is ast.Struct {
|
if struct_sym.info is ast.Struct {
|
||||||
if struct_sym.info.generic_types.len > 0 && struct_sym.info.concrete_types.len == 0
|
if struct_sym.info.generic_types.len > 0 && struct_sym.info.concrete_types.len == 0
|
||||||
&& c.cur_concrete_types.len == 0 {
|
&& c.table.cur_concrete_types.len == 0 {
|
||||||
c.error('generic struct init must specify type parameter, e.g. Foo<int>',
|
c.error('generic struct init must specify type parameter, e.g. Foo<int>',
|
||||||
struct_init.pos)
|
struct_init.pos)
|
||||||
}
|
}
|
||||||
|
@ -704,7 +702,7 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) ast.Type {
|
||||||
return ast.void_type
|
return ast.void_type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
utyp := c.unwrap_generic_struct(struct_init.typ, c.table.cur_fn.generic_names, c.cur_concrete_types)
|
utyp := c.unwrap_generic_struct(struct_init.typ, c.table.cur_fn.generic_names, c.table.cur_concrete_types)
|
||||||
c.ensure_type_exists(utyp, struct_init.pos) or {}
|
c.ensure_type_exists(utyp, struct_init.pos) or {}
|
||||||
type_sym := c.table.get_type_symbol(utyp)
|
type_sym := c.table.get_type_symbol(utyp)
|
||||||
if !c.inside_unsafe && type_sym.kind == .sum_type {
|
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 {
|
||||||
// Make sure the first letter is capital, do not allow e.g. `x := string{}`,
|
// Make sure the first letter is capital, do not allow e.g. `x := string{}`,
|
||||||
// but `x := T{}` is ok.
|
// but `x := T{}` is ok.
|
||||||
if !c.is_builtin_mod && !c.inside_unsafe && type_sym.language == .v
|
if !c.is_builtin_mod && !c.inside_unsafe && type_sym.language == .v
|
||||||
&& c.cur_concrete_types.len == 0 {
|
&& c.table.cur_concrete_types.len == 0 {
|
||||||
pos := type_sym.name.last_index('.') or { -1 }
|
pos := type_sym.name.last_index('.') or { -1 }
|
||||||
first_letter := type_sym.name[pos + 1]
|
first_letter := type_sym.name[pos + 1]
|
||||||
if !first_letter.is_capital() {
|
if !first_letter.is_capital() {
|
||||||
|
@ -2220,7 +2218,7 @@ pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type {
|
||||||
concrete_types << concrete_type
|
concrete_types << concrete_type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !isnil(c.table.cur_fn) && c.cur_concrete_types.len == 0 && has_generic {
|
if !isnil(c.table.cur_fn) && c.table.cur_concrete_types.len == 0 && has_generic {
|
||||||
c.error('generic fn using generic types cannot be called outside of generic fn',
|
c.error('generic fn using generic types cannot be called outside of generic fn',
|
||||||
call_expr.pos)
|
call_expr.pos)
|
||||||
}
|
}
|
||||||
|
@ -2981,7 +2979,7 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) {
|
||||||
mut expected_type := c.unwrap_generic(c.expected_type)
|
mut expected_type := c.unwrap_generic(c.expected_type)
|
||||||
if expected_type.has_flag(.generic) && c.table.get_type_symbol(expected_type).kind == .struct_ {
|
if expected_type.has_flag(.generic) && c.table.get_type_symbol(expected_type).kind == .struct_ {
|
||||||
if t_typ := c.table.resolve_generic_to_concrete(expected_type, c.table.cur_fn.generic_names,
|
if t_typ := c.table.resolve_generic_to_concrete(expected_type, c.table.cur_fn.generic_names,
|
||||||
c.cur_concrete_types, true)
|
c.table.cur_concrete_types, true)
|
||||||
{
|
{
|
||||||
expected_type = t_typ
|
expected_type = t_typ
|
||||||
}
|
}
|
||||||
|
@ -3004,7 +3002,7 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) {
|
||||||
mut expected_types := [expected_type]
|
mut expected_types := [expected_type]
|
||||||
if expected_type_sym.info is ast.MultiReturn {
|
if expected_type_sym.info is ast.MultiReturn {
|
||||||
expected_types = expected_type_sym.info.types
|
expected_types = expected_type_sym.info.types
|
||||||
if c.cur_concrete_types.len > 0 {
|
if c.table.cur_concrete_types.len > 0 {
|
||||||
expected_types = expected_types.map(c.unwrap_generic(it))
|
expected_types = expected_types.map(c.unwrap_generic(it))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4561,7 +4559,7 @@ fn (mut c Checker) stmts(stmts []ast.Stmt) {
|
||||||
pub fn (mut c Checker) unwrap_generic(typ ast.Type) ast.Type {
|
pub fn (mut c Checker) unwrap_generic(typ ast.Type) ast.Type {
|
||||||
if typ.has_flag(.generic) {
|
if typ.has_flag(.generic) {
|
||||||
if t_typ := c.table.resolve_generic_to_concrete(typ, c.table.cur_fn.generic_names,
|
if t_typ := c.table.resolve_generic_to_concrete(typ, c.table.cur_fn.generic_names,
|
||||||
c.cur_concrete_types, false)
|
c.table.cur_concrete_types, false)
|
||||||
{
|
{
|
||||||
return t_typ
|
return t_typ
|
||||||
}
|
}
|
||||||
|
@ -7063,7 +7061,7 @@ fn (mut c Checker) post_process_generic_fns() {
|
||||||
mut node := c.file.generic_fns[i]
|
mut node := c.file.generic_fns[i]
|
||||||
c.mod = node.mod
|
c.mod = node.mod
|
||||||
for concrete_types in c.table.fn_generic_types[node.name] {
|
for concrete_types in c.table.fn_generic_types[node.name] {
|
||||||
c.cur_concrete_types = concrete_types
|
c.table.cur_concrete_types = concrete_types
|
||||||
c.fn_decl(mut node)
|
c.fn_decl(mut node)
|
||||||
if node.name == 'vweb.run' {
|
if node.name == 'vweb.run' {
|
||||||
for ct in concrete_types {
|
for ct in concrete_types {
|
||||||
|
@ -7073,13 +7071,13 @@ fn (mut c Checker) post_process_generic_fns() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.cur_concrete_types = []
|
c.table.cur_concrete_types = []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
|
fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
|
||||||
c.returns = false
|
c.returns = false
|
||||||
if node.generic_names.len > 0 && c.cur_concrete_types.len == 0 {
|
if node.generic_names.len > 0 && c.table.cur_concrete_types.len == 0 {
|
||||||
// Just remember the generic function for now.
|
// Just remember the generic function for now.
|
||||||
// It will be processed later in c.post_process_generic_fns,
|
// It will be processed later in c.post_process_generic_fns,
|
||||||
// after all other normal functions are processed.
|
// after all other normal functions are processed.
|
||||||
|
|
|
@ -124,8 +124,6 @@ mut:
|
||||||
is_builtin_mod bool
|
is_builtin_mod bool
|
||||||
hotcode_fn_names []string
|
hotcode_fn_names []string
|
||||||
embedded_files []ast.EmbeddedFile
|
embedded_files []ast.EmbeddedFile
|
||||||
// cur_fn ast.FnDecl
|
|
||||||
cur_concrete_types []ast.Type // current concrete types, e.g. <int, string>
|
|
||||||
sql_i int
|
sql_i int
|
||||||
sql_stmt_name string
|
sql_stmt_name string
|
||||||
sql_bind_name string
|
sql_bind_name string
|
||||||
|
|
|
@ -141,7 +141,7 @@ fn (mut g Gen) gen_fn_decl(node &ast.FnDecl, skip bool) {
|
||||||
// if g.fileis('vweb.v') {
|
// if g.fileis('vweb.v') {
|
||||||
// println('\ngen_fn_decl() $node.name $node.is_generic $g.cur_generic_type')
|
// println('\ngen_fn_decl() $node.name $node.is_generic $g.cur_generic_type')
|
||||||
// }
|
// }
|
||||||
if node.generic_names.len > 0 && g.cur_concrete_types.len == 0 { // need the cur_concrete_type check to avoid inf. recursion
|
if node.generic_names.len > 0 && g.table.cur_concrete_types.len == 0 { // need the cur_concrete_type check to avoid inf. recursion
|
||||||
// loop thru each generic type and generate a function
|
// loop thru each generic type and generate a function
|
||||||
for concrete_types in g.table.fn_generic_types[node.name] {
|
for concrete_types in g.table.fn_generic_types[node.name] {
|
||||||
if g.pref.is_verbose {
|
if g.pref.is_verbose {
|
||||||
|
@ -149,10 +149,10 @@ fn (mut g Gen) gen_fn_decl(node &ast.FnDecl, skip bool) {
|
||||||
the_type := syms.map(node.name).join(', ')
|
the_type := syms.map(node.name).join(', ')
|
||||||
println('gen fn `$node.name` for type `$the_type`')
|
println('gen fn `$node.name` for type `$the_type`')
|
||||||
}
|
}
|
||||||
g.cur_concrete_types = concrete_types
|
g.table.cur_concrete_types = concrete_types
|
||||||
g.gen_fn_decl(node, skip)
|
g.gen_fn_decl(node, skip)
|
||||||
}
|
}
|
||||||
g.cur_concrete_types = []
|
g.table.cur_concrete_types = []
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cur_fn_save := g.table.cur_fn
|
cur_fn_save := g.table.cur_fn
|
||||||
|
@ -190,11 +190,11 @@ fn (mut g Gen) gen_fn_decl(node &ast.FnDecl, skip bool) {
|
||||||
name = c_name(name)
|
name = c_name(name)
|
||||||
}
|
}
|
||||||
mut type_name := g.typ(node.return_type)
|
mut type_name := g.typ(node.return_type)
|
||||||
if g.cur_concrete_types.len > 0 {
|
if g.table.cur_concrete_types.len > 0 {
|
||||||
// foo<T>() => foo_T_int(), foo_T_string() etc
|
// foo<T>() => foo_T_int(), foo_T_string() etc
|
||||||
// Using _T_ to differentiate between get<string> and get_string
|
// Using _T_ to differentiate between get<string> and get_string
|
||||||
name += '_T'
|
name += '_T'
|
||||||
for concrete_type in g.cur_concrete_types {
|
for concrete_type in g.table.cur_concrete_types {
|
||||||
gen_name := g.typ(concrete_type)
|
gen_name := g.typ(concrete_type)
|
||||||
name += '_' + gen_name
|
name += '_' + gen_name
|
||||||
}
|
}
|
||||||
|
@ -504,7 +504,7 @@ fn (mut g Gen) call_expr(node ast.CallExpr) {
|
||||||
pub fn (mut g Gen) unwrap_generic(typ ast.Type) ast.Type {
|
pub fn (mut g Gen) unwrap_generic(typ ast.Type) ast.Type {
|
||||||
if typ.has_flag(.generic) {
|
if typ.has_flag(.generic) {
|
||||||
if t_typ := g.table.resolve_generic_to_concrete(typ, g.table.cur_fn.generic_names,
|
if t_typ := g.table.resolve_generic_to_concrete(typ, g.table.cur_fn.generic_names,
|
||||||
g.cur_concrete_types, false)
|
g.table.cur_concrete_types, false)
|
||||||
{
|
{
|
||||||
return t_typ
|
return t_typ
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue