-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Strict func does not catch mutation #20808
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@bung87 please investigate. |
The below is a smaller reproduction, right? {.experimental: "strictFuncs".}
type
Node = ref object
num: int
kids: seq[Node]
func initKids(node: Node) =
# node.num = 7 # Error: an object reachable from 'node' is potentially mutated
for kid in node.kids:
kid.num = 42 # No error.
proc newNode: Node =
var kid = Node()
result = Node(kids: @[kid])
initKids(result)
echo newNode().kids[0].num It looks like this problem exists in Nim |
reduced example, it's not handled by current implementation. {.experimental: "strictFuncs".}
type
Node = ref object
num: int
kids: seq[Node]
func initKids(node: Node) =
# node.num = 7 # Error: an object reachable from 'node' is potentially mutated
for kid in node.kids:
kid.num = 42 # No error.
var kid = Node()
var a = Node(kids: @[kid])
initKids(a)
|
duno what expected here func initKids2(kids: seq[Node]) =
for kid in kids:
kid.num = 42
let kids = @[kid]
initKids2(kids) |
I believe after transforming |
An error, right? The experimental manual says:
I think the minimal reproduction so far is: {.experimental: "strictFuncs".}
type
Node = ref object
num: int
func mutate(nodes: seq[Node]) =
for node in nodes:
node.num = 42 # No error, despite mutation of an object reachable via non-`var` parameter.
let nodes = @[Node(num: 7)]
mutate(nodes)
echo nodes[0].num Current output:
Expected output:
|
Note that the error does appear when we remove the for loop: {.experimental: "strictFuncs".}
type
Node = ref object
num: int
func mutate(nodes: seq[Node]) =
let node = nodes[0]
node.num = 42 # Error, as expected.
let nodes = @[Node(num: 7)]
mutate(nodes)
echo nodes[0].num Output:
|
But no error when we assign {.experimental: "strictFuncs".}
type
Node = ref object
num: int
func first(nodes: seq[Node]): Node =
nodes[0]
func mutate(nodes: seq[Node]) =
let node = first(nodes)
node.num = 42 # No error, despite mutation of an object reachable via non-`var` parameter.
let nodes = @[Node(num: 7)]
mutate(nodes)
echo nodes[0].num So it's not just due to |
So the analysis works only if the return type is lent T but it doesn't work for iterators. |
In theory it works for all cases that have been shown here. It's just an implementation bug, |
That's what I understood from the spec - thanks for confirming. My understanding is that @planetis-m was just saying that (correct me if I'm wrong):
{.experimental: "strictFuncs".}
type
Node = ref object
num: int
iterator myItems(nodes: seq[Node]): lent Node =
var i = 0
let L = nodes.len
while i < L:
yield nodes[i]
inc i
func mutate(nodes: seq[Node]) =
for node in nodes.myItems:
node.num = 42 # No error, despite mutation of an object reachable via non-`var` parameter.
let nodes = @[Node(num: 7)]
mutate(nodes)
echo nodes[0].num |
In case it's convenient, somebody working on the write tracking might like to see if they can address #20863 at the same time. It's another |
Not release blocking. I also have a better design for strict functions that might make it into version 2.2. |
* closes nim-lang#20808 * atlas: better docs
* closes nim-lang#20808 * atlas: better docs
* closes nim-lang#20808 * atlas: better docs
Uh oh!
There was an error while loading. Please reload this page.
What happened?
Line 9 mutates tree but its not caught by the compiler.
Nim Version
Nim Compiler Version 1.7.3 [Linux: amd64]
Compiled at 2022-11-09
Copyright (c) 2006-2022 by Andreas Rumpf
git hash: 6894a00
active boot switches: -d:release --gc:markAndSweep
Current Standard Output Logs
Expected Standard Output Logs
Possible Solution
No response
Additional Information
No response
The text was updated successfully, but these errors were encountered: