1
0
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:
Felipe Pena 2023-05-08 18:22:22 -03:00 committed by GitHub
parent 6ac09e605e
commit 1e56a69c02
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 60 additions and 4 deletions

View File

@ -635,6 +635,8 @@ pub:
pos token.Pos pos token.Pos
name string name string
is_mut bool is_mut bool
is_shared bool
is_atomic bool
is_auto_rec bool is_auto_rec bool
type_pos token.Pos type_pos token.Pos
is_hidden bool // interface first arg is_hidden bool // interface first arg
@ -642,6 +644,18 @@ pub mut:
typ Type 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 { pub fn (f &Fn) new_method_with_receiver_type(new_type Type) Fn {
unsafe { unsafe {
mut new_method := f mut new_method := f

View File

@ -50,7 +50,11 @@ pub fn (node &AnonFn) stringify(t &Table, cur_mod string, m2a map[string]string)
if i > 0 { if i > 0 {
f.write_string(', ') 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('mut ')
} }
f.write_string(var.name) f.write_string(var.name)

View File

@ -2524,7 +2524,7 @@ pub fn (mut c Checker) expr(node_ ast.Expr) ast.Type {
} else { } else {
tsym.cname 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 node.cname = type_cname
return node.expr_type return node.expr_type
} }

View File

@ -1086,7 +1086,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast.
} }
} else { } else {
if param.is_mut { 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', c.error('function `${node.name}` parameter `${param.name}` is `${tok}`, so use `${tok} ${call_arg.expr}` instead',
call_arg.expr.pos()) call_arg.expr.pos())
} else { } else {
@ -2056,7 +2056,7 @@ fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
} }
} else { } else {
if param.is_mut { 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', c.error('method `${node.name}` parameter ${i + 1} is `${tok}`, so use `${tok} ${arg.expr}` instead',
arg.expr.pos()) arg.expr.pos())
} else { } else {

View File

@ -692,6 +692,8 @@ fn (mut p Parser) fn_receiver(mut params []ast.Param, mut rec ReceiverParsingInf
pos: rec_start_pos pos: rec_start_pos
name: rec.name name: rec.name
is_mut: rec.is_mut is_mut: rec.is_mut
is_atomic: is_atomic
is_shared: is_shared
is_auto_rec: is_auto_rec is_auto_rec: is_auto_rec
typ: rec.typ typ: rec.typ
type_pos: rec.type_pos type_pos: rec.type_pos
@ -1006,6 +1008,8 @@ fn (mut p Parser) fn_args() ([]ast.Param, bool, bool) {
pos: arg_pos[i] pos: arg_pos[i]
name: arg_name name: arg_name
is_mut: is_mut is_mut: is_mut
is_atomic: is_atomic
is_shared: is_shared
typ: typ typ: typ
type_pos: type_pos[i] type_pos: type_pos[i]
} }
@ -1090,6 +1094,8 @@ fn (mut p Parser) closure_vars() []ast.Param {
pos: var_pos pos: var_pos
name: var_name name: var_name
is_mut: is_mut is_mut: is_mut
is_atomic: is_atomic
is_shared: is_shared
} }
if p.tok.kind != .comma { if p.tok.kind != .comma {
break break

View 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
}
}