For var/let bindings defined in loops, the aliveEnd is now only
updated during the first analysis of the loop. This ensures that
variables defined outside the loop, but only assigned to within the
loop, always have longer alive times than variables defined within
loops, thus preventing outer variables borrowing from inner variables
(cursorfication cannot happen when a variable outlives its assignment
source).
This fix also renders the isConditionallyReassigned heuristic
obsolete, which was used to fix a more specific case of the same bug.
The heuristic disabled cursorfication for all variables of which
re-assignments are enclosed by a loop and if/else/elif/of,
which also applied to, e.g.:
while cond:
if cond:
var a = newString(...)
var b = newString(...)
var x: string
x = a
x = b # this assignment disabled `x` being turned into a cursor
discard a
With the heuristic removed, in the above example, x is now turned
into a cursor, matching what would happen when there is no enclosing
loop or if.
Summary
var
/let
bindings are now inferred to be cursors more reliablyFixes https://github.com/nim-works/nimskull/issues/1385
Details
For
var
/let
bindings defined in loops, thealiveEnd
is now only updated during the first analysis of the loop. This ensures that variables defined outside the loop, but only assigned to within the loop, always have longer alive times than variables defined within loops, thus preventing outer variables borrowing from inner variables (cursorfication cannot happen when a variable outlives its assignment source).This fix also renders the
isConditionallyReassigned
heuristic obsolete, which was used to fix a more specific case of the same bug. The heuristic disabled cursorfication for all variables of which re-assignments are enclosed by a loop andif
/else
/elif
/of
, which also applied to, e.g.:With the heuristic removed, in the above example,
x
is now turned into a cursor, matching what would happen when there is no enclosing loop orif
.