mirror of
https://github.com/vlang/v.git
synced 2025-09-11 16:36:20 -04:00
v: optimize the compiler performance (#22709)
This commit is contained in:
parent
2ad5d0cd15
commit
ee4f29fd87
@ -746,12 +746,6 @@ fn (s string) == (a string) bool {
|
||||
if s.len != a.len {
|
||||
return false
|
||||
}
|
||||
if s.len > 0 {
|
||||
last_idx := s.len - 1
|
||||
if s[last_idx] != a[last_idx] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
return vmemcmp(s.str, a.str, a.len) == 0
|
||||
}
|
||||
|
@ -360,6 +360,7 @@ pub:
|
||||
is_global bool
|
||||
is_volatile bool
|
||||
is_deprecated bool
|
||||
is_embed bool
|
||||
pub mut:
|
||||
is_recursive bool
|
||||
is_part_of_union bool
|
||||
@ -485,6 +486,7 @@ pub:
|
||||
next_comments []Comment
|
||||
has_prev_newline bool
|
||||
has_break_line bool
|
||||
is_embed bool
|
||||
pub mut:
|
||||
expr Expr // `val1`
|
||||
name string // 'field1'
|
||||
|
@ -40,6 +40,7 @@ pub fn new_scope(parent &Scope, start_pos int) &Scope {
|
||||
}
|
||||
*/
|
||||
|
||||
@[inline]
|
||||
fn (s &Scope) dont_lookup_parent() bool {
|
||||
return s.parent == unsafe { nil } || s.detached_from_parent
|
||||
}
|
||||
|
@ -2000,7 +2000,7 @@ pub fn (mut t Table) unwrap_generic_type_ex(typ Type, generic_names []string, co
|
||||
}
|
||||
}
|
||||
// Update type in `info.embeds`, if it's embed
|
||||
if fields[i].name.len > 1 && fields[i].name[0].is_capital() {
|
||||
if fields[i].is_embed {
|
||||
mut parent_sym := t.sym(typ)
|
||||
mut parent_info := parent_sym.info
|
||||
if mut parent_info is Struct {
|
||||
@ -2186,7 +2186,7 @@ pub fn (mut t Table) generic_insts_to_concrete() {
|
||||
fields[i].typ = t_typ
|
||||
}
|
||||
// Update type in `info.embeds`, if it's embed
|
||||
if fields[i].name.len > 1 && fields[i].name[0].is_capital() {
|
||||
if fields[i].is_embed {
|
||||
for mut embed in parent_info.embeds {
|
||||
if embed == orig_type {
|
||||
embed = fields[i].typ
|
||||
|
@ -1701,7 +1701,7 @@ pub fn (t &TypeSymbol) embed_name() string {
|
||||
|
||||
pub fn (t &TypeSymbol) has_method(name string) bool {
|
||||
for mut method in unsafe { t.methods } {
|
||||
if method.name == name {
|
||||
if method.name.len == name.len && method.name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -1715,7 +1715,7 @@ pub fn (t &TypeSymbol) has_method_with_generic_parent(name string) bool {
|
||||
|
||||
pub fn (t &TypeSymbol) find_method(name string) ?Fn {
|
||||
for mut method in unsafe { t.methods } {
|
||||
if method.name == name {
|
||||
if method.name.len == name.len && method.name == name {
|
||||
return method
|
||||
}
|
||||
}
|
||||
@ -1830,7 +1830,7 @@ pub fn (t &TypeSymbol) has_field(name string) bool {
|
||||
|
||||
fn (a &Aggregate) find_field(name string) ?StructField {
|
||||
for mut field in unsafe { a.fields } {
|
||||
if field.name == name {
|
||||
if field.name.len == name.len && field.name == name {
|
||||
return field
|
||||
}
|
||||
}
|
||||
@ -1839,7 +1839,7 @@ fn (a &Aggregate) find_field(name string) ?StructField {
|
||||
|
||||
pub fn (i &Interface) find_field(name string) ?StructField {
|
||||
for mut field in unsafe { i.fields } {
|
||||
if field.name == name {
|
||||
if field.name.len == name.len && field.name == name {
|
||||
return field
|
||||
}
|
||||
}
|
||||
@ -1848,7 +1848,7 @@ pub fn (i &Interface) find_field(name string) ?StructField {
|
||||
|
||||
pub fn (i &Interface) find_method(name string) ?Fn {
|
||||
for mut method in unsafe { i.methods } {
|
||||
if method.name == name {
|
||||
if method.name.len == name.len && method.name == name {
|
||||
return method
|
||||
}
|
||||
}
|
||||
@ -1857,7 +1857,7 @@ pub fn (i &Interface) find_method(name string) ?Fn {
|
||||
|
||||
pub fn (i &Interface) has_method(name string) bool {
|
||||
for mut method in unsafe { i.methods } {
|
||||
if method.name == name {
|
||||
if method.name.len == name.len && method.name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@ -1866,7 +1866,7 @@ pub fn (i &Interface) has_method(name string) bool {
|
||||
|
||||
pub fn (s Struct) find_field(name string) ?StructField {
|
||||
for mut field in unsafe { s.fields } {
|
||||
if field.name == name {
|
||||
if name.len == field.name.len && field.name == name {
|
||||
return field
|
||||
}
|
||||
}
|
||||
|
@ -5360,10 +5360,10 @@ fn (c &Checker) check_import_sym_conflict(ident string) bool {
|
||||
for import_sym in c.file.imports {
|
||||
// Check if alias exists or not
|
||||
if !import_sym.alias.is_blank() {
|
||||
if import_sym.alias == ident {
|
||||
if import_sym.alias.len == ident.len && import_sym.alias == ident {
|
||||
return true
|
||||
}
|
||||
} else if import_sym.mod == ident {
|
||||
} else if import_sym.mod.len == ident.len && import_sym.mod == ident {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -806,8 +806,7 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.',
|
||||
|
||||
// all the fields of initialized embedded struct are ignored, they are considered initialized
|
||||
sym := c.table.sym(init_field.typ)
|
||||
if init_field.name != '' && init_field.name[0].is_capital() && sym.kind == .struct
|
||||
&& sym.language == .v {
|
||||
if init_field.is_embed && sym.kind == .struct && sym.language == .v {
|
||||
struct_fields := c.table.struct_fields(sym)
|
||||
for struct_field in struct_fields {
|
||||
inited_fields << struct_field.name
|
||||
@ -928,7 +927,7 @@ fn (mut c Checker) check_uninitialized_struct_fields_and_embeds(node ast.StructI
|
||||
continue
|
||||
}
|
||||
sym := c.table.sym(field.typ)
|
||||
if field.name != '' && field.name[0].is_capital() && sym.info is ast.Struct {
|
||||
if field.is_embed && sym.info is ast.Struct {
|
||||
// struct embeds
|
||||
continue
|
||||
}
|
||||
@ -957,13 +956,14 @@ fn (mut c Checker) check_uninitialized_struct_fields_and_embeds(node ast.StructI
|
||||
}
|
||||
continue
|
||||
}
|
||||
if field.typ.is_ptr() && !field.typ.has_flag(.shared_f) && !field.typ.has_flag(.option)
|
||||
field_is_option := field.typ.has_flag(.option)
|
||||
if field.typ.is_ptr() && !field.typ.has_flag(.shared_f) && !field_is_option
|
||||
&& !node.has_update_expr && !c.pref.translated && !c.file.is_translated {
|
||||
c.error('reference field `${type_sym.name}.${field.name}` must be initialized',
|
||||
node.pos)
|
||||
continue
|
||||
}
|
||||
if !field.typ.has_flag(.option) {
|
||||
if !field_is_option {
|
||||
if sym.kind == .struct {
|
||||
c.check_ref_fields_initialized(sym, mut checked_types, '${type_sym.name}.${field.name}',
|
||||
node.pos)
|
||||
@ -976,7 +976,7 @@ fn (mut c Checker) check_uninitialized_struct_fields_and_embeds(node ast.StructI
|
||||
}
|
||||
}
|
||||
// Do not allow empty uninitialized interfaces
|
||||
if sym.kind == .interface && !node.has_update_expr && !field.typ.has_flag(.option)
|
||||
if sym.kind == .interface && !node.has_update_expr && !field_is_option
|
||||
&& sym.language != .js && !field.attrs.contains('noinit') {
|
||||
// TODO: should be an error instead, but first `ui` needs updating.
|
||||
c.note('interface field `${type_sym.name}.${field.name}` must be initialized',
|
||||
@ -996,7 +996,7 @@ fn (mut c Checker) check_uninitialized_struct_fields_and_embeds(node ast.StructI
|
||||
c.error('field `${type_sym.name}.${field.name}` must be initialized', node.pos)
|
||||
}
|
||||
if !node.has_update_expr && !field.has_default_expr && !field.typ.is_ptr()
|
||||
&& !field.typ.has_flag(.option) {
|
||||
&& !field_is_option {
|
||||
field_final_sym := c.table.final_sym(field.typ)
|
||||
if field_final_sym.kind == .struct {
|
||||
mut zero_struct_init := ast.StructInit{
|
||||
@ -1063,7 +1063,7 @@ fn (mut c Checker) check_ref_fields_initialized(struct_sym &ast.TypeSymbol, mut
|
||||
if sym.language == .c {
|
||||
continue
|
||||
}
|
||||
if field.name != '' && field.name[0].is_capital() && sym.language == .v {
|
||||
if field.is_embed && sym.language == .v {
|
||||
// an embedded struct field
|
||||
continue
|
||||
}
|
||||
@ -1106,7 +1106,7 @@ fn (mut c Checker) check_ref_fields_initialized_note(struct_sym &ast.TypeSymbol,
|
||||
if sym.language == .c {
|
||||
continue
|
||||
}
|
||||
if field.name != '' && field.name[0].is_capital() && sym.language == .v {
|
||||
if field.is_embed && sym.language == .v {
|
||||
// an embedded struct field
|
||||
continue
|
||||
}
|
||||
|
@ -55,12 +55,14 @@ pub fn (o &OrderedDepMap) get(name string) []string {
|
||||
return res
|
||||
}
|
||||
|
||||
@[direct_array_access]
|
||||
pub fn (mut o OrderedDepMap) delete(name string) {
|
||||
if name !in o.data {
|
||||
panic('delete: no such key: ${name}')
|
||||
}
|
||||
for i, _ in o.keys {
|
||||
if o.keys[i] == name {
|
||||
item := o.keys[i]
|
||||
if item.len == name.len && item == name {
|
||||
o.keys.delete(i)
|
||||
break
|
||||
}
|
||||
|
@ -1086,8 +1086,12 @@ fn (mut g Gen) gen_array_contains_methods() {
|
||||
ptr_typ := g.equality_fn(elem_type)
|
||||
fn_builder.writeln('\t\tif (${ptr_typ}_sumtype_eq(((${elem_type_str}*)a.data)[i], v)) {')
|
||||
} else if elem_kind == .alias && elem_is_not_ptr {
|
||||
ptr_typ := g.equality_fn(elem_type)
|
||||
fn_builder.writeln('\t\tif (${ptr_typ}_alias_eq(((${elem_type_str}*)a.data)[i], v)) {')
|
||||
if g.no_eq_method_types[elem_type] {
|
||||
fn_builder.writeln('\t\tif (((${elem_type_str}*)a.data)[i] == v) {')
|
||||
} else {
|
||||
ptr_typ := g.equality_fn(elem_type)
|
||||
fn_builder.writeln('\t\tif (${ptr_typ}_alias_eq(((${elem_type_str}*)a.data)[i], v)) {')
|
||||
}
|
||||
} else {
|
||||
fn_builder.writeln('\t\tif (((${elem_type_str}*)a.data)[i] == v) {')
|
||||
}
|
||||
@ -1124,8 +1128,12 @@ fn (mut g Gen) gen_array_contains_methods() {
|
||||
ptr_typ := g.equality_fn(elem_type)
|
||||
fn_builder.writeln('\t\tif (${ptr_typ}_sumtype_eq(a[i], v)) {')
|
||||
} else if elem_kind == .alias && elem_is_not_ptr {
|
||||
ptr_typ := g.equality_fn(elem_type)
|
||||
fn_builder.writeln('\t\tif (${ptr_typ}_alias_eq(a[i], v)) {')
|
||||
if g.no_eq_method_types[elem_type] {
|
||||
fn_builder.writeln('\t\tif (a[i] == v) {')
|
||||
} else {
|
||||
ptr_typ := g.equality_fn(elem_type)
|
||||
fn_builder.writeln('\t\tif (${ptr_typ}_alias_eq(a[i], v)) {')
|
||||
}
|
||||
} else {
|
||||
fn_builder.writeln('\t\tif (a[i] == v) {')
|
||||
}
|
||||
|
@ -97,8 +97,12 @@ fn (mut g Gen) gen_sumtype_equality_fn(left_type ast.Type) string {
|
||||
eq_fn := g.gen_map_equality_fn(typ)
|
||||
fn_builder.writeln('\t\treturn ${eq_fn}_map_eq(*${left_arg}, *${right_arg});')
|
||||
} else if variant.sym.kind == .alias && !typ.is_ptr() {
|
||||
eq_fn := g.gen_alias_equality_fn(typ)
|
||||
fn_builder.writeln('\t\treturn ${eq_fn}_alias_eq(*${left_arg}, *${right_arg});')
|
||||
if g.no_eq_method_types[typ] {
|
||||
fn_builder.writeln('\t\treturn *${left_arg} == *${right_arg};')
|
||||
} else {
|
||||
eq_fn := g.gen_alias_equality_fn(typ)
|
||||
fn_builder.writeln('\t\treturn ${eq_fn}_alias_eq(*${left_arg}, *${right_arg});')
|
||||
}
|
||||
} else if variant.sym.kind == .function {
|
||||
fn_builder.writeln('\t\treturn *((voidptr*)(*${left_arg})) == *((voidptr*)(*${right_arg}));')
|
||||
} else {
|
||||
@ -242,8 +246,12 @@ fn (mut g Gen) gen_struct_equality_fn(left_type ast.Type) string {
|
||||
eq_fn := g.gen_map_equality_fn(field.typ)
|
||||
fn_builder.write_string('${eq_fn}_map_eq(${left_arg}, ${right_arg})')
|
||||
} else if field_type.sym.kind == .alias && !field.typ.is_ptr() {
|
||||
eq_fn := g.gen_alias_equality_fn(field.typ)
|
||||
fn_builder.write_string('${eq_fn}_alias_eq(${left_arg}, ${right_arg})')
|
||||
if g.no_eq_method_types[field.typ] {
|
||||
fn_builder.write_string('${left_arg} == ${right_arg}')
|
||||
} else {
|
||||
eq_fn := g.gen_alias_equality_fn(field.typ)
|
||||
fn_builder.write_string('${eq_fn}_alias_eq(${left_arg}, ${right_arg})')
|
||||
}
|
||||
} else if field_type.sym.kind == .function && !field.typ.has_flag(.option) {
|
||||
fn_builder.write_string('*((voidptr*)(${left_arg})) == *((voidptr*)(${right_arg}))')
|
||||
} else if field_type.sym.kind == .interface
|
||||
@ -385,8 +393,12 @@ fn (mut g Gen) gen_array_equality_fn(left_type ast.Type) string {
|
||||
eq_fn := g.gen_map_equality_fn(elem.typ)
|
||||
fn_builder.writeln('\t\tif (!${eq_fn}_map_eq(((${ptr_elem_styp}*)${left_data})[i], ((${ptr_elem_styp}*)${right_data})[i])) {')
|
||||
} else if elem.sym.kind == .alias && !elem.typ.is_ptr() {
|
||||
eq_fn := g.gen_alias_equality_fn(elem.typ)
|
||||
fn_builder.writeln('\t\tif (!${eq_fn}_alias_eq(((${ptr_elem_styp}*)${left_data})[i], ((${ptr_elem_styp}*)${right_data})[i])) {')
|
||||
if g.no_eq_method_types[elem.typ] {
|
||||
fn_builder.writeln('\t\tif (((${ptr_elem_styp}*)${left_data})[i] != ((${ptr_elem_styp}*)${right_data})[i]) {')
|
||||
} else {
|
||||
eq_fn := g.gen_alias_equality_fn(elem.typ)
|
||||
fn_builder.writeln('\t\tif (!${eq_fn}_alias_eq(((${ptr_elem_styp}*)${left_data})[i], ((${ptr_elem_styp}*)${right_data})[i])) {')
|
||||
}
|
||||
} else if elem.sym.kind == .function {
|
||||
fn_builder.writeln('\t\tif (*((voidptr*)((byte*)${left_data}+(i*${left_elem}))) != *((voidptr*)((byte*)${right_data}+(i*${right_elem})))) {')
|
||||
} else {
|
||||
|
@ -87,7 +87,8 @@ mut:
|
||||
file &ast.File = unsafe { nil }
|
||||
table &ast.Table = unsafe { nil }
|
||||
styp_cache map[ast.Type]string
|
||||
unique_file_path_hash u64 // a hash of file.path, used for making auxiliary fn generation unique (like `compare_xyz`)
|
||||
no_eq_method_types map[ast.Type]bool // types that does not need to call its auto eq methods for optimization
|
||||
unique_file_path_hash u64 // a hash of file.path, used for making auxiliary fn generation unique (like `compare_xyz`)
|
||||
fn_decl &ast.FnDecl = unsafe { nil } // pointer to the FnDecl we are currently inside otherwise 0
|
||||
last_fn_c_name string
|
||||
tmp_count int // counter for unique tmp vars (_tmp1, _tmp2 etc); resets at the start of each fn.
|
||||
@ -466,6 +467,9 @@ pub fn gen(files []&ast.File, mut table ast.Table, pref_ &pref.Preferences) (str
|
||||
for k, v in g.autofree_methods {
|
||||
global_g.autofree_methods[k] = v
|
||||
}
|
||||
for k, v in g.no_eq_method_types {
|
||||
global_g.no_eq_method_types[k] = v
|
||||
}
|
||||
}
|
||||
} else {
|
||||
util.timing_start('cgen serial processing')
|
||||
@ -1062,13 +1066,13 @@ pub fn (mut g Gen) write_typeof_functions() {
|
||||
// V type to C typecc
|
||||
@[inline]
|
||||
fn (mut g Gen) styp(t ast.Type) string {
|
||||
if t.has_flag(.option) {
|
||||
if !t.has_option_or_result() {
|
||||
return g.base_type(t)
|
||||
} else if t.has_flag(.option) {
|
||||
// Register an optional if it's not registered yet
|
||||
return g.register_option(t)
|
||||
} else if t.has_flag(.result) {
|
||||
return g.register_result(t)
|
||||
} else {
|
||||
return g.base_type(t)
|
||||
return g.register_result(t)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1098,7 +1102,7 @@ fn (mut g Gen) base_type(_t ast.Type) string {
|
||||
if t.has_flag(.shared_f) {
|
||||
styp = g.find_or_register_shared(t, styp)
|
||||
}
|
||||
nr_muls := g.unwrap_generic(t).nr_muls()
|
||||
nr_muls := t.nr_muls()
|
||||
if nr_muls > 0 {
|
||||
styp += strings.repeat(`*`, nr_muls)
|
||||
}
|
||||
|
@ -193,21 +193,35 @@ fn (mut g Gen) infix_expr_eq_op(node ast.InfixExpr) {
|
||||
}
|
||||
match kind {
|
||||
.alias {
|
||||
ptr_typ := g.equality_fn(left.typ)
|
||||
if node.op == .ne {
|
||||
g.write('!')
|
||||
// optimize simple eq/ne operation on numbers
|
||||
if left.unaliased_sym.is_int() {
|
||||
if left.typ.is_ptr() {
|
||||
g.write('*'.repeat(left.typ.nr_muls()))
|
||||
}
|
||||
g.expr(node.left)
|
||||
g.write(' ${node.op} ')
|
||||
if right.typ.is_ptr() {
|
||||
g.write('*'.repeat(right.typ.nr_muls()))
|
||||
}
|
||||
g.expr(node.right)
|
||||
g.no_eq_method_types[left.typ] = true
|
||||
} else {
|
||||
ptr_typ := g.equality_fn(left.typ)
|
||||
if node.op == .ne {
|
||||
g.write('!')
|
||||
}
|
||||
g.write('${ptr_typ}_alias_eq(')
|
||||
if left.typ.is_ptr() {
|
||||
g.write('*'.repeat(left.typ.nr_muls()))
|
||||
}
|
||||
g.expr(node.left)
|
||||
g.write(', ')
|
||||
if right.typ.is_ptr() {
|
||||
g.write('*'.repeat(right.typ.nr_muls()))
|
||||
}
|
||||
g.expr(node.right)
|
||||
g.write(')')
|
||||
}
|
||||
g.write('${ptr_typ}_alias_eq(')
|
||||
if left.typ.is_ptr() {
|
||||
g.write('*'.repeat(left.typ.nr_muls()))
|
||||
}
|
||||
g.expr(node.left)
|
||||
g.write(', ')
|
||||
if right.typ.is_ptr() {
|
||||
g.write('*'.repeat(right.typ.nr_muls()))
|
||||
}
|
||||
g.expr(node.right)
|
||||
g.write(')')
|
||||
}
|
||||
.array {
|
||||
ptr_typ := g.equality_fn(left.unaliased.clear_flag(.shared_f))
|
||||
@ -515,10 +529,10 @@ fn (mut g Gen) infix_expr_in_op(node ast.InfixExpr) {
|
||||
expr: node.left
|
||||
expr_type: node.left_type
|
||||
}
|
||||
g.infix_expr_in_optimization(new_node_left, node.right)
|
||||
g.infix_expr_in_optimization(new_node_left, node.left_type, node.right)
|
||||
}
|
||||
} else {
|
||||
g.infix_expr_in_optimization(node.left, node.right)
|
||||
g.infix_expr_in_optimization(node.left, node.left_type, node.right)
|
||||
}
|
||||
g.write(')')
|
||||
return
|
||||
@ -604,7 +618,7 @@ fn (mut g Gen) infix_expr_in_op(node ast.InfixExpr) {
|
||||
// `a in [1,2,3]!` optimization => `a == 1 || a == 2 || a == 3`
|
||||
// avoids an allocation
|
||||
g.write('(')
|
||||
g.infix_expr_in_optimization(node.left, node.right)
|
||||
g.infix_expr_in_optimization(node.left, node.left_type, node.right)
|
||||
g.write(')')
|
||||
return
|
||||
}
|
||||
@ -642,8 +656,9 @@ fn (mut g Gen) infix_expr_in_op(node ast.InfixExpr) {
|
||||
// infix_expr_in_optimization optimizes `<var> in <array>` expressions,
|
||||
// and transform them in a series of equality comparison
|
||||
// i.e. `a in [1,2,3]` => `a == 1 || a == 2 || a == 3`
|
||||
fn (mut g Gen) infix_expr_in_optimization(left ast.Expr, right ast.ArrayInit) {
|
||||
fn (mut g Gen) infix_expr_in_optimization(left ast.Expr, left_type ast.Type, right ast.ArrayInit) {
|
||||
mut elem_sym := g.table.sym(right.elem_type)
|
||||
left_parent_idx := g.table.sym(left_type).parent_idx
|
||||
for i, array_expr in right.exprs {
|
||||
match elem_sym.kind {
|
||||
.string, .alias, .sum_type, .map, .interface, .array, .struct {
|
||||
@ -659,9 +674,10 @@ fn (mut g Gen) infix_expr_in_optimization(left ast.Expr, right ast.ArrayInit) {
|
||||
} else {
|
||||
g.write('_SLIT_EQ(${var}.str, ${var}.len, "${slit}")')
|
||||
}
|
||||
unsafe {
|
||||
goto end
|
||||
if i < right.exprs.len - 1 {
|
||||
g.write(' || ')
|
||||
}
|
||||
continue
|
||||
} else if array_expr is ast.StringLiteral {
|
||||
g.write('fast_string_eq(')
|
||||
} else {
|
||||
@ -674,7 +690,23 @@ fn (mut g Gen) infix_expr_in_optimization(left ast.Expr, right ast.ArrayInit) {
|
||||
} else {
|
||||
ptr_typ := g.equality_fn(right.elem_type)
|
||||
if elem_sym.kind == .alias {
|
||||
g.write('${ptr_typ}_alias_eq(')
|
||||
// optimization for alias to number
|
||||
if elem_sym.is_int() {
|
||||
g.expr(left)
|
||||
g.write(' == ')
|
||||
if left_parent_idx != 0 && !((array_expr is ast.SelectorExpr
|
||||
&& array_expr.typ == left_type)
|
||||
|| (array_expr is ast.Ident && array_expr.obj.typ == left_type)) {
|
||||
g.write('(${g.styp(left_parent_idx)})')
|
||||
}
|
||||
g.expr(array_expr)
|
||||
if i < right.exprs.len - 1 {
|
||||
g.write(' || ')
|
||||
}
|
||||
continue
|
||||
} else {
|
||||
g.write('${ptr_typ}_alias_eq(')
|
||||
}
|
||||
} else if elem_sym.kind == .sum_type {
|
||||
g.write('${ptr_typ}_sumtype_eq(')
|
||||
} else if elem_sym.kind == .map {
|
||||
@ -698,7 +730,6 @@ fn (mut g Gen) infix_expr_in_optimization(left ast.Expr, right ast.ArrayInit) {
|
||||
g.expr(array_expr)
|
||||
}
|
||||
}
|
||||
end:
|
||||
if i < right.exprs.len - 1 {
|
||||
g.write(' || ')
|
||||
}
|
||||
|
@ -782,7 +782,7 @@ fn (mut g Gen) gen_struct_enc_dec(utyp ast.Type, type_info ast.TypeInfo, styp st
|
||||
}
|
||||
} else {
|
||||
// embeded
|
||||
if name.len > 0 && name[0].is_capital() && field_sym.info is ast.Struct {
|
||||
if field.is_embed && field_sym.info is ast.Struct {
|
||||
for embed in info.embeds {
|
||||
if embed == int(field.typ) {
|
||||
prefix_embed := if embed_prefix != '' {
|
||||
|
@ -31,7 +31,7 @@ fn (mut g Gen) unwrap_generic(typ ast.Type) ast.Type {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if typ.has_flag(.generic) && g.table.sym(typ).kind == .struct {
|
||||
} else if g.table.sym(typ).kind == .struct {
|
||||
// resolve selector `a.foo` where `a` is struct[T] on non generic function
|
||||
sym := g.table.sym(typ)
|
||||
if sym.info is ast.Struct {
|
||||
|
@ -2214,6 +2214,7 @@ fn (mut p Parser) note_with_pos(s string, pos token.Pos) {
|
||||
}
|
||||
}
|
||||
|
||||
@[direct_array_access]
|
||||
fn (mut p Parser) parse_multi_expr(is_top_level bool) ast.Stmt {
|
||||
// in here might be 1) multi-expr 2) multi-assign
|
||||
// 1, a, c ... } // multi-expression
|
||||
|
@ -340,6 +340,7 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
|
||||
attrs: p.attrs
|
||||
is_pub: is_embed || is_field_pub
|
||||
is_mut: is_embed || is_field_mut
|
||||
is_embed: is_embed
|
||||
is_global: is_field_global
|
||||
is_volatile: is_field_volatile
|
||||
is_deprecated: is_field_deprecated
|
||||
@ -503,6 +504,7 @@ fn (mut p Parser) struct_init(typ_str string, kind ast.StructInitKind, is_option
|
||||
parent_type: typ
|
||||
has_prev_newline: has_prev_newline
|
||||
has_break_line: has_break_line
|
||||
is_embed: field_name.len > 0 && field_name[0].is_capital()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user