mirror of
https://github.com/vlang/v.git
synced 2025-09-13 22:42:26 +03:00
type_resolver: refactor resolve_comptime_type (#23616)
This commit is contained in:
parent
e4d1011bb1
commit
78effd0c09
9 changed files with 43 additions and 29 deletions
|
@ -1453,6 +1453,7 @@ fn (t Tree) selector_expr(node ast.SelectorExpr) &Node {
|
||||||
obj.add_terse('from_embed_types', t.array_node_type(node.from_embed_types))
|
obj.add_terse('from_embed_types', t.array_node_type(node.from_embed_types))
|
||||||
obj.add_terse('has_hidden_receiver', t.bool_node(node.has_hidden_receiver))
|
obj.add_terse('has_hidden_receiver', t.bool_node(node.has_hidden_receiver))
|
||||||
obj.add_terse('next_token', t.token_node(node.next_token))
|
obj.add_terse('next_token', t.token_node(node.next_token))
|
||||||
|
obj.add_terse('is_field_typ', t.bool_node(node.is_field_typ))
|
||||||
obj.add('pos', t.pos(node.pos))
|
obj.add('pos', t.pos(node.pos))
|
||||||
obj.add('scope', t.number_node(int(node.scope)))
|
obj.add('scope', t.number_node(int(node.scope)))
|
||||||
return obj
|
return obj
|
||||||
|
|
|
@ -311,6 +311,7 @@ pub mut:
|
||||||
from_embed_types []Type // holds the type of the embed that the method is called from
|
from_embed_types []Type // holds the type of the embed that the method is called from
|
||||||
generic_from_embed_types [][]Type // holds the types of the embeds for each generic instance when the same generic method is called.
|
generic_from_embed_types [][]Type // holds the types of the embeds for each generic instance when the same generic method is called.
|
||||||
has_hidden_receiver bool
|
has_hidden_receiver bool
|
||||||
|
is_field_typ bool // var.typ for comptime $for var
|
||||||
}
|
}
|
||||||
|
|
||||||
// root_ident returns the origin ident where the selector started.
|
// root_ident returns the origin ident where the selector started.
|
||||||
|
|
|
@ -1645,6 +1645,7 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
|
||||||
return node.expr_type
|
return node.expr_type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
node.is_field_typ = node.is_field_typ || c.comptime.is_comptime_selector_type(node)
|
||||||
old_selector_expr := c.inside_selector_expr
|
old_selector_expr := c.inside_selector_expr
|
||||||
c.inside_selector_expr = true
|
c.inside_selector_expr = true
|
||||||
mut typ := c.expr(mut node.expr)
|
mut typ := c.expr(mut node.expr)
|
||||||
|
|
|
@ -151,12 +151,12 @@ fn (mut g Gen) gen_assert_metainfo(node ast.AssertStmt, kind AssertMetainfoKind)
|
||||||
g.writeln('\t${metaname}.op = ${expr_op_str};')
|
g.writeln('\t${metaname}.op = ${expr_op_str};')
|
||||||
g.writeln('\t${metaname}.llabel = ${expr_left_str};')
|
g.writeln('\t${metaname}.llabel = ${expr_left_str};')
|
||||||
g.writeln('\t${metaname}.rlabel = ${expr_right_str};')
|
g.writeln('\t${metaname}.rlabel = ${expr_right_str};')
|
||||||
left_type := if g.comptime.is_comptime_expr(node.expr.left) {
|
left_type := if node.expr.left_ct_expr {
|
||||||
g.type_resolver.get_type(node.expr.left)
|
g.type_resolver.get_type_or_default(node.expr.left, node.expr.left_type)
|
||||||
} else {
|
} else {
|
||||||
node.expr.left_type
|
node.expr.left_type
|
||||||
}
|
}
|
||||||
right_type := if g.comptime.is_comptime_expr(node.expr.right) {
|
right_type := if node.expr.right_ct_expr {
|
||||||
g.type_resolver.get_type(node.expr.right)
|
g.type_resolver.get_type(node.expr.right)
|
||||||
} else {
|
} else {
|
||||||
node.expr.right_type
|
node.expr.right_type
|
||||||
|
|
|
@ -3584,7 +3584,7 @@ fn (mut g Gen) expr(node_ ast.Expr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast.IsRefType {
|
ast.IsRefType {
|
||||||
typ := g.resolve_comptime_type(node.expr, g.get_type(node.typ))
|
typ := g.type_resolver.typeof_type(node.expr, g.get_type(node.typ))
|
||||||
node_typ := g.unwrap_generic(typ)
|
node_typ := g.unwrap_generic(typ)
|
||||||
sym := g.table.sym(node_typ)
|
sym := g.table.sym(node_typ)
|
||||||
if sym.language == .v && sym.kind in [.placeholder, .any] {
|
if sym.language == .v && sym.kind in [.placeholder, .any] {
|
||||||
|
@ -3669,7 +3669,7 @@ fn (mut g Gen) expr(node_ ast.Expr) {
|
||||||
g.writeln2('\tpanic_option_not_set(_SLIT("none"));', '}')
|
g.writeln2('\tpanic_option_not_set(_SLIT("none"));', '}')
|
||||||
g.write(cur_line)
|
g.write(cur_line)
|
||||||
if is_unwrapped {
|
if is_unwrapped {
|
||||||
typ := g.resolve_comptime_type(node.expr, node.typ)
|
typ := g.type_resolver.typeof_type(node.expr, node.typ)
|
||||||
g.write('*(${g.base_type(typ)}*)&')
|
g.write('*(${g.base_type(typ)}*)&')
|
||||||
g.expr(node.expr)
|
g.expr(node.expr)
|
||||||
g.write('.data')
|
g.write('.data')
|
||||||
|
@ -3844,7 +3844,7 @@ fn (mut g Gen) type_name(raw_type ast.Type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) typeof_expr(node ast.TypeOf) {
|
fn (mut g Gen) typeof_expr(node ast.TypeOf) {
|
||||||
typ := g.resolve_comptime_type(node.expr, g.get_type(node.typ))
|
typ := g.type_resolver.typeof_type(node.expr, g.get_type(node.typ))
|
||||||
sym := g.table.sym(typ)
|
sym := g.table.sym(typ)
|
||||||
if sym.kind == .sum_type {
|
if sym.kind == .sum_type {
|
||||||
// When encountering a .sum_type, typeof() should be done at runtime,
|
// When encountering a .sum_type, typeof() should be done at runtime,
|
||||||
|
@ -3894,14 +3894,14 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
|
||||||
// typeof(expr).name
|
// typeof(expr).name
|
||||||
mut name_type := node.name_type
|
mut name_type := node.name_type
|
||||||
if node.expr is ast.TypeOf {
|
if node.expr is ast.TypeOf {
|
||||||
name_type = g.resolve_comptime_type(node.expr.expr, name_type)
|
name_type = g.type_resolver.typeof_type(node.expr.expr, name_type)
|
||||||
}
|
}
|
||||||
g.type_name(name_type)
|
g.type_name(name_type)
|
||||||
return
|
return
|
||||||
} else if node.field_name == 'idx' {
|
} else if node.field_name == 'idx' {
|
||||||
mut name_type := node.name_type
|
mut name_type := node.name_type
|
||||||
if node.expr is ast.TypeOf {
|
if node.expr is ast.TypeOf {
|
||||||
name_type = g.resolve_comptime_type(node.expr.expr, name_type)
|
name_type = g.type_resolver.typeof_type(node.expr.expr, name_type)
|
||||||
}
|
}
|
||||||
// `typeof(expr).idx`
|
// `typeof(expr).idx`
|
||||||
g.write(int(g.unwrap_generic(name_type)).str())
|
g.write(int(g.unwrap_generic(name_type)).str())
|
||||||
|
@ -3909,7 +3909,7 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
|
||||||
} else if node.field_name == 'unaliased_typ' {
|
} else if node.field_name == 'unaliased_typ' {
|
||||||
mut name_type := node.name_type
|
mut name_type := node.name_type
|
||||||
if node.expr is ast.TypeOf {
|
if node.expr is ast.TypeOf {
|
||||||
name_type = g.resolve_comptime_type(node.expr.expr, name_type)
|
name_type = g.type_resolver.typeof_type(node.expr.expr, name_type)
|
||||||
}
|
}
|
||||||
// `typeof(expr).unaliased_typ`
|
// `typeof(expr).unaliased_typ`
|
||||||
g.write(int(g.table.unaliased_type(g.unwrap_generic(name_type))).str())
|
g.write(int(g.table.unaliased_type(g.unwrap_generic(name_type))).str())
|
||||||
|
@ -3917,7 +3917,7 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
|
||||||
} else if node.field_name == 'indirections' {
|
} else if node.field_name == 'indirections' {
|
||||||
mut name_type := node.name_type
|
mut name_type := node.name_type
|
||||||
if node.expr is ast.TypeOf {
|
if node.expr is ast.TypeOf {
|
||||||
name_type = g.resolve_comptime_type(node.expr.expr, name_type)
|
name_type = g.type_resolver.typeof_type(node.expr.expr, name_type)
|
||||||
}
|
}
|
||||||
// `typeof(expr).indirections`
|
// `typeof(expr).indirections`
|
||||||
g.write(int(g.unwrap_generic(name_type).nr_muls()).str())
|
g.write(int(g.unwrap_generic(name_type).nr_muls()).str())
|
||||||
|
@ -5224,7 +5224,7 @@ fn (mut g Gen) cast_expr(node ast.CastExpr) {
|
||||||
node_typ := g.unwrap_generic(node.typ)
|
node_typ := g.unwrap_generic(node.typ)
|
||||||
mut expr_type := node.expr_type
|
mut expr_type := node.expr_type
|
||||||
sym := g.table.sym(node_typ)
|
sym := g.table.sym(node_typ)
|
||||||
if g.comptime.is_comptime_expr(node.expr) {
|
if g.comptime.is_comptime(node.expr) {
|
||||||
expr_type = g.unwrap_generic(g.type_resolver.get_type(node.expr))
|
expr_type = g.unwrap_generic(g.type_resolver.get_type(node.expr))
|
||||||
}
|
}
|
||||||
node_typ_is_option := node.typ.has_flag(.option)
|
node_typ_is_option := node.typ.has_flag(.option)
|
||||||
|
@ -7231,7 +7231,7 @@ fn (mut g Gen) get_type(typ ast.Type) ast.Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) size_of(node ast.SizeOf) {
|
fn (mut g Gen) size_of(node ast.SizeOf) {
|
||||||
typ := g.resolve_comptime_type(node.expr, g.get_type(node.typ))
|
typ := g.type_resolver.typeof_type(node.expr, g.get_type(node.typ))
|
||||||
node_typ := g.unwrap_generic(typ)
|
node_typ := g.unwrap_generic(typ)
|
||||||
sym := g.table.sym(node_typ)
|
sym := g.table.sym(node_typ)
|
||||||
if sym.language == .v && sym.kind in [.placeholder, .any] {
|
if sym.language == .v && sym.kind in [.placeholder, .any] {
|
||||||
|
|
|
@ -801,21 +801,6 @@ fn (mut g Gen) pop_comptime_info() {
|
||||||
g.comptime.comptime_for_method_ret_type = old.comptime_for_method_ret_type
|
g.comptime.comptime_for_method_ret_type = old.comptime_for_method_ret_type
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) resolve_comptime_type(node ast.Expr, default_type ast.Type) ast.Type {
|
|
||||||
if g.comptime.is_comptime_expr(node) {
|
|
||||||
return g.type_resolver.get_type(node)
|
|
||||||
} else if node is ast.SelectorExpr && node.expr_type != 0 {
|
|
||||||
if node.expr is ast.Ident && g.comptime.is_comptime_selector_type(node) {
|
|
||||||
return g.type_resolver.get_type_from_comptime_var(node.expr)
|
|
||||||
}
|
|
||||||
sym := g.table.sym(g.unwrap_generic(node.expr_type))
|
|
||||||
if f := g.table.find_field_with_embeds(sym, node.field_name) {
|
|
||||||
return f.typ
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return default_type
|
|
||||||
}
|
|
||||||
|
|
||||||
fn (mut g Gen) comptime_for(node ast.ComptimeFor) {
|
fn (mut g Gen) comptime_for(node ast.ComptimeFor) {
|
||||||
sym := if node.typ != g.field_data_type {
|
sym := if node.typ != g.field_data_type {
|
||||||
g.table.final_sym(g.unwrap_generic(node.typ))
|
g.table.final_sym(g.unwrap_generic(node.typ))
|
||||||
|
|
|
@ -1324,7 +1324,7 @@ fn (mut g Gen) gen_to_str_method_call(node ast.CallExpr) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
} else if left_node is ast.PostfixExpr {
|
} else if left_node is ast.PostfixExpr {
|
||||||
rec_type = g.resolve_comptime_type(left_node.expr, rec_type)
|
rec_type = g.type_resolver.get_type_or_default(left_node.expr, rec_type)
|
||||||
if left_node.op == .question {
|
if left_node.op == .question {
|
||||||
rec_type = rec_type.clear_flag(.option)
|
rec_type = rec_type.clear_flag(.option)
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,22 @@ pub fn (t &ResolverInfo) is_comptime_variant_var(node ast.Ident) bool {
|
||||||
return node.name == t.comptime_for_variant_var
|
return node.name == t.comptime_for_variant_var
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// typeof_type resolves type for typeof() expr where field.typ is resolved to real type instead of int type to make type(field.typ).name working
|
||||||
|
pub fn (mut t TypeResolver) typeof_type(node ast.Expr, default_type ast.Type) ast.Type {
|
||||||
|
if t.info.is_comptime(node) {
|
||||||
|
return t.get_type(node)
|
||||||
|
} else if node is ast.SelectorExpr && node.expr_type != 0 {
|
||||||
|
if node.expr is ast.Ident && node.is_field_typ {
|
||||||
|
return t.get_type_from_comptime_var(node.expr)
|
||||||
|
}
|
||||||
|
sym := t.table.sym(t.resolver.unwrap_generic(node.expr_type))
|
||||||
|
if f := t.table.find_field_with_embeds(sym, node.field_name) {
|
||||||
|
return f.typ
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return default_type
|
||||||
|
}
|
||||||
|
|
||||||
// get_ct_type_var gets the comptime type of the variable (.generic_param, .key_var, etc)
|
// get_ct_type_var gets the comptime type of the variable (.generic_param, .key_var, etc)
|
||||||
@[inline]
|
@[inline]
|
||||||
pub fn (t &ResolverInfo) get_ct_type_var(node ast.Expr) ast.ComptimeVarKind {
|
pub fn (t &ResolverInfo) get_ct_type_var(node ast.Expr) ast.ComptimeVarKind {
|
||||||
|
|
|
@ -207,7 +207,7 @@ pub fn (mut t TypeResolver) get_type(node ast.Expr) ast.Type {
|
||||||
}
|
}
|
||||||
return ctyp
|
return ctyp
|
||||||
} else if node is ast.SelectorExpr {
|
} else if node is ast.SelectorExpr {
|
||||||
if t.info.is_comptime_selector_type(node) {
|
if node.is_field_typ {
|
||||||
return t.get_type_from_comptime_var(node.expr as ast.Ident)
|
return t.get_type_from_comptime_var(node.expr as ast.Ident)
|
||||||
}
|
}
|
||||||
if node.expr is ast.Ident && node.expr.ct_expr {
|
if node.expr is ast.Ident && node.expr.ct_expr {
|
||||||
|
@ -216,8 +216,18 @@ pub fn (mut t TypeResolver) get_type(node ast.Expr) ast.Type {
|
||||||
// Struct[T] can have field with generic type
|
// Struct[T] can have field with generic type
|
||||||
if struct_sym.info is ast.Struct && struct_sym.info.generic_types.len > 0 {
|
if struct_sym.info is ast.Struct && struct_sym.info.generic_types.len > 0 {
|
||||||
if field := t.table.find_field(struct_sym, node.field_name) {
|
if field := t.table.find_field(struct_sym, node.field_name) {
|
||||||
|
if f_unwrap := node.scope.find_struct_field(ast.Expr(node.expr).str(),
|
||||||
|
t.get_type_or_default(node.expr, node.expr_type), node.field_name)
|
||||||
|
{
|
||||||
|
return f_unwrap.smartcasts.last()
|
||||||
|
}
|
||||||
return field.typ
|
return field.typ
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
sym := t.table.sym(t.resolver.unwrap_generic(node.expr_type))
|
||||||
|
if f := t.table.find_field_with_embeds(sym, node.field_name) {
|
||||||
|
return f.typ
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return node.typ
|
return node.typ
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue