checker: allow `a[i]` for `shared` arrays outside `unsafe` (#8292)

pull/8298/head
Uwe Krüger 2021-01-23 13:33:32 +01:00 committed by GitHub
parent b8857baa98
commit 38880b23eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 11 additions and 26 deletions

View File

@ -4940,7 +4940,7 @@ pub fn (mut c Checker) index_expr(mut node ast.IndexExpr) table.Type {
if node.left.obj is ast.Var { if node.left.obj is ast.Var {
v := node.left.obj as ast.Var v := node.left.obj as ast.Var
// `mut param []T` function parameter // `mut param []T` function parameter
is_ok = v.is_mut && v.is_arg && !typ.deref().is_ptr() is_ok = ((v.is_mut && v.is_arg) || v.share == .shared_t) && !typ.deref().is_ptr()
} }
} }
if !is_ok && !c.pref.translated { if !is_ok && !c.pref.translated {

View File

@ -19,19 +19,14 @@ fn test_shared_array() {
go incr(shared foo, 1) go incr(shared foo, 1)
for _ in 0 .. 50000 { for _ in 0 .. 50000 {
lock foo { lock foo {
unsafe {
foo[0] -= 2 foo[0] -= 2
foo[1] += 3 foo[1] += 3
} }
} }
}
mut finished_threads := 0 mut finished_threads := 0
for { for {
rlock foo { rlock foo {
finished_threads = unsafe { finished_threads = foo[2]
foo[2]
}
} }
if finished_threads == 4 { if finished_threads == 4 {
break break
@ -39,14 +34,8 @@ fn test_shared_array() {
time.sleep_ms(100) time.sleep_ms(100)
} }
rlock foo { rlock foo {
f0 := unsafe { f0 := foo[0]
foo[0] f1 := foo[1]
}
f1 := unsafe {
foo[1]
}
assert f0 == 100010 assert f0 == 100010
assert f1 == 350020 assert f1 == 350020
} }

View File

@ -12,10 +12,8 @@ fn incr(shared foo map[string]int, key string, sem sync.Semaphore) {
fn test_shared_array() { fn test_shared_array() {
shared foo := &{'p': 10, 'q': 0} shared foo := &{'p': 10, 'q': 0}
lock foo { lock foo {
unsafe {
foo['q'] = 20 foo['q'] = 20
} }
}
sem := sync.new_semaphore() sem := sync.new_semaphore()
go incr(shared foo, 'p', sem) go incr(shared foo, 'p', sem)
go incr(shared foo, 'q', sem) go incr(shared foo, 'q', sem)
@ -23,18 +21,16 @@ fn test_shared_array() {
go incr(shared foo, 'q', sem) go incr(shared foo, 'q', sem)
for _ in 0 .. 50000 { for _ in 0 .. 50000 {
lock foo { lock foo {
unsafe {
foo['p'] -= 2 foo['p'] -= 2
foo['q'] += 3 foo['q'] += 3
} }
} }
}
for _ in 0..4 { for _ in 0..4 {
sem.wait() sem.wait()
} }
rlock foo { rlock foo {
fp := unsafe { foo['p'] } fp := foo['p']
fq := unsafe { foo['q'] } fq := foo['q']
assert fp == 100010 assert fp == 100010
assert fq == 350020 assert fq == 350020
} }