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 smartcasts := []ast.Type{}
|
||||||
mut is_already_casted := false
|
mut is_already_casted := false
|
||||||
mut orig_type := 0
|
mut orig_type := 0
|
||||||
|
mut is_inherited := false
|
||||||
if mut expr.obj is ast.Var {
|
if mut expr.obj is ast.Var {
|
||||||
is_mut = expr.obj.is_mut
|
is_mut = expr.obj.is_mut
|
||||||
smartcasts << expr.obj.smartcasts
|
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 {
|
if orig_type == 0 {
|
||||||
orig_type = expr.obj.typ
|
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
|
// smartcast either if the value is immutable or if the mut argument is explicitly given
|
||||||
if (!is_mut || expr.is_mut) && !is_already_casted {
|
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
|
pos: expr.pos
|
||||||
is_used: true
|
is_used: true
|
||||||
is_mut: expr.is_mut
|
is_mut: expr.is_mut
|
||||||
|
is_inherited: is_inherited
|
||||||
smartcasts: smartcasts
|
smartcasts: smartcasts
|
||||||
orig_type: orig_type
|
orig_type: orig_type
|
||||||
})
|
})
|
||||||
|
@ -4348,6 +4348,9 @@ fn (mut g Gen) ident(node ast.Ident) {
|
|||||||
} else {
|
} else {
|
||||||
mut is_ptr := false
|
mut is_ptr := false
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
|
if node.obj.is_inherited {
|
||||||
|
g.write(closure_ctx + '->')
|
||||||
|
}
|
||||||
g.write(name)
|
g.write(name)
|
||||||
if node.obj.orig_type.is_ptr() {
|
if node.obj.orig_type.is_ptr() {
|
||||||
is_ptr = true
|
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