Nil type check implementation (#15287)

* Nil checking
* Enable current older not nil checking again, run new checking only under flag, skip our test
* Enable tests, work on try/except and bugs, fix notnil tests

* Enable strictNotNil tests (currently with lowercase category) and add some expected output
* Work on try/except/finally: still some things unclear and a lot of code can raise out of try
* Fix the notnil build by going back to the old version of a test which I shouldn't have changed

* Fix test : use action compile
* Work on mutation and aliasing: not finished
* Render var parititions graph, try to understand it, fix a nilcheck if bug
* Rebase, progress on working with partitions
* Improve time logic
* Fix some bugs, use graph indices instead of symbol in nil map
* Fix bugs, test simpler ident aliasing for now, support two mutation levels
* Support ContentMutation and ReAssignment: for now just detect possible re assignment for var parameters of calls
* Enable several simple passing tests
* Cleanup a bit, fix condition/branch infix-related bug
* Remove some files, address some comments by Araq
* Use internalError and no quit for now
* Separate tests with expected warnings and with expected ok, fix a bug with if with a single branch related to copyMap
* Fix new data structures, bugs: make tests pass, disable some for now
* Work on fixing errors with non-sym nodes, aliasing: tests fail
* Work on alias support: simple set-based logic, todo more tests and ref sets?
* Use ref sets: TODO can we think of handle seq-s similar to varpartitions' Araq ones
* Handle defers in one place, stop raising in reverse to make an async test compile with strictNotNil, add a commented out test
* Dot expressions: call/reassignment. Other refactorings and distinct, SeqOfDistinct support. Checkout an older varpartitions
* Work on field tracking
* Backup : trying to fix bugs when running some stdlib stuff for running an async test
* Start a section about strict not nil checking in experimental manual
* Fix experimental strict not nil manual section and move it to another file based on Araq feedback
* Fix unstructured flow and double warning problems, fix manual, cleanup
* Fix if/elif/else : take in account structure according to Araq feedback
* Refactor a bit
* Work on bracket expr support, re-enable tests, clarify in manual/tests/implementation static index support for now
* Work on compiling stdlib and compiler with strictNotNil
* Small fixes to the manual for strictNotNil
* Fix idgen for strict check nil rebase
* Enable some simple tests, remove old stuff, comment out code/print
* Copy the original varpartitions source instead of my changes
* Remove some files
This commit is contained in:
Alexander Ivanov 2020-12-29 11:31:11 +02:00 • committed by GitHub
commit 672dc5cd87
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 2215 additions and 14 deletions

View file

@ -917,6 +917,7 @@ proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType =
# check every except the last is an object:
for i in isCall..<n.len-1:
let ni = n[i]
# echo "semAnyRef ", "n: ", n, "i: ", i, "ni: ", ni
if ni.kind == nkNilLit:
isNilable = true
else:
@ -933,7 +934,7 @@ proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType =
addSonSkipIntLit(result, t, c.idgen)
if tfPartial in result.flags:
if result.lastSon.kind == tyObject: incl(result.lastSon.flags, tfPartial)
#if not isNilable: result.flags.incl tfNotNil
# if not isNilable: result.flags.incl tfNotNil
case wrapperKind
of tyOwned:
if optOwnedRefs in c.config.globalOptions:
@ -1563,6 +1564,8 @@ proc semTypeClass(c: PContext, n: PNode, prev: PType): PType =
if modifier != tyNone:
dummyName = param[0]
dummyType = c.makeTypeWithModifier(modifier, candidateTypeSlot)
# if modifier == tyRef:
# dummyType.flags.incl tfNotNil
if modifier == tyTypeDesc:
dummyType.flags.incl tfConceptMatchedTypeSym
dummyType.flags.incl tfCheckedForDestructor
@ -1747,9 +1750,11 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
if n[2].kind != nkNilLit:
localError(c.config, n.info,
"Invalid syntax. When used with a type, 'not' can be followed only by 'nil'")
if notnil notin c.features:
if notnil notin c.features and strictNotNil notin c.features:
localError(c.config, n.info,
"enable the 'not nil' annotation with {.experimental: \"notnil\".}")
"enable the 'not nil' annotation with {.experimental: \"notnil\".} or " &
" the `strict not nil` annotation with {.experimental: \"strictNotNil\".} " &
" the \"notnil\" one is going to be deprecated, so please use \"strictNotNil\"")
let resolvedType = result.skipTypes({tyGenericInst, tyAlias, tySink, tyOwned})
case resolvedType.kind
of tyGenericParam, tyTypeDesc, tyFromExpr: