ast: improve Type and TypeFlag related operations (#22107)

This commit is contained in:
Delyan Angelov 2024-08-23 20:58:57 +03:00 committed by GitHub
parent 637291da16
commit 19c567047e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 98 additions and 90 deletions

View File

@ -76,7 +76,6 @@ pub fn (mut t Table) free() {
}
}
pub const invalid_type_idx = -1
pub const fn_type_escape_seq = [' ', '', '(', '_', ')', '']
pub const map_cname_escape_seq = ['[', '_T_', ', ', '_', ']', '']
@ -768,7 +767,7 @@ fn (mut t Table) rewrite_already_registered_symbol(typ TypeSymbol, existing_idx
}
return existing_idx
}
return ast.invalid_type_idx
return invalid_type_idx
}
@[inline]
@ -1559,7 +1558,7 @@ pub fn (mut t Table) resolve_generic_static_type_name(fn_name string, generic_na
valid_generic := util.is_generic_type_name(generic_name)
&& generic_name in generic_names
if valid_generic {
name_type := Type(t.find_type_idx(generic_name)).set_flag(.generic)
name_type := idx_to_type(t.find_type_idx(generic_name)).set_flag(.generic)
if typ := t.resolve_generic_to_concrete(name_type, generic_names, concrete_types) {
return '${t.type_to_str(typ)}${fn_name[index..]}'
}

View File

@ -15,7 +15,12 @@ import strings
import v.pref
import v.token
pub type Type = int
pub type Type = u32
@[inline]
pub fn idx_to_type(idx int) Type {
return Type(u32(idx))
}
pub struct UnknownTypeInfo {}
@ -110,13 +115,13 @@ pub mut:
}
// max of 8
pub enum TypeFlag {
option
result
variadic
generic
shared_f
atomic_f
pub enum TypeFlag as u32 {
option = 1 << 24
result = 1 << 25
variadic = 1 << 26
generic = 1 << 27
shared_f = 1 << 28
atomic_f = 1 << 29
}
/*
@ -307,7 +312,7 @@ pub fn (t Type) is_full() bool {
// return nr_muls for `t`
@[inline]
pub fn (t Type) nr_muls() int {
return (int(t) >> 16) & 0xff
return (t >> 16) & 0xff
}
// return true if `t` is a pointer (nr_muls>0)
@ -315,7 +320,7 @@ pub fn (t Type) nr_muls() int {
pub fn (t Type) is_ptr() bool {
// any normal pointer, i.e. &Type, &&Type etc;
// Note: voidptr, charptr and byteptr are NOT included!
return (int(t) >> 16) & 0xff != 0
return (t >> 16) & 0xff != 0
}
// is_pointer returns true if `typ` is any of the builtin pointer types (voidptr, byteptr, charptr)
@ -334,7 +339,7 @@ pub fn (typ Type) is_voidptr() bool {
// is_any_kind_of_pointer returns true if t is any type of pointer
@[inline]
pub fn (t Type) is_any_kind_of_pointer() bool {
return (int(t) >> 16) & 0xff != 0 || (u16(t) & 0xffff) in ast.pointer_type_idxs
return (t >> 16) & 0xff != 0 || (u16(t) & 0xffff) in ast.pointer_type_idxs
}
// set nr_muls on `t` and return it
@ -343,50 +348,56 @@ pub fn (t Type) set_nr_muls(nr_muls int) Type {
if nr_muls < 0 || nr_muls > 255 {
panic('set_nr_muls: nr_muls must be between 0 & 255')
}
return int(t) & 0xff00ffff | int(u32(nr_muls) << 16)
return t & 0xff00ffff | u32(nr_muls) << 16
}
// increments nr_muls on `t` and return it
@[inline]
pub fn (t Type) ref() Type {
nr_muls := (int(t) >> 16) & 0xff
nr_muls := (t >> 16) & 0xff
if nr_muls == 255 {
panic('ref: nr_muls is already at max of 255')
}
return int(t) & 0xff00ffff | int(u32(nr_muls + 1) << 16)
return t & 0xff00ffff | (nr_muls + 1) << 16
}
// decrement nr_muls on `t` and return it
@[inline]
pub fn (t Type) deref() Type {
nr_muls := (int(t) >> 16) & 0xff
nr_muls := (t >> 16) & 0xff
if nr_muls == 0 {
panic('deref: type `${t}` is not a pointer')
}
return int(t) & 0xff00ffff | int(u32(nr_muls - 1) << 16)
return t & 0xff00ffff | (nr_muls - 1) << 16
}
// set `flag` on `t` and return `t`
// has_flag returns whether the given named `flag` is set
@[inline]
pub fn (t Type) has_flag(flag TypeFlag) bool {
return (t & u32(flag)) != 0
}
// set_flag returns a new type, that is like the input `t`, but with the named `flag` set
@[inline]
pub fn (t Type) set_flag(flag TypeFlag) Type {
return int(t) | (1 << (int(flag) + 24))
return t | u32(flag)
}
// clear `flag` on `t` and return `t`
// clear_flag returns a new type, that is like `t`, but with the named `flag` cleared
@[inline]
pub fn (t Type) clear_flag(flag TypeFlag) Type {
return int(t) & ~(1 << (int(flag) + 24))
return t & ~(u32(flag))
}
// clear all flags or multi flags
// clear_flags returns a new type, based on `t`, but with cleared named `flags`
@[inline]
pub fn (t Type) clear_flags(flags ...TypeFlag) Type {
if flags.len == 0 {
return int(t) & 0xffffff
return t & 0xffffff
} else {
mut typ := int(t)
for flag in flags {
typ = typ & ~(1 << (int(flag) + 24))
typ = typ & ~(u32(flag))
}
return typ
}
@ -395,18 +406,12 @@ pub fn (t Type) clear_flags(flags ...TypeFlag) Type {
// clear option and result flags
@[inline]
pub fn (t Type) clear_option_and_result() Type {
return u32(t) & ~0x0300_0000
}
// return true if `flag` is set on `t`
@[inline]
pub fn (t Type) has_flag(flag TypeFlag) bool {
return int(t) & (1 << (int(flag) + 24)) != 0
return t & ~0x0300_0000
}
@[inline]
pub fn (t Type) has_option_or_result() bool {
return u32(t) & 0x0300_0000 != 0
return t & 0x0300_0000 != 0
}
// debug returns a verbose representation of the information in ts, useful for tracing/debugging
@ -594,6 +599,8 @@ pub fn (typ Type) is_bool() bool {
return typ.idx() == ast.bool_type_idx
}
pub const invalid_type_idx = -1
pub const no_type_idx = 0
pub const void_type_idx = 1
pub const voidptr_type_idx = 2
pub const byteptr_type_idx = 3
@ -651,6 +658,8 @@ pub const number_type_idxs = [i8_type_idx, i16_type_idx, int_type_idx, i32_type_
rune_type_idx]
pub const pointer_type_idxs = [voidptr_type_idx, byteptr_type_idx, charptr_type_idx, nil_type_idx]
pub const invalid_type = idx_to_type(invalid_type_idx) // -1 is a purposefully invalid type, not by default, but to signify checker errors
pub const no_type = idx_to_type(no_type_idx) // 0 is an invalid type, but it is useful for initialising default ast.Type values, in fields or before loops
pub const void_type = new_type(void_type_idx)
pub const ovoid_type = new_type(void_type_idx).set_flag(.option) // the return type of `fn ()?`
pub const rvoid_type = new_type(void_type_idx).set_flag(.result) // the return type of `fn () !`

View File

@ -575,7 +575,7 @@ fn (mut c Checker) check_shift(mut node ast.InfixExpr, left_type_ ast.Type, righ
// part of the quotient of E1/2^E2. If E1 has a signed type and
// a negative value, the resulting value is implementation-defined (ID).
left_sym_final := c.table.final_sym(left_type)
left_type_final := ast.Type(left_sym_final.idx)
left_type_final := ast.idx_to_type(left_sym_final.idx)
if !(c.is_generated || c.inside_unsafe || c.file.is_translated || c.pref.translated) {
if node.op == .left_shift && left_type_final.is_signed() {
c.note('shifting a value from a signed type `${left_sym_final.name}` can change the sign',

View File

@ -507,7 +507,7 @@ fn (mut c Checker) check_valid_pascal_case(name string, identifier string, pos t
}
fn (mut c Checker) type_decl(node ast.TypeDecl) {
if node.typ == ast.invalid_type_idx && (node is ast.AliasTypeDecl || node is ast.SumTypeDecl) {
if node.typ == ast.invalid_type && (node is ast.AliasTypeDecl || node is ast.SumTypeDecl) {
typ_desc := if node is ast.AliasTypeDecl { 'alias' } else { 'sum type' }
c.error('cannot register ${typ_desc} `${node.name}`, another type with this name exists',
node.pos)
@ -852,7 +852,7 @@ fn (mut c Checker) fail_if_immutable(mut expr ast.Expr) (string, token.Pos) {
return to_lock, pos
}
left_sym := c.table.sym(expr.left_type)
mut elem_type := ast.Type(0)
mut elem_type := ast.no_type
mut kind := ''
match left_sym.info {
ast.Array {
@ -1469,7 +1469,7 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
valid_generic := util.is_generic_type_name(name) && c.table.cur_fn != unsafe { nil }
&& name in c.table.cur_fn.generic_names
if valid_generic {
name_type = ast.Type(c.table.find_type_idx(name)).set_flag(.generic)
name_type = ast.idx_to_type(c.table.find_type_idx(name)).set_flag(.generic)
}
}
ast.TypeOf {
@ -1813,7 +1813,7 @@ fn (mut c Checker) const_decl(mut node ast.ConstDecl) {
fn (mut c Checker) enum_decl(mut node ast.EnumDecl) {
c.check_valid_pascal_case(node.name, 'enum name', node.pos)
if node.typ == ast.invalid_type_idx {
if node.typ == ast.invalid_type {
c.error('cannot register enum `${node.name}`, another type with this name exists',
node.pos)
return

View File

@ -265,7 +265,7 @@ fn (mut c Checker) comptime_for(mut node ast.ComptimeFor) {
c.push_new_comptime_info()
c.comptime.inside_comptime_for = true
if c.field_data_type == 0 {
c.field_data_type = ast.Type(c.table.find_type_idx('FieldData'))
c.field_data_type = ast.idx_to_type(c.table.find_type_idx('FieldData'))
}
c.comptime.comptime_for_field_value = field
c.comptime.comptime_for_field_var = node.val_var
@ -298,7 +298,7 @@ fn (mut c Checker) comptime_for(mut node ast.ComptimeFor) {
c.push_new_comptime_info()
c.comptime.inside_comptime_for = true
if c.enum_data_type == 0 {
c.enum_data_type = ast.Type(c.table.find_type_idx('EnumData'))
c.enum_data_type = ast.idx_to_type(c.table.find_type_idx('EnumData'))
}
c.comptime.comptime_for_enum_var = node.val_var
c.comptime.type_map[node.val_var] = c.enum_data_type
@ -327,7 +327,7 @@ fn (mut c Checker) comptime_for(mut node ast.ComptimeFor) {
}
} else if node.kind == .variants {
if c.variant_data_type == 0 {
c.variant_data_type = ast.Type(c.table.find_type_idx('VariantData'))
c.variant_data_type = ast.idx_to_type(c.table.find_type_idx('VariantData'))
}
mut variants := []ast.Type{}
if c.comptime.comptime_for_field_var != '' && typ == c.field_data_type {

View File

@ -323,7 +323,7 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
}
}
}
if node.return_type != ast.Type(0) {
if node.return_type != ast.no_type {
if !c.ensure_type_exists(node.return_type, node.return_type_pos) {
return
}
@ -886,7 +886,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast.
node.name = ''
c.expr(mut node.left)
left := node.left as ast.AnonFn
if left.typ != ast.Type(0) {
if left.typ != ast.no_type {
anon_fn_sym := c.table.sym(left.typ)
func = (anon_fn_sym.info as ast.FnType).func
found = true
@ -1011,7 +1011,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast.
return ast.void_type
}
ret_typ := ast.Type(idx).set_flag(.option)
ret_typ := ast.idx_to_type(idx).set_flag(.option)
if node.args.len != 1 {
c.error('expected 1 argument, but got ${node.args.len}', node.pos)
} else {
@ -2103,7 +2103,7 @@ fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
}
ast.Array {
typ := c.table.unaliased_type(final_left_sym.info.elem_type)
parent_type = ast.Type(c.table.find_or_register_array(typ))
parent_type = ast.idx_to_type(c.table.find_or_register_array(typ))
}
else {}
}
@ -2357,7 +2357,7 @@ fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
node.should_be_skipped = c.evaluate_once_comptime_if_attribute(mut method.attrs[method.ctdefine_idx])
}
c.check_expected_arg_count(mut node, method) or { return method.return_type }
mut exp_arg_typ := ast.Type(0) // type of 1st arg for special builtin methods
mut exp_arg_typ := ast.no_type // type of 1st arg for special builtin methods
mut param_is_mut := false
mut no_type_promotion := false
if left_sym.info is ast.Chan {
@ -2371,7 +2371,7 @@ fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
}
for i, mut arg in node.args {
if i > 0 || exp_arg_typ == ast.Type(0) {
if i > 0 || exp_arg_typ == ast.no_type {
exp_arg_typ = if method.is_variadic && i >= method.params.len - 1 {
method.params.last().typ
} else {
@ -3021,7 +3021,7 @@ fn (mut c Checker) map_builtin_method_call(mut node ast.CallExpr, left_type_ ast
} else {
c.table.find_or_register_array(info.value_type)
}
ret_type = ast.Type(typ)
ret_type = ast.idx_to_type(typ)
if info.key_type.has_flag(.generic) && method_name == 'keys' {
ret_type = ret_type.set_flag(.generic)
}

View File

@ -570,15 +570,15 @@ fn (mut c Checker) smartcast_if_conds(mut node ast.Expr, mut scope ast.Scope) {
c.comptime.type_map['${c.comptime.comptime_for_variant_var}.typ']
} else {
c.error('invalid type `${right_expr}`', right_expr.pos)
ast.Type(0)
ast.no_type
}
}
else {
c.error('invalid type `${right_expr}`', right_expr.pos())
ast.Type(0)
ast.no_type
}
}
if right_type != ast.Type(0) {
if right_type != ast.no_type {
right_sym := c.table.sym(right_type)
mut expr_type := c.unwrap_generic(node.left_type)
left_sym := c.table.sym(expr_type)

View File

@ -731,15 +731,15 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
c.comptime.type_map['${c.comptime.comptime_for_variant_var}.typ']
} else {
c.error('invalid type `${right_expr}`', right_expr.pos)
ast.Type(0)
ast.no_type
}
}
else {
c.error('invalid type `${right_expr}`', right_expr.pos())
ast.Type(0)
ast.no_type
}
}
if typ != ast.Type(0) {
if typ != ast.no_type {
typ_sym := c.table.sym(typ)
op := node.op.str()
if typ_sym.kind == .placeholder {

View File

@ -460,7 +460,7 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym ast.TypeSym
// when match is type matching, then register smart cast for every branch
if expr_types.len > 0 {
if cond_type_sym.kind in [.sum_type, .interface_] {
mut expr_type := ast.Type(0)
mut expr_type := ast.no_type
if expr_types.len > 1 {
mut agg_name := strings.new_builder(20)
mut agg_cname := strings.new_builder(20)

View File

@ -636,7 +636,7 @@ fn (mut c Checker) check_orm_or_expr(mut expr ORMExpr) {
// check_db_expr checks the `db_expr` implements `orm.Connection` and has no `option` flag.
fn (mut c Checker) check_db_expr(mut db_expr ast.Expr) bool {
connection_type_index := c.table.find_type_idx('orm.Connection')
connection_typ := ast.Type(connection_type_index)
connection_typ := ast.idx_to_type(connection_type_index)
db_expr_type := c.expr(mut db_expr)
// If we didn't find `orm.Connection`, we don't have any imported modules
@ -678,7 +678,7 @@ fn (c &Checker) get_field_foreign_table_type(table_field &ast.StructField) ast.T
} else if c.table.sym(table_field.typ).kind == .array {
return c.table.sym(table_field.typ).array_info().elem_type
} else {
return ast.Type(0)
return ast.no_type
}
}

View File

@ -633,8 +633,8 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini
continue
}
}
mut got_type := ast.Type(0)
mut exp_type := ast.Type(0)
mut got_type := ast.no_type
mut exp_type := ast.no_type
inited_fields << field_name
exp_type = field_info.typ
exp_type_sym := c.table.sym(exp_type)

View File

@ -1028,7 +1028,7 @@ pub fn (mut f Fmt) enum_decl(node ast.EnumDecl) {
f.write('pub ')
}
mut name := node.name.after('.')
if node.typ != ast.int_type && node.typ != ast.invalid_type_idx {
if node.typ != ast.int_type && node.typ != ast.invalid_type {
senum_type := f.table.type_to_str_using_aliases(node.typ, f.mod2alias)
name += ' as ${senum_type}'
}

View File

@ -485,8 +485,8 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
}
mut str_add := false
mut op_overloaded := false
mut op_expected_left := ast.Type(0)
mut op_expected_right := ast.Type(0)
mut op_expected_left := ast.no_type
mut op_expected_right := ast.no_type
is_shared_re_assign := !is_decl && node.left_types[i].has_flag(.shared_f)
&& left is ast.Ident && left_sym.kind in [.array, .map, .struct_]
if node.op == .plus_assign && unaliased_right_sym.kind == .string {

View File

@ -1255,9 +1255,9 @@ fn (mut g Gen) get_enum_type_idx_from_fn_name(fn_name string) (string, int) {
}
fn (mut g Gen) gen_enum_static_from_string(fn_name string, mod_enum_name string, idx int) {
enum_typ := ast.Type(idx)
enum_typ := ast.idx_to_type(idx)
enum_styp := g.typ(enum_typ)
option_enum_typ := ast.Type(idx).set_flag(.option)
option_enum_typ := enum_typ.set_flag(.option)
option_enum_styp := g.typ(option_enum_typ)
enum_field_names := g.table.get_enum_field_names(mod_enum_name)
enum_field_vals := g.table.get_enum_field_vals(mod_enum_name)

View File

@ -325,9 +325,9 @@ pub fn gen(files []&ast.File, mut table ast.Table, pref_ &pref.Preferences) (str
label: 'global_cgen'
)
inner_loop: unsafe { &ast.empty_stmt }
field_data_type: ast.Type(table.find_type_idx('FieldData'))
enum_data_type: ast.Type(table.find_type_idx('EnumData'))
variant_data_type: ast.Type(table.find_type_idx('VariantData'))
field_data_type: ast.idx_to_type(table.find_type_idx('FieldData'))
enum_data_type: ast.idx_to_type(table.find_type_idx('EnumData'))
variant_data_type: ast.idx_to_type(table.find_type_idx('VariantData'))
is_cc_msvc: pref_.ccompiler == 'msvc'
use_segfault_handler: !('no_segfault_handler' in pref_.compile_defines
|| pref_.os in [.wasm32, .wasm32_emscripten])
@ -715,8 +715,8 @@ fn cgen_process_one_file_cb(mut p pool.PoolProcessor, idx int, wid int) &Gen {
label: 'cgen_process_one_file_cb idx: ${idx}, wid: ${wid}'
)
inner_loop: &ast.empty_stmt
field_data_type: ast.Type(global_g.table.find_type_idx('FieldData'))
enum_data_type: ast.Type(global_g.table.find_type_idx('EnumData'))
field_data_type: ast.idx_to_type(global_g.table.find_type_idx('FieldData'))
enum_data_type: ast.idx_to_type(global_g.table.find_type_idx('EnumData'))
array_sort_fn: global_g.array_sort_fn
waiter_fns: global_g.waiter_fns
threaded_fns: global_g.threaded_fns
@ -1175,7 +1175,7 @@ fn (mut g Gen) option_type_name(t ast.Type) (string, string) {
} else {
styp = '${c.option_name}_${base}'
}
if t.is_ptr() || t.has_flag(.generic) {
if t.has_flag(.generic) || t.is_ptr() {
styp = styp.replace('*', '_ptr')
}
return styp, base
@ -1197,7 +1197,7 @@ fn (mut g Gen) result_type_name(t ast.Type) (string, string) {
} else {
styp = '${c.result_name}_${base}'
}
if t.is_ptr() || t.has_flag(.generic) {
if t.has_flag(.generic) || t.is_ptr() {
styp = styp.replace('*', '_ptr')
}
return styp, base
@ -2426,13 +2426,13 @@ fn (mut g Gen) get_sumtype_casting_fn(got_ ast.Type, exp_ ast.Type) string {
g.sumtype_casting_fns << SumtypeCastingFn{
fn_name: fn_name
got: if got_.has_flag(.option) {
new_got := ast.Type(got_sym.idx).set_flag(.option)
new_got := ast.idx_to_type(got_sym.idx).set_flag(.option)
new_got
} else {
got_sym.idx
}
exp: if exp_.has_flag(.option) {
new_exp := ast.Type(exp).set_flag(.option)
new_exp := ast.idx_to_type(exp).set_flag(.option)
new_exp
} else {
exp

View File

@ -102,7 +102,7 @@ fn (mut g Gen) dump_expr_definitions() {
name = name[3..]
}
_, str_method_expects_ptr, _ := dump_sym.str_method_info()
typ := ast.Type(dump_type)
typ := ast.idx_to_type(dump_type)
is_ptr := typ.is_ptr()
deref, _ := deref_kind(str_method_expects_ptr, is_ptr, dump_type)
to_string_fn_name := g.get_str_fn(typ.clear_flags(.shared_f, .result))

View File

@ -1543,7 +1543,7 @@ fn (mut g Gen) resolve_receiver_type(node ast.CallExpr) (ast.Type, &ast.TypeSymb
typ := g.table.unaliased_type(typ_sym.info.elem_type)
typ_idx := g.table.find_type_idx(g.table.array_name(typ))
if typ_idx > 0 {
unwrapped_rec_type = ast.Type(typ_idx)
unwrapped_rec_type = ast.idx_to_type(typ_idx)
typ_sym = g.table.sym(unwrapped_rec_type)
}
}
@ -1927,7 +1927,7 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
mut is_interface_call := false
mut is_selector_call := false
if node.left_type != 0 {
mut fn_typ := ast.Type(0)
mut fn_typ := ast.no_type
left_sym := g.table.sym(node.left_type)
if node.is_field {
if field := g.table.find_field_with_embeds(left_sym, node.name) {

View File

@ -717,10 +717,10 @@ fn (mut g Gen) infix_expr_is_op(node ast.InfixExpr) {
g.unwrap_generic(node.right.typ)
}
ast.None {
g.table.type_idxs['None__']
ast.idx_to_type(g.table.type_idxs['None__'])
}
else {
ast.Type(0)
ast.no_type
}
}
sub_sym := g.table.sym(sub_type)

View File

@ -562,7 +562,7 @@ fn (mut g Gen) gen_sumtype_enc_dec(utyp ast.Type, sym ast.TypeSymbol, mut enc st
'cJSON_IsString(root->child)'
} else if var_t.ends_with('bool') {
'cJSON_IsBool(root->child)'
} else if g.table.sym(g.table.value_type(ast.Type(variant_symbols[i].idx))).kind == .struct_ {
} else if g.table.sym(g.table.value_type(ast.idx_to_type(variant_symbols[i].idx))).kind == .struct_ {
'cJSON_IsObject(root->child)'
} else {
'cJSON_IsNumber(root->child)'

View File

@ -90,7 +90,7 @@ fn (mut g JsGen) comptime_if_cond(cond ast.Expr, pkg_exist bool) bool {
.key_is, .not_is {
left := cond.left
mut name := ''
mut exp_type := ast.Type(0)
mut exp_type := ast.no_type
got_type := (cond.right as ast.TypeNode).typ
// Handle `$if x is Interface {`
// mut matches_interface := 'false'

View File

@ -3189,7 +3189,7 @@ fn (mut g JsGen) greater_typ(left ast.Type, right ast.Type) ast.Type {
}
return ast.Type(ast.int_literal_type_idx)
}
return ast.Type(l)
return ast.idx_to_type(l)
}
fn (mut g JsGen) gen_map_init_expr(it ast.MapInit) {

View File

@ -447,7 +447,7 @@ fn handle_vweb(mut table ast.Table, mut all_fn_root_names []string, result_name
result_type_idx := table.find_type_idx(result_name)
if result_type_idx != 0 {
all_fn_root_names << filter_name
typ_vweb_context := ast.Type(table.find_type_idx(context_name)).set_nr_muls(1)
typ_vweb_context := ast.idx_to_type(table.find_type_idx(context_name)).set_nr_muls(1)
all_fn_root_names << '${int(typ_vweb_context)}.html'
for vgt in table.used_vweb_types {
sym_app := table.sym(vgt)

View File

@ -246,7 +246,7 @@ fn (mut p Parser) parse_sql_stmt_line() ast.SqlStmtLine {
}
}
mut inserted_var := ''
mut table_type := ast.Type(0)
mut table_type := ast.no_type
if kind != .delete {
if kind == .update {
table_type = p.parse_type()

View File

@ -335,7 +335,7 @@ fn (mut p Parser) parse_fn_type(name string, generic_types []ast.Type) ast.Type
}
generic_names := p.types_to_names(generic_types, fn_type_pos, 'generic_types') or {
return ast.Type(0)
return ast.no_type
}
func := ast.Fn{
@ -425,7 +425,7 @@ fn (mut p Parser) parse_inline_sum_type() ast.Type {
for variant in variants {
if variant.typ == 0 {
p.error_with_pos('unknown type for variant: ${variant}', variant.pos)
return ast.Type(0)
return ast.no_type
}
variant_names << p.table.sym(variant.typ).name
}
@ -452,7 +452,7 @@ fn (mut p Parser) parse_inline_sum_type() ast.Type {
} else if variants.len == 1 {
return variants[0].typ
}
return ast.Type(0)
return ast.no_type
}
// parse_sum_type_variants parses several types separated with a pipe and returns them as a list with at least one node.
@ -714,7 +714,7 @@ fn (mut p Parser) parse_any_type(language ast.Language, is_ptr bool, check_dot b
if name == 'thread' {
return p.parse_thread_type()
}
mut ret := ast.Type(0)
mut ret := ast.no_type
if name == '' {
// This means the developer is using some wrong syntax like `x: int` instead of `x int`
p.error('expecting type declaration')
@ -806,7 +806,7 @@ fn (mut p Parser) find_type_or_add_placeholder(name string, language ast.Languag
if p.struct_init_generic_types.len > 0 && sym.info.generic_types.len > 0
&& p.struct_init_generic_types != sym.info.generic_types {
generic_names := p.types_to_names(p.struct_init_generic_types, p.tok.pos(),
'struct_init_generic_types') or { return ast.Type(0) }
'struct_init_generic_types') or { return ast.no_type }
// NOTE:
// Used here for the wraparound `< >` characters, is not a reserved character in generic syntax,
// is used as the `generic names` part of the qualified type name,

View File

@ -178,7 +178,7 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
is_on_top := ast_fields.len == 0 && !(is_field_pub || is_field_mut || is_field_global)
has_prev_newline := p.has_prev_newline()
mut field_name := ''
mut typ := ast.Type(0)
mut typ := ast.no_type
mut type_pos := token.Pos{}
mut field_pos := token.Pos{}
mut option_pos := token.Pos{}