alternative, much simpler algorithm for strict func checking (#21066)

* alternative, much simpler algorithm for strict func checking

* forgot to git add new compiler module

* new spec is incredibly simple to describe

* fixes bigints regression

* typos

* closes #16305; closes #17387; closes #20863
This commit is contained in:
Andreas Rumpf 2022-12-11 16:58:50 +01:00 • committed by GitHub
commit 3812d91390
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 187 additions and 78 deletions

View file

@ -0,0 +1,55 @@
#
#
# The Nim Compiler
# (c) Copyright 2022 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## New "strict funcs" checking. Much simpler and hopefully easier to teach than
## the old but more advanced algorithm that can/could be found in `varpartitions.nim`.
import ast, typeallowed, renderer
from aliasanalysis import PathKinds0, PathKinds1
from trees import getMagic
proc isDangerousLocation*(n: PNode; owner: PSym): bool =
var n = n
var hasDeref = false
while true:
case n.kind
of nkDerefExpr, nkHiddenDeref:
if n[0].typ.kind != tyVar:
hasDeref = true
n = n[0]
of PathKinds0 - {nkDerefExpr, nkHiddenDeref}:
n = n[0]
of PathKinds1:
n = n[1]
of nkCallKinds:
if n.len > 1:
if (n.typ != nil and classifyViewType(n.typ) != noView) or getMagic(n) == mSlice:
# borrow from first parameter:
n = n[1]
else:
break
else:
break
else:
break
if n.kind == nkSym:
# dangerous if contains a pointer deref or if it doesn't belong to us:
result = hasDeref or n.sym.owner != owner
when false:
# store to something that belongs to a `var` parameter is fine:
let s = n.sym
if s.kind == skParam:
# dangerous unless a `var T` parameter:
result = s.typ.kind != tyVar
else:
# dangerous if contains a pointer deref or if it doesn't belong to us:
result = hasDeref or s.owner != owner
else:
# dangerous if it contains a pointer deref
result = hasDeref