diff options
| author | 2026-10-15 02:35:44 +0330 | |
|---|---|---|
| committer | 2026-10-15 02:40:51 +0330 | |
| commit | 3de6ae4a6a74b2c4fa14c3f2d6fbfff3bb83c5f5 (patch) | |
| tree | 577ac1025bb02a11069cf288a38bfc5120e8402d /src/compiler | |
| parent | destructors: reassigning an m owner that still holds a value frees the old va... (diff) | |
destructors: nothing moves out of a value with a drop: pop on an array with a drop, or on an array field of a value with a drop, is error: a: can't move out of a value with drop (fields were already borrowed projections); spec 6.15.5, four conformance programs
Diffstat (limited to 'src/compiler')
| -rw-r--r-- | src/compiler/builtins.zc | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/src/compiler/builtins.zc b/src/compiler/builtins.zc index 8c00636..44ed3b1 100644 --- a/src/compiler/builtins.zc +++ b/src/compiler/builtins.zc @@ -670,13 +670,18 @@ int typearg() { } // len(a), cap(a), push(a, x), pop(a), resize(a, n): growable arrays. // len of a T[n] is just n. +// arrroot: the local the array belongs to (itself, or the owner of the struct it is a field of), or -1 +int arrroot = 0 - 1; word arrvalue(int c) { - argloc = -1; arrloc = -1; + argloc = -1; arrloc = -1; arrroot = -1; if (lv && lvk == LV_LOCAL && xty[0] == TY_DYN) { arrloc = lvi; if (o3on && o3cache[lvi]) argloc = lvi; } effect_value = effect_mask(c); rval(); plainuse(c); af_access(xaf, tpack()); + if (arrloc >= 0) arrroot = lroot(arrloc); + else if (c >= C_VAR && tracked(c - C_VAR)) arrroot = lroot(c - C_VAR); + else if (xbor >= 0 && tracked(xbor)) arrroot = lroot(xbor); return xty; } // parse an array argument and retain the receiver's mutation and bounds facts. @@ -803,6 +808,8 @@ int array_pop(word t) { if (isfl(xty)) xfloat = 1; xaf = 0; xbor = -1; effect_value = 0; if (isref(xty)) { + // pop moves the element out: not out of an array with a drop, whose drop may need it (6.15.5) + if (fchk && arrroot >= 0 && ldroppable(arrroot)) cerrn(arrroot, "can't move out of a value with drop"); xcls = C_FRESH; xaf = af_new(-1, 2, tpack()); newsz = -1; newleaf = 0; return C_FRESH; } return 0; |
