Skip to content

Commit 0426a4d

Browse files
authored
fixes #15508 (#15509)
1 parent acbe27b commit 0426a4d

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

compiler/varpartitions.nim

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ proc dec(x: var AbstractTime; diff = 1) {.borrow.}
4848
type
4949
SubgraphFlag = enum
5050
isMutated, # graph might be mutated
51-
connectsConstParam, # graph is connected to a non-var parameter.
51+
isMutatedDirectly, # graph is mutated directly by a non-var parameter.
52+
connectsConstParam # graph is connected to a non-var parameter.
5253

5354
VarFlag = enum
5455
ownsData,
@@ -99,12 +100,12 @@ type
99100
config: ConfigRef
100101

101102
proc mutationAfterConnection(g: MutationInfo): bool {.inline.} =
102-
#echo g.maxMutation, " ", g.minConnection, " ", g.param
103+
#echo g.maxMutation.int, " ", g.minConnection.int, " ", g.param
103104
g.maxMutation > g.minConnection
104105

105106
proc `$`*(config: ConfigRef; g: MutationInfo): string =
106107
result = ""
107-
if g.flags == {isMutated, connectsConstParam}:
108+
if g.flags * {isMutated, connectsConstParam} == {isMutated, connectsConstParam}:
108109
result.add "\nan object reachable from '"
109110
result.add g.param.name.s
110111
result.add "' is potentially mutated"
@@ -119,7 +120,8 @@ proc `$`*(config: ConfigRef; g: MutationInfo): string =
119120

120121
proc hasSideEffect*(c: var Partitions; info: var MutationInfo): bool =
121122
for g in mitems c.graphs:
122-
if g.flags == {isMutated, connectsConstParam} and mutationAfterConnection(g):
123+
if g.flags * {isMutated, connectsConstParam} == {isMutated, connectsConstParam} and
124+
(mutationAfterConnection(g) or isMutatedDirectly in g.flags):
123125
info = g
124126
return true
125127
return false
@@ -173,11 +175,16 @@ proc potentialMutation(v: var Partitions; s: PSym; info: TLineInfo) =
173175
let id = variableId(v, s)
174176
if id >= 0:
175177
let r = root(v, id)
178+
let flags = if s.kind == skParam and isConstParam(s):
179+
{isMutated, isMutatedDirectly}
180+
else:
181+
{isMutated}
182+
176183
case v.s[r].con.kind
177184
of isEmptyRoot:
178185
v.s[r].con = Connection(kind: isRootOf, graphIndex: v.graphs.len)
179186
v.graphs.add MutationInfo(param: if isConstParam(s): s else: nil, mutatedHere: info,
180-
connectedVia: unknownLineInfo, flags: {isMutated},
187+
connectedVia: unknownLineInfo, flags: flags,
181188
maxMutation: v.abstractTime, minConnection: MaxTime,
182189
mutations: @[v.abstractTime])
183190
of isRootOf:
@@ -187,7 +194,7 @@ proc potentialMutation(v: var Partitions; s: PSym; info: TLineInfo) =
187194
if v.abstractTime > g.maxMutation:
188195
g.mutatedHere = info
189196
g.maxMutation = v.abstractTime
190-
g.flags.incl isMutated
197+
g.flags.incl flags
191198
g.mutations.add v.abstractTime
192199
else:
193200
assert false, "cannot happen"
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
discard """
2+
errormsg: "'edit' can have side effects"
3+
nimout: '''an object reachable from 'x' is potentially mutated
4+
tfuncs_cannot_mutate_simple.nim(17, 4) the mutation is here'''
5+
line: 16
6+
"""
7+
8+
{.experimental: "strictFuncs".}
9+
10+
# bug #15508
11+
12+
type
13+
MyType = ref object
14+
data: string
15+
16+
func edit(x: MyType) =
17+
x.data = "hello"
18+
19+
let x = MyType()
20+
x.edit()
21+
echo x.data

0 commit comments

Comments
 (0)