mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
parent
5f0ad64155
commit
3e3b289583
@ -164,6 +164,12 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
|
||||
mut right := if i < node.right.len { node.right[i] } else { node.right[0] }
|
||||
mut right_type := node.right_types[i]
|
||||
if mut right is ast.Ident {
|
||||
// resolve shared right vairable
|
||||
if right_type.has_flag(.shared_f) {
|
||||
if c.fail_if_unreadable(right, right_type, 'right-hand side of assignment') {
|
||||
return
|
||||
}
|
||||
}
|
||||
right_sym := c.table.sym(right_type)
|
||||
if right_sym.info is ast.Struct {
|
||||
if right_sym.info.generic_types.len > 0 {
|
||||
|
@ -4664,7 +4664,8 @@ fn (mut c Checker) ensure_type_exists(typ ast.Type, pos token.Pos) ? {
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut c Checker) fail_if_unreadable(expr ast.Expr, typ ast.Type, what string) {
|
||||
// return true if a violation of a shared variable access rule is detected
|
||||
fn (mut c Checker) fail_if_unreadable(expr ast.Expr, typ ast.Type, what string) bool {
|
||||
mut pos := token.Pos{}
|
||||
match expr {
|
||||
ast.Ident {
|
||||
@ -4673,9 +4674,10 @@ fn (mut c Checker) fail_if_unreadable(expr ast.Expr, typ ast.Type, what string)
|
||||
action := if what == 'argument' { 'passed' } else { 'used' }
|
||||
c.error('`${expr.name}` is `shared` and must be `rlock`ed or `lock`ed to be ${action} as non-mut ${what}',
|
||||
expr.pos)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return
|
||||
return false
|
||||
}
|
||||
ast.SelectorExpr {
|
||||
pos = expr.pos
|
||||
@ -4685,31 +4687,42 @@ fn (mut c Checker) fail_if_unreadable(expr ast.Expr, typ ast.Type, what string)
|
||||
action := if what == 'argument' { 'passed' } else { 'used' }
|
||||
c.error('`${expr_name}` is `shared` and must be `rlock`ed or `lock`ed to be ${action} as non-mut ${what}',
|
||||
expr.pos)
|
||||
return true
|
||||
}
|
||||
return
|
||||
return false
|
||||
} else {
|
||||
c.fail_if_unreadable(expr.expr, expr.expr_type, what)
|
||||
if c.fail_if_unreadable(expr.expr, expr.expr_type, what) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
ast.CallExpr {
|
||||
pos = expr.pos
|
||||
if expr.is_method {
|
||||
c.fail_if_unreadable(expr.left, expr.left_type, what)
|
||||
if c.fail_if_unreadable(expr.left, expr.left_type, what) {
|
||||
return true
|
||||
}
|
||||
return
|
||||
}
|
||||
return false
|
||||
}
|
||||
ast.LockExpr {
|
||||
// TODO: check expressions inside the lock by appending to c.(r)locked_names
|
||||
return
|
||||
return false
|
||||
}
|
||||
ast.IndexExpr {
|
||||
pos = expr.left.pos().extend(expr.pos)
|
||||
c.fail_if_unreadable(expr.left, expr.left_type, what)
|
||||
if c.fail_if_unreadable(expr.left, expr.left_type, what) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
ast.InfixExpr {
|
||||
pos = expr.left.pos().extend(expr.pos)
|
||||
c.fail_if_unreadable(expr.left, expr.left_type, what)
|
||||
c.fail_if_unreadable(expr.right, expr.right_type, what)
|
||||
if c.fail_if_unreadable(expr.left, expr.left_type, what) {
|
||||
return true
|
||||
}
|
||||
if c.fail_if_unreadable(expr.right, expr.right_type, what) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
else {
|
||||
pos = expr.pos()
|
||||
@ -4718,7 +4731,9 @@ fn (mut c Checker) fail_if_unreadable(expr ast.Expr, typ ast.Type, what string)
|
||||
if typ.has_flag(.shared_f) {
|
||||
c.error('you have to create a handle and `rlock` it to use a `shared` element as non-mut ${what}',
|
||||
pos)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fn (mut c Checker) fail_if_stack_struct_action_outside_unsafe(mut ident ast.Ident, failed_action string) {
|
||||
|
13
vlib/v/checker/tests/shared_param_assign_err.out
Normal file
13
vlib/v/checker/tests/shared_param_assign_err.out
Normal file
@ -0,0 +1,13 @@
|
||||
vlib/v/checker/tests/shared_param_assign_err.vv:2:10: error: `arr` is `shared` and must be `rlock`ed or `lock`ed to be used as non-mut right-hand side of assignment
|
||||
1 | fn foo(shared arr []string) {
|
||||
2 | arr2 := arr
|
||||
| ~~~
|
||||
3 | println(arr2)
|
||||
4 | }
|
||||
vlib/v/checker/tests/shared_param_assign_err.vv:3:10: error: `arr2` is `shared` and must be `rlock`ed or `lock`ed to be used as non-mut argument to print
|
||||
1 | fn foo(shared arr []string) {
|
||||
2 | arr2 := arr
|
||||
3 | println(arr2)
|
||||
| ~~~~
|
||||
4 | }
|
||||
5 |
|
9
vlib/v/checker/tests/shared_param_assign_err.vv
Normal file
9
vlib/v/checker/tests/shared_param_assign_err.vv
Normal file
@ -0,0 +1,9 @@
|
||||
fn foo(shared arr []string) {
|
||||
arr2 := arr
|
||||
println(arr2)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
shared arr := ['']
|
||||
foo(shared arr)
|
||||
}
|
Loading…
Reference in New Issue
Block a user