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

@ -1,9 +1,6 @@
discard """
errormsg: "'mutate' can have side effects"
nimout: '''an object reachable from 'n' is potentially mutated
tfuncs_cannot_mutate.nim(39, 15) the mutation is here
tfuncs_cannot_mutate.nim(37, 7) is the statement that connected the mutation to the parameter
'''
errormsg: "cannot mutate location select(x, z).data within a strict func"
line: 35
"""
{.experimental: "strictFuncs".}
@ -25,8 +22,7 @@ func len(n: Node): int =
it = it.ri
func doNotDistract(n: Node) =
var m = Node()
m.data = "abc"
var m = Node(data: "abc")
func select(a, b: Node): Node = b

View file

@ -1,9 +1,6 @@
discard """
errormsg: "'copy' can have side effects"
nimout: '''an object reachable from 'y' is potentially mutated
tfuncs_cannot_mutate2.nim(15, 7) the mutation is here
tfuncs_cannot_mutate2.nim(13, 10) is the statement that connected the mutation to the parameter
'''
errormsg: "cannot mutate location x[0].a within a strict func"
line: 12
"""
{.experimental: "strictFuncs".}

View file

@ -1,7 +1,6 @@
discard """
errormsg: "'edit' can have side effects"
nimout: '''an object reachable from 'x' is potentially mutated
tfuncs_cannot_mutate_simple.nim(16, 4) the mutation is here'''
errormsg: '''cannot mutate location x.data within a strict func'''
line: 15
"""
{.experimental: "strictFuncs".}

View file

@ -0,0 +1,65 @@
discard """
action: compile
"""
{.experimental: "strictFuncs".}
func sortedFake1[T](a: openArray[T]): seq[T] =
for i in 0 .. a.high: result.add a[i]
func sortedFake2[T](a: openArray[T]): seq[T] =
result = newSeq[T](a.len)
for i in 0 .. a.high: result[i] = a[i]
type Foo1 = object
type Foo2 = ref object
block:
let a1 = sortedFake1([Foo1()]) # ok
let a2 = sortedFake1([Foo2()]) # ok
block:
let a1 = sortedFake2([Foo1()]) # ok
let a2 = sortedFake2([Foo2()]) # error: Error: 'sortedFake2' can have side effects
import std/sequtils
type Foob = ref object
x: int
let a1 = zip(@[1,2], @[1,2]) # ok
let a2 = zip(@[Foob(x: 1)], @[Foob(x: 2)]) # error in 1.6.0 RC2, but not 1.4.x
# bug #20863
type
Fooc = ref object
func twice(foo: Fooc) =
var a = newSeq[Fooc](2)
a[0] = foo # No error.
a[1] = foo # Error: 'twice' can have side effects.
let foo = Fooc()
twice(foo)
# bug #17387
import json
func parseColumn(columnNode: JsonNode) =
let columnName = columnNode["name"].str
parseColumn(%*{"a": "b"})
type
MyTable = object
data: seq[int]
JsonNode3 = ref object
fields: MyTable
proc `[]`(t: var MyTable, key: string): var int =
result = t.data[0]
proc `[]`(x: JsonNode3, key: string): int =
result = x.fields[key]
func parseColumn(columnNode: JsonNode3) =
var columnName = columnNode["test"]
parseColumn(JsonNode3())