mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker, parser: save shared/atomic specifier for ast.Param (#18124)
This commit is contained in:
parent
6ac09e605e
commit
1e56a69c02
@ -635,6 +635,8 @@ pub:
|
||||
pos token.Pos
|
||||
name string
|
||||
is_mut bool
|
||||
is_shared bool
|
||||
is_atomic bool
|
||||
is_auto_rec bool
|
||||
type_pos token.Pos
|
||||
is_hidden bool // interface first arg
|
||||
@ -642,6 +644,18 @@ pub mut:
|
||||
typ Type
|
||||
}
|
||||
|
||||
pub fn (p &Param) specifier() string {
|
||||
if p.is_shared {
|
||||
return 'shared'
|
||||
} else if p.is_atomic {
|
||||
return 'atomic'
|
||||
} else if p.is_mut {
|
||||
return 'mut'
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (f &Fn) new_method_with_receiver_type(new_type Type) Fn {
|
||||
unsafe {
|
||||
mut new_method := f
|
||||
|
@ -50,7 +50,11 @@ pub fn (node &AnonFn) stringify(t &Table, cur_mod string, m2a map[string]string)
|
||||
if i > 0 {
|
||||
f.write_string(', ')
|
||||
}
|
||||
if var.is_mut {
|
||||
if var.is_shared {
|
||||
f.write_string('shared ')
|
||||
} else if var.is_atomic {
|
||||
f.write_string('atomic ')
|
||||
} else if var.is_mut {
|
||||
f.write_string('mut ')
|
||||
}
|
||||
f.write_string(var.name)
|
||||
|
@ -2524,7 +2524,7 @@ pub fn (mut c Checker) expr(node_ ast.Expr) ast.Type {
|
||||
} else {
|
||||
tsym.cname
|
||||
}
|
||||
c.table.dumps[int(unwrapped_expr_type.clear_flag(.result))] = type_cname
|
||||
c.table.dumps[int(unwrapped_expr_type.clear_flag(.result).clear_flag(.atomic_f))] = type_cname
|
||||
node.cname = type_cname
|
||||
return node.expr_type
|
||||
}
|
||||
|
@ -1086,7 +1086,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast.
|
||||
}
|
||||
} else {
|
||||
if param.is_mut {
|
||||
tok := if param.typ.has_flag(.shared_f) { 'shared' } else { call_arg.share.str() }
|
||||
tok := param.specifier()
|
||||
c.error('function `${node.name}` parameter `${param.name}` is `${tok}`, so use `${tok} ${call_arg.expr}` instead',
|
||||
call_arg.expr.pos())
|
||||
} else {
|
||||
@ -2056,7 +2056,7 @@ fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
|
||||
}
|
||||
} else {
|
||||
if param.is_mut {
|
||||
tok := if param.typ.has_flag(.shared_f) { 'shared' } else { arg.share.str() }
|
||||
tok := param.specifier()
|
||||
c.error('method `${node.name}` parameter ${i + 1} is `${tok}`, so use `${tok} ${arg.expr}` instead',
|
||||
arg.expr.pos())
|
||||
} else {
|
||||
|
@ -692,6 +692,8 @@ fn (mut p Parser) fn_receiver(mut params []ast.Param, mut rec ReceiverParsingInf
|
||||
pos: rec_start_pos
|
||||
name: rec.name
|
||||
is_mut: rec.is_mut
|
||||
is_atomic: is_atomic
|
||||
is_shared: is_shared
|
||||
is_auto_rec: is_auto_rec
|
||||
typ: rec.typ
|
||||
type_pos: rec.type_pos
|
||||
@ -1006,6 +1008,8 @@ fn (mut p Parser) fn_args() ([]ast.Param, bool, bool) {
|
||||
pos: arg_pos[i]
|
||||
name: arg_name
|
||||
is_mut: is_mut
|
||||
is_atomic: is_atomic
|
||||
is_shared: is_shared
|
||||
typ: typ
|
||||
type_pos: type_pos[i]
|
||||
}
|
||||
@ -1090,6 +1094,8 @@ fn (mut p Parser) closure_vars() []ast.Param {
|
||||
pos: var_pos
|
||||
name: var_name
|
||||
is_mut: is_mut
|
||||
is_atomic: is_atomic
|
||||
is_shared: is_shared
|
||||
}
|
||||
if p.tok.kind != .comma {
|
||||
break
|
||||
|
32
vlib/v/tests/inherited_vars_test.v
Normal file
32
vlib/v/tests/inherited_vars_test.v
Normal file
@ -0,0 +1,32 @@
|
||||
struct Shared {
|
||||
mut:
|
||||
a int
|
||||
}
|
||||
|
||||
fn test_atomic() {
|
||||
atomic a := 0
|
||||
a++
|
||||
|
||||
fn [atomic a] () {
|
||||
a++
|
||||
dump(a)
|
||||
}()
|
||||
dump(a)
|
||||
assert a == 1
|
||||
}
|
||||
|
||||
fn test_shared() {
|
||||
shared b := Shared{
|
||||
a: 0
|
||||
}
|
||||
|
||||
fn [shared b] () {
|
||||
lock b {
|
||||
b.a++
|
||||
}
|
||||
}()
|
||||
rlock b {
|
||||
dump(b.a)
|
||||
assert b.a == 1
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user