mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker, cgen: fix closure with inherited sumtype variable (#18894)
This commit is contained in:
parent
e71370dc40
commit
44d2f2b302
@ -3650,6 +3650,7 @@ fn (mut c Checker) smartcast(mut expr ast.Expr, cur_type ast.Type, to_type_ ast.
|
||||
mut smartcasts := []ast.Type{}
|
||||
mut is_already_casted := false
|
||||
mut orig_type := 0
|
||||
mut is_inherited := false
|
||||
if mut expr.obj is ast.Var {
|
||||
is_mut = expr.obj.is_mut
|
||||
smartcasts << expr.obj.smartcasts
|
||||
@ -3657,6 +3658,7 @@ fn (mut c Checker) smartcast(mut expr ast.Expr, cur_type ast.Type, to_type_ ast.
|
||||
if orig_type == 0 {
|
||||
orig_type = expr.obj.typ
|
||||
}
|
||||
is_inherited = expr.obj.is_inherited
|
||||
}
|
||||
// smartcast either if the value is immutable or if the mut argument is explicitly given
|
||||
if (!is_mut || expr.is_mut) && !is_already_casted {
|
||||
@ -3667,6 +3669,7 @@ fn (mut c Checker) smartcast(mut expr ast.Expr, cur_type ast.Type, to_type_ ast.
|
||||
pos: expr.pos
|
||||
is_used: true
|
||||
is_mut: expr.is_mut
|
||||
is_inherited: is_inherited
|
||||
smartcasts: smartcasts
|
||||
orig_type: orig_type
|
||||
})
|
||||
|
@ -4348,6 +4348,9 @@ fn (mut g Gen) ident(node ast.Ident) {
|
||||
} else {
|
||||
mut is_ptr := false
|
||||
if i == 0 {
|
||||
if node.obj.is_inherited {
|
||||
g.write(closure_ctx + '->')
|
||||
}
|
||||
g.write(name)
|
||||
if node.obj.orig_type.is_ptr() {
|
||||
is_ptr = true
|
||||
|
75
vlib/v/tests/closure_with_sumtype_var_test.v
Normal file
75
vlib/v/tests/closure_with_sumtype_var_test.v
Normal file
@ -0,0 +1,75 @@
|
||||
import encoding.binary
|
||||
import rand
|
||||
|
||||
type DataType = int | string
|
||||
|
||||
struct DataBuilder {
|
||||
mut:
|
||||
func fn (mut []u8)
|
||||
len int
|
||||
}
|
||||
|
||||
pub fn (mut d DataBuilder) add(v DataType) {
|
||||
func := d.func
|
||||
len := d.len
|
||||
d.func = fn [v, len, func] (mut b []u8) {
|
||||
if !isnil(func) {
|
||||
func(mut b)
|
||||
}
|
||||
match v {
|
||||
int {
|
||||
binary.big_endian_put_u32_at(mut b, u32(v), len)
|
||||
}
|
||||
string {
|
||||
binary.big_endian_put_u16_at(mut b, u16(v.len), len)
|
||||
for i := 0; i < v.len; i++ {
|
||||
b[len + 2 + i] = v[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
d.len += match v {
|
||||
int { 4 }
|
||||
string { 2 + v.len }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (d &DataBuilder) build() []u8 {
|
||||
mut b := []u8{len: d.len}
|
||||
d.func(mut b)
|
||||
binary.big_endian_put_u16(mut b, u16(d.len - 2))
|
||||
unsafe {
|
||||
d.func = nil
|
||||
d.len = 2
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
fn new_data_builder() DataBuilder {
|
||||
return DataBuilder{
|
||||
func: unsafe { nil }
|
||||
len: 2
|
||||
}
|
||||
}
|
||||
|
||||
fn test_closure_with_sumtype_var() {
|
||||
mut data := new_data_builder()
|
||||
data.add(1)
|
||||
data.add(2)
|
||||
data.add(3)
|
||||
data.add(4)
|
||||
data.add(5)
|
||||
data.add('1')
|
||||
data.add('22')
|
||||
data.add('334455')
|
||||
data.add(rand.string(rand.int_in_range(10, 100)!))
|
||||
data.add('5')
|
||||
data.add(1)
|
||||
data.add(2)
|
||||
data.add(3)
|
||||
data.add(4)
|
||||
data.add(5)
|
||||
ret := data.build()
|
||||
dump(ret)
|
||||
assert binary.big_endian_u16_at(ret, 0) == ret[2..].len
|
||||
}
|
Loading…
Reference in New Issue
Block a user