mirror of
https://github.com/vlang/v.git
synced 2025-09-13 22:42:26 +03:00
This commit is contained in:
parent
5376a55cef
commit
89d1aac5bd
9 changed files with 44 additions and 10 deletions
|
@ -884,6 +884,7 @@ pub enum ComptimeVarKind {
|
||||||
generic_param // generic fn parameter
|
generic_param // generic fn parameter
|
||||||
generic_var // generic var
|
generic_var // generic var
|
||||||
smartcast // smart cast when used in `is v` (when `v` is from $for .variants)
|
smartcast // smart cast when used in `is v` (when `v` is from $for .variants)
|
||||||
|
aggregate // aggregate var
|
||||||
}
|
}
|
||||||
|
|
||||||
@[minify]
|
@[minify]
|
||||||
|
|
|
@ -4331,6 +4331,8 @@ fn (mut c Checker) smartcast(mut expr ast.Expr, cur_type ast.Type, to_type_ ast.
|
||||||
is_inherited = expr.obj.is_inherited
|
is_inherited = expr.obj.is_inherited
|
||||||
ct_type_var = if is_comptime {
|
ct_type_var = if is_comptime {
|
||||||
.smartcast
|
.smartcast
|
||||||
|
} else if c.table.type_kind(to_type_) == .aggregate {
|
||||||
|
.aggregate
|
||||||
} else {
|
} else {
|
||||||
.no_comptime
|
.no_comptime
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ fn (mut c Checker) get_default_fmt(ftyp ast.Type, typ ast.Type) u8 {
|
||||||
return `s`
|
return `s`
|
||||||
}
|
}
|
||||||
if ftyp in [ast.string_type, ast.bool_type]
|
if ftyp in [ast.string_type, ast.bool_type]
|
||||||
|| sym.kind in [.enum, .array, .array_fixed, .struct, .map, .multi_return, .sum_type, .interface, .none]
|
|| sym.kind in [.enum, .array, .array_fixed, .struct, .map, .multi_return, .sum_type, .interface, .aggregate, .none]
|
||||||
|| ftyp.has_option_or_result() || sym.has_method('str') {
|
|| ftyp.has_option_or_result() || sym.has_method('str') {
|
||||||
return `s`
|
return `s`
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -5022,7 +5022,7 @@ fn (mut g Gen) ident(node ast.Ident) {
|
||||||
if node.info is ast.IdentVar {
|
if node.info is ast.IdentVar {
|
||||||
if node.obj is ast.Var {
|
if node.obj is ast.Var {
|
||||||
if !g.is_assign_lhs
|
if !g.is_assign_lhs
|
||||||
&& node.obj.ct_type_var !in [.smartcast, .generic_param, .no_comptime] {
|
&& node.obj.ct_type_var !in [.smartcast, .generic_param, .no_comptime, .aggregate] {
|
||||||
comptime_type := g.type_resolver.get_type(node)
|
comptime_type := g.type_resolver.get_type(node)
|
||||||
if comptime_type.has_flag(.option) {
|
if comptime_type.has_flag(.option) {
|
||||||
if (g.inside_opt_or_res || g.left_is_opt) && node.or_expr.kind == .absent {
|
if (g.inside_opt_or_res || g.left_is_opt) && node.or_expr.kind == .absent {
|
||||||
|
|
|
@ -836,11 +836,7 @@ fn (mut g Gen) infix_expr_in_optimization(left ast.Expr, left_type ast.Type, rig
|
||||||
fn (mut g Gen) infix_expr_is_op(node ast.InfixExpr) {
|
fn (mut g Gen) infix_expr_is_op(node ast.InfixExpr) {
|
||||||
mut left_sym := g.table.sym(g.unwrap_generic(g.type_resolver.get_type_or_default(node.left,
|
mut left_sym := g.table.sym(g.unwrap_generic(g.type_resolver.get_type_or_default(node.left,
|
||||||
node.left_type)))
|
node.left_type)))
|
||||||
is_aggregate := left_sym.kind == .aggregate
|
is_aggregate := node.left is ast.Ident && g.comptime.get_ct_type_var(node.left) == .aggregate
|
||||||
if is_aggregate {
|
|
||||||
parent_left_type := (left_sym.info as ast.Aggregate).sum_type
|
|
||||||
left_sym = g.table.sym(parent_left_type)
|
|
||||||
}
|
|
||||||
right_sym := g.table.sym(node.right_type)
|
right_sym := g.table.sym(node.right_type)
|
||||||
if left_sym.kind == .interface && right_sym.kind == .interface {
|
if left_sym.kind == .interface && right_sym.kind == .interface {
|
||||||
g.gen_interface_is_op(node)
|
g.gen_interface_is_op(node)
|
||||||
|
@ -880,7 +876,7 @@ fn (mut g Gen) infix_expr_is_op(node ast.InfixExpr) {
|
||||||
sub_sym := g.table.sym(sub_type)
|
sub_sym := g.table.sym(sub_type)
|
||||||
g.write('_${left_sym.cname}_${sub_sym.cname}_index')
|
g.write('_${left_sym.cname}_${sub_sym.cname}_index')
|
||||||
return
|
return
|
||||||
} else if left_sym.kind == .sum_type {
|
} else if left_sym.kind == .sum_type || is_aggregate {
|
||||||
g.write('_typ ${cmp_op} ')
|
g.write('_typ ${cmp_op} ')
|
||||||
}
|
}
|
||||||
if node.right is ast.None {
|
if node.right is ast.None {
|
||||||
|
|
|
@ -218,6 +218,9 @@ fn (mut g Gen) match_expr_sumtype(node ast.MatchExpr, is_expr bool, cond_var str
|
||||||
}
|
}
|
||||||
cur_expr := unsafe { &branch.exprs[sumtype_index] }
|
cur_expr := unsafe { &branch.exprs[sumtype_index] }
|
||||||
if cond_sym.kind == .sum_type {
|
if cond_sym.kind == .sum_type {
|
||||||
|
if cur_expr is ast.TypeNode {
|
||||||
|
g.type_resolver.update_ct_type(cond_var, cur_expr.typ)
|
||||||
|
}
|
||||||
g.write('${dot_or_ptr}_typ == ')
|
g.write('${dot_or_ptr}_typ == ')
|
||||||
if cur_expr is ast.None {
|
if cur_expr is ast.None {
|
||||||
g.write('${ast.none_type.idx()} /* none */')
|
g.write('${ast.none_type.idx()} /* none */')
|
||||||
|
|
25
vlib/v/tests/comptime/comptime_aggregate_var_test.v
Normal file
25
vlib/v/tests/comptime/comptime_aggregate_var_test.v
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
module main
|
||||||
|
|
||||||
|
type Value = int | i64 | u64 | string | []u8
|
||||||
|
|
||||||
|
fn d(val Value) string {
|
||||||
|
match val {
|
||||||
|
int, i64, u64, []u8 {
|
||||||
|
s := sizeof(val)
|
||||||
|
x := val
|
||||||
|
return 'Value is number or byte array, size=${s} ${x}'
|
||||||
|
}
|
||||||
|
string {
|
||||||
|
x := val
|
||||||
|
return 'Value is string: ${x}'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_main() {
|
||||||
|
assert d(Value(0)) == 'Value is number or byte array, size=4 0'
|
||||||
|
assert d(Value(i64(1))) == 'Value is number or byte array, size=8 1'
|
||||||
|
assert d(Value(u64(2))) == 'Value is number or byte array, size=8 2'
|
||||||
|
assert d(Value([u8(1), 2])) == 'Value is number or byte array, size=32 [1, 2]'
|
||||||
|
assert d(Value('')) == 'Value is string: '
|
||||||
|
}
|
|
@ -41,6 +41,6 @@ fn test_typeof_aggregate() {
|
||||||
|
|
||||||
assert rets.len == 3
|
assert rets.len == 3
|
||||||
assert rets[0] == 'The type of `a` is `Foo`'
|
assert rets[0] == 'The type of `a` is `Foo`'
|
||||||
assert rets[1] == 'The type of `a` is `(Bar | Baz | Bazaar)` and its text says bar'
|
assert rets[1] == 'The type of `a` is `Bar` and its text says bar'
|
||||||
assert rets[2] == 'The type of `a` is `(Bar | Baz | Bazaar)` and its text says baz'
|
assert rets[2] == 'The type of `a` is `Baz` and its text says baz'
|
||||||
}
|
}
|
||||||
|
|
|
@ -190,6 +190,13 @@ pub fn (mut t TypeResolver) get_type(node ast.Expr) ast.Type {
|
||||||
ctyp
|
ctyp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.aggregate {
|
||||||
|
t.get_ct_type_or_default(node.name, if node.obj.smartcasts.len > 0 {
|
||||||
|
node.obj.smartcasts.last()
|
||||||
|
} else {
|
||||||
|
node.obj.typ
|
||||||
|
})
|
||||||
|
}
|
||||||
.key_var, .value_var {
|
.key_var, .value_var {
|
||||||
// key and value variables from normal for stmt
|
// key and value variables from normal for stmt
|
||||||
t.get_ct_type_or_default(node.name, ast.void_type)
|
t.get_ct_type_or_default(node.name, ast.void_type)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue