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

@ -1919,13 +1919,16 @@ proc implicitConv(kind: TNodeKind, f: PType, arg: PNode, m: TCandidate,
result.add c.graph.emptyNode
result.add arg
proc isLValue(c: PContext; n: PNode): bool {.inline.} =
proc isLValue(c: PContext; n: PNode, isOutParam = false): bool {.inline.} =
let aa = isAssignable(nil, n)
case aa
of arLValue, arLocalLValue, arStrange:
result = true
of arDiscriminant:
result = c.inUncheckedAssignSection > 0
of arAddressableConst:
let sym = getRoot(n)
result = strictDefs in c.features and sym != nil and sym.kind == skLet and isOutParam
else:
result = false
@ -2396,7 +2399,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, m: var TCandidate, marker: var Int
if argConverter.typ.kind notin {tyVar}:
m.firstMismatch.kind = kVarNeeded
noMatch()
elif not isLValue(c, n):
elif not (isLValue(c, n, isOutParam(formal.typ))):
m.firstMismatch.kind = kVarNeeded
noMatch()