definite assignment analysis for let (#21024)

* draft for let daa

* patch

* fixes bugs

* errors for global let variable reassignments

* checkpoint

* out param accepts let

* add more tests

* add documentation

* merge tests
This commit is contained in:
ringabout 2022-12-06 17:19:12 +08:00 • committed by GitHub
commit b2c7019006
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 144 additions and 30 deletions

View file

@ -557,15 +557,16 @@ proc semVarMacroPragma(c: PContext, a: PNode, n: PNode): PNode =
return result
template isLocalSym(sym: PSym): bool =
sym.kind in {skVar, skLet} and not
({sfGlobal, sfPure} * sym.flags != {} or
sfCompileTime in sym.flags) or
sym.kind in {skProc, skFunc, skIterator} and
sfGlobal notin sym.flags
template isLocalVarSym(n: PNode): bool =
n.kind == nkSym and
(n.sym.kind in {skVar, skLet} and not
({sfGlobal, sfPure} * n.sym.flags != {} or
sfCompileTime in n.sym.flags) or
n.sym.kind in {skProc, skFunc, skIterator} and
sfGlobal notin n.sym.flags
)
n.kind == nkSym and isLocalSym(n.sym)
proc usesLocalVar(n: PNode): bool =
for z in 1 ..< n.len:
if n[z].isLocalVarSym:
@ -718,7 +719,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
else:
checkNilable(c, v)
# allow let to not be initialised if imported from C:
if v.kind == skLet and sfImportc notin v.flags:
if v.kind == skLet and sfImportc notin v.flags and (strictDefs notin c.features or not isLocalSym(v)):
localError(c.config, a.info, errLetNeedsInit)
if sfCompileTime in v.flags:
var x = newNodeI(result.kind, v.info)