Skip to content

Commit 052e5af

Browse files
authored
checker: fix assign check, when rechecking for another concrete type (#23212)
1 parent 8f684c7 commit 052e5af

File tree

5 files changed

+78
-5
lines changed

5 files changed

+78
-5
lines changed

vlib/v/checker/assign.v

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,17 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
182182
node.right_types << c.check_expr_option_or_result_call(node.right[i],
183183
right_type)
184184
}
185+
} else {
186+
// on generic recheck phase it might be needed to resolve the rhs again
187+
if i < node.right.len && c.comptime.has_comptime_expr(node.right[i]) {
188+
mut expr := mut node.right[i]
189+
old_inside_recheck := c.inside_recheck
190+
c.inside_recheck = true
191+
right_type := c.expr(mut expr)
192+
node.right_types[i] = c.check_expr_option_or_result_call(node.right[i],
193+
right_type)
194+
c.inside_recheck = old_inside_recheck
195+
}
185196
}
186197
mut right := if i < node.right.len { node.right[i] } else { node.right[0] }
187198
mut right_type := node.right_types[i]
@@ -494,7 +505,6 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
494505
if (left.is_map || left.is_farray) && left.is_setter {
495506
left.recursive_mapset_is_setter(true)
496507
}
497-
498508
right_type = c.comptime.get_type_or_default(right, right_type)
499509
}
500510
if mut left is ast.InfixExpr {

vlib/v/checker/checker.v

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ pub mut:
7777
is_builtin_mod bool // true inside the 'builtin', 'os' or 'strconv' modules; TODO: remove the need for special casing this
7878
is_just_builtin_mod bool // true only inside 'builtin'
7979
is_generated bool // true for `@[generated] module xyz` .v files
80+
inside_recheck bool // true when rechecking rhs assign statement
8081
inside_unsafe bool // true inside `unsafe {}` blocks
8182
inside_const bool // true inside `const ( ... )` blocks
8283
inside_anon_fn bool // true inside `fn() { ... }()`
@@ -1774,7 +1775,7 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
17741775
}
17751776

17761777
if has_field {
1777-
is_used_outside := sym.mod != c.mod
1778+
is_used_outside := !c.inside_recheck && sym.mod != c.mod
17781779
if is_used_outside && !field.is_pub && sym.language != .c {
17791780
unwrapped_sym := c.table.sym(c.unwrap_generic(typ))
17801781
c.error('field `${unwrapped_sym.name}.${field_name}` is not public', node.pos)

vlib/v/comptime/comptimeinfo.v

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,17 @@ pub fn (mut ct ComptimeInfo) is_comptime_expr(node ast.Expr) bool {
3636
|| node is ast.ComptimeSelector
3737
}
3838

39+
// has_comptime_expr checks if the expr contains some comptime expr
40+
@[inline]
41+
pub fn (mut ct ComptimeInfo) has_comptime_expr(node ast.Expr) bool {
42+
return (node is ast.Ident && node.ct_expr)
43+
|| (node is ast.IndexExpr && ct.has_comptime_expr(node.left))
44+
|| node is ast.ComptimeSelector
45+
|| (node is ast.SelectorExpr && ct.has_comptime_expr(node.expr))
46+
|| (node is ast.InfixExpr && (ct.has_comptime_expr(node.left)
47+
|| ct.has_comptime_expr(node.right)))
48+
}
49+
3950
// is_comptime checks if the node is related to a comptime marked variable
4051
@[inline]
4152
pub fn (mut ct ComptimeInfo) is_comptime(node ast.Expr) bool {
@@ -100,6 +111,7 @@ pub fn (mut ct ComptimeInfo) get_expr_type_or_default(node ast.Expr, default_typ
100111
}
101112

102113
// get_type_or_default retries the comptime value if the AST node is related to comptime otherwise default_typ is returned
114+
@[inline]
103115
pub fn (mut ct ComptimeInfo) get_type_or_default(node ast.Expr, default_typ ast.Type) ast.Type {
104116
match node {
105117
ast.Ident {
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
module main
2+
3+
pub struct Vector[T] {
4+
n int
5+
values []T
6+
}
7+
8+
pub fn Vector.new[T](v []T) Vector[T] {
9+
return Vector[T]{
10+
n: v.len
11+
values: v
12+
}
13+
}
14+
15+
pub fn (v Vector[T]) str() string {
16+
return v.values.str()
17+
}
18+
19+
pub fn (v Vector[T]) + (u Vector[T]) Vector[T] {
20+
assert v.n == u.n
21+
return Vector[T]{
22+
n: v.n
23+
values: []T{len: v.n, init: T(v.values[index] + u.values[index])}
24+
}
25+
}
26+
27+
pub fn (v Vector[T]) dot(u Vector[T]) T {
28+
assert v.n == u.n
29+
mut sum := T(0)
30+
for i in 0 .. v.n {
31+
sum += v.values[i] * u.values[i]
32+
}
33+
return sum
34+
}
35+
36+
fn test_main() {
37+
v := Vector.new[f64]([1.0, 2, 3])
38+
vdotv := v.dot(v)
39+
assert vdotv == 14.0
40+
41+
u := Vector.new[int]([1, 2, 3])
42+
udotu := u.dot(u)
43+
assert udotu == 14
44+
}

vlib/x/json2/decoder2/decode_sumtype.v

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,15 @@ fn (mut decoder Decoder) get_decoded_sumtype_workaround[T](initialized_sumtype T
88
if initialized_sumtype is v {
99
// workaround for auto generated function considering sumtype as array
1010
unsafe {
11-
mut val := initialized_sumtype
12-
decoder.decode_value(mut val)!
13-
return T(val)
11+
$if initialized_sumtype is $map {
12+
mut val := initialized_sumtype.clone()
13+
decoder.decode_value(mut val)!
14+
return T(val)
15+
} $else {
16+
mut val := initialized_sumtype
17+
decoder.decode_value(mut val)!
18+
return T(val)
19+
}
1420
}
1521
}
1622
}

0 commit comments

Comments
 (0)