Skip to content

Commit 12c20e3

Browse files
authored
checker: fix compound selector smartcasting/option unwrapping (fix #24662) (#24712)
1 parent 364f9eb commit 12c20e3

File tree

5 files changed

+48
-11
lines changed

5 files changed

+48
-11
lines changed

vlib/v/ast/scope.v

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,10 @@ pub fn (s &Scope) find_struct_field(name string, struct_type Type, field_name st
6565
if s == unsafe { nil } {
6666
return unsafe { nil }
6767
}
68+
k := '${name}.${field_name}'
6869
for sc := unsafe { s }; true; sc = sc.parent {
69-
if field := sc.struct_fields[name] {
70-
if field.struct_type == struct_type && field.name == field_name {
70+
if field := sc.struct_fields[k] {
71+
if field.struct_type == struct_type {
7172
return &ScopeStructField{
7273
...field
7374
}
@@ -164,12 +165,13 @@ pub fn (mut s Scope) update_smartcasts(name string, typ Type, is_unwrapped bool)
164165

165166
// selector_expr: name.field_name
166167
pub fn (mut s Scope) register_struct_field(name string, field ScopeStructField) {
167-
if f := s.struct_fields[name] {
168-
if f.struct_type == field.struct_type && f.name == field.name {
168+
k := '${name}.${field.name}'
169+
if f := s.struct_fields[k] {
170+
if f.struct_type == field.struct_type {
169171
return
170172
}
171173
}
172-
s.struct_fields[name] = field
174+
s.struct_fields[k] = field
173175
}
174176

175177
pub fn (mut s Scope) register(obj ScopeObject) {

vlib/v/checker/checker.v

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4416,7 +4416,12 @@ fn (mut c Checker) smartcast(mut expr ast.Expr, cur_type ast.Type, to_type_ ast.
44164416
orig_type = field.typ
44174417
}
44184418
}
4419-
expr_str := expr.expr.str()
4419+
mut expr_str := expr.expr.str()
4420+
if mut expr.expr is ast.ParExpr {
4421+
if mut expr.expr.expr is ast.AsCast {
4422+
expr_str = expr.expr.expr.expr.str()
4423+
}
4424+
}
44204425
field := scope.find_struct_field(expr_str, expr.expr_type, expr.field_name)
44214426
if field != unsafe { nil } {
44224427
smartcasts << field.smartcasts

vlib/v/gen/c/assign.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
346346
left.obj.typ = var_type
347347
g.assign_ct_type = var_type
348348
} else if val is ast.Ident && val.info is ast.IdentVar {
349-
val_info := (val as ast.Ident).info
349+
val_info := (val as ast.Ident).info as ast.IdentVar
350350
gen_or = val.or_expr.kind != .absent
351351
if val_info.is_option && gen_or {
352352
var_type = val_type.clear_flag(.option)

vlib/v/parser/orm.v

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -359,10 +359,12 @@ fn (mut p Parser) check_sql_where_expr_has_no_undefined_variables(expr &ast.Expr
359359
}
360360
}
361361
} else if expr is ast.InfixExpr {
362-
if expr.left is ast.Ident && expr.right is ast.Ident {
363-
return p.check_sql_where_expr_has_no_undefined_variables(expr.right, [
364-
expr.left.str(),
365-
])
362+
if expr.left is ast.Ident {
363+
if expr.right is ast.Ident {
364+
return p.check_sql_where_expr_has_no_undefined_variables(expr.right, [
365+
expr.left.name,
366+
])
367+
}
366368
}
367369

368370
left_check_result := p.check_sql_where_expr_has_no_undefined_variables(expr.left,
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
struct Options {
2+
option_1 ?[]int
3+
option_2 ?[]int
4+
}
5+
6+
fn test_none() {
7+
values := Options{
8+
option_1: [1, 2, 3]
9+
option_2: none
10+
}
11+
mut res := 0.0
12+
if values.option_1 != none && values.option_2 != none {
13+
res = values.option_1[0] + values.option_2[0]
14+
}
15+
assert res == 0
16+
}
17+
18+
fn test_add() {
19+
values := Options{
20+
option_1: [1, 2, 3]
21+
option_2: [3]
22+
}
23+
mut res := 0.0
24+
if values.option_1 != none && values.option_2 != none {
25+
res = values.option_1[0] + values.option_2[0]
26+
}
27+
assert res == 4
28+
}

0 commit comments

Comments
 (0)