Skip to content

Commit 27f637a

Browse files
authored
checker: simplify unwrap nested selector fix (#23526)
1 parent facee32 commit 27f637a

File tree

5 files changed

+91
-35
lines changed

5 files changed

+91
-35
lines changed

vlib/v/ast/ast.v

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -925,9 +925,8 @@ pub:
925925
name string
926926
pos token.Pos
927927
typ Type
928-
orig_type Type // original sumtype type; 0 if it's not a sumtype
929-
pub mut:
930-
smartcasts []Type // nested sum types require nested smart casting, for that a list of types is needed
928+
orig_type Type // original sumtype type; 0 if it's not a sumtype
929+
smartcasts []Type // nested sum types require nested smart casting, for that a list of types is needed
931930
// TODO: move this to a real docs site later
932931
// 10 <- original type (orig_type)
933932
// [11, 12, 13] <- cast order (smartcasts)

vlib/v/ast/scope.v

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -157,16 +157,6 @@ pub fn (mut s Scope) register_struct_field(name string, field ScopeStructField)
157157
s.struct_fields[name] = field
158158
}
159159

160-
pub fn (mut s Scope) register_or_update_struct_field(name string, field ScopeStructField) {
161-
if mut f := s.struct_fields[name] {
162-
if f.struct_type == field.struct_type && f.name == field.name {
163-
s.struct_fields[name].smartcasts = field.smartcasts
164-
return
165-
}
166-
}
167-
s.struct_fields[name] = field
168-
}
169-
170160
pub fn (mut s Scope) register(obj ScopeObject) {
171161
if !(obj.name == '_' || obj.name in s.objects) {
172162
s.objects[obj.name] = obj

vlib/v/checker/checker.v

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4286,33 +4286,21 @@ fn (mut c Checker) smartcast(mut expr ast.Expr, cur_type ast.Type, to_type_ ast.
42864286
orig_type = field.typ
42874287
}
42884288
}
4289-
mut nested_unwrap := false
4290-
if mut field := scope.find_struct_field(expr.expr.str(), expr.expr_type, expr.field_name) {
4289+
expr_str := expr.expr.str()
4290+
if mut field := scope.find_struct_field(expr_str, expr.expr_type, expr.field_name) {
42914291
smartcasts << field.smartcasts
4292-
nested_unwrap = smartcasts.len > 1
42934292
}
42944293
// smartcast either if the value is immutable or if the mut argument is explicitly given
42954294
if !is_mut || expr.is_mut || is_option_unwrap || orig_type.has_flag(.option) {
42964295
smartcasts << to_type
4297-
if nested_unwrap {
4298-
scope.register_or_update_struct_field(expr.expr.str(), ast.ScopeStructField{
4299-
struct_type: expr.expr_type
4300-
name: expr.field_name
4301-
typ: cur_type
4302-
smartcasts: smartcasts
4303-
pos: expr.pos
4304-
orig_type: orig_type
4305-
})
4306-
} else {
4307-
scope.register_struct_field(expr.expr.str(), ast.ScopeStructField{
4308-
struct_type: expr.expr_type
4309-
name: expr.field_name
4310-
typ: cur_type
4311-
smartcasts: smartcasts
4312-
pos: expr.pos
4313-
orig_type: orig_type
4314-
})
4315-
}
4296+
scope.register_struct_field(expr_str, ast.ScopeStructField{
4297+
struct_type: expr.expr_type
4298+
name: expr.field_name
4299+
typ: cur_type
4300+
smartcasts: smartcasts
4301+
pos: expr.pos
4302+
orig_type: orig_type
4303+
})
43164304
} else {
43174305
c.smartcast_mut_pos = expr.pos
43184306
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
type SumType = int | string | f64
2+
3+
struct Foo[T] {
4+
field ?SumType
5+
}
6+
7+
fn t[T](val Foo[T]) {
8+
if val.field != none {
9+
if val.field is string {
10+
dump(val.field)
11+
assert val.field == 'foo'
12+
} else if val.field is int {
13+
dump(val.field)
14+
assert val.field == 1
15+
} else if val.field is f64 {
16+
dump(val.field)
17+
assert val.field == 1.23
18+
}
19+
} else {
20+
dump(val.field)
21+
assert val.field == none
22+
}
23+
}
24+
25+
fn test_main() {
26+
t(Foo[int]{})
27+
t(Foo[string]{})
28+
t(Foo[f64]{})
29+
30+
t(Foo[int]{ field: 1 })
31+
t(Foo[string]{ field: 'foo' })
32+
t(Foo[f64]{ field: 1.23 })
33+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
module main
2+
3+
type Foo = string | int | f32
4+
5+
struct Svc {
6+
mut:
7+
log ?Foo
8+
}
9+
10+
fn t(v string) !string {
11+
return v
12+
}
13+
14+
fn Svc.init(log ?Foo) Svc {
15+
mut svc := Svc{
16+
log: log
17+
}
18+
if svc.log != none {
19+
if svc.log is string {
20+
assert svc.log.str() == 'foo'
21+
_ := t(svc.log) or { panic(err) }
22+
} else {
23+
assert false
24+
}
25+
assert true
26+
}
27+
return svc
28+
}
29+
30+
struct CSvc {
31+
Svc
32+
pub mut:
33+
log ?Foo
34+
}
35+
36+
pub fn CSvc.init(log ?Foo) CSvc {
37+
mut c := CSvc{
38+
log: log
39+
}
40+
c.Svc = Svc.init(log)
41+
return c
42+
}
43+
44+
fn test_main() {
45+
CSvc.init('foo')
46+
}

0 commit comments

Comments
 (0)