@@ -5063,6 +5063,32 @@ fn (mut c Checker) lock_expr(mut node ast.LockExpr) ast.Type {
50635063 mut last_stmt := node.stmts.last ()
50645064 if mut last_stmt is ast.ExprStmt {
50655065 c.expected_type = expected_type
5066+ // Check for shared array slice - auto clone for safety
5067+ if mut last_stmt.expr is ast.IndexExpr {
5068+ index_expr := last_stmt.expr
5069+ if index_expr.index is ast.RangeExpr && index_expr.left_type.has_flag (.shared_f)
5070+ && ! c.inside_unsafe {
5071+ // Slicing a shared array creates a view over shared memory.
5072+ // Auto-clone for safety to avoid data races.
5073+ c.add_error_detail_with_pos ('To silence this notice, use either an explicit `.clone()`,
5074+ or use an explicit `unsafe{ ... }` block, if you do not want a copy of the slice.' ,
5075+ index_expr.pos)
5076+ c.note ('an implicit clone of the shared array slice was done here' ,
5077+ index_expr.pos)
5078+ slice_type := index_expr.typ
5079+ last_stmt.expr = ast.CallExpr{
5080+ name: 'clone'
5081+ kind: .clone
5082+ left: index_expr
5083+ left_type: slice_type
5084+ is_method: true
5085+ receiver_type: slice_type
5086+ return_type: slice_type
5087+ scope: c.fn_scope
5088+ is_return_used: true
5089+ }
5090+ }
5091+ }
50665092 ret_type = c.expr (mut last_stmt.expr)
50675093 }
50685094 }
@@ -5529,12 +5555,13 @@ fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type {
55295555 }
55305556 // array[1..2] => array
55315557 // fixed_array[1..2] => array
5558+ // shared array[1..2] => array (slicing creates a new non-shared array)
55325559 if typ_sym.kind == .array_fixed {
55335560 elem_type := c.table.value_type (typ)
55345561 idx := c.table.find_or_register_array (elem_type)
55355562 typ = ast.new_type (idx)
55365563 } else {
5537- typ = typ.set_nr_muls (0 )
5564+ typ = typ.set_nr_muls (0 ). clear_flag (.shared_f)
55385565 }
55395566 } else { // [1]
55405567 if typ_sym.kind == .map {
0 commit comments