parent
acbe27b082
commit
0426a4d85a
2 changed files with 34 additions and 6 deletions
|
|
@ -48,7 +48,8 @@ proc dec(x: var AbstractTime; diff = 1) {.borrow.}
|
||||||
type
|
type
|
||||||
SubgraphFlag = enum
|
SubgraphFlag = enum
|
||||||
isMutated, # graph might be mutated
|
isMutated, # graph might be mutated
|
||||||
connectsConstParam, # graph is connected to a non-var parameter.
|
isMutatedDirectly, # graph is mutated directly by a non-var parameter.
|
||||||
|
connectsConstParam # graph is connected to a non-var parameter.
|
||||||
|
|
||||||
VarFlag = enum
|
VarFlag = enum
|
||||||
ownsData,
|
ownsData,
|
||||||
|
|
@ -99,12 +100,12 @@ type
|
||||||
config: ConfigRef
|
config: ConfigRef
|
||||||
|
|
||||||
proc mutationAfterConnection(g: MutationInfo): bool {.inline.} =
|
proc mutationAfterConnection(g: MutationInfo): bool {.inline.} =
|
||||||
#echo g.maxMutation, " ", g.minConnection, " ", g.param
|
#echo g.maxMutation.int, " ", g.minConnection.int, " ", g.param
|
||||||
g.maxMutation > g.minConnection
|
g.maxMutation > g.minConnection
|
||||||
|
|
||||||
proc `$`*(config: ConfigRef; g: MutationInfo): string =
|
proc `$`*(config: ConfigRef; g: MutationInfo): string =
|
||||||
result = ""
|
result = ""
|
||||||
if g.flags == {isMutated, connectsConstParam}:
|
if g.flags * {isMutated, connectsConstParam} == {isMutated, connectsConstParam}:
|
||||||
result.add "\nan object reachable from '"
|
result.add "\nan object reachable from '"
|
||||||
result.add g.param.name.s
|
result.add g.param.name.s
|
||||||
result.add "' is potentially mutated"
|
result.add "' is potentially mutated"
|
||||||
|
|
@ -119,7 +120,8 @@ proc `$`*(config: ConfigRef; g: MutationInfo): string =
|
||||||
|
|
||||||
proc hasSideEffect*(c: var Partitions; info: var MutationInfo): bool =
|
proc hasSideEffect*(c: var Partitions; info: var MutationInfo): bool =
|
||||||
for g in mitems c.graphs:
|
for g in mitems c.graphs:
|
||||||
if g.flags == {isMutated, connectsConstParam} and mutationAfterConnection(g):
|
if g.flags * {isMutated, connectsConstParam} == {isMutated, connectsConstParam} and
|
||||||
|
(mutationAfterConnection(g) or isMutatedDirectly in g.flags):
|
||||||
info = g
|
info = g
|
||||||
return true
|
return true
|
||||||
return false
|
return false
|
||||||
|
|
@ -173,11 +175,16 @@ proc potentialMutation(v: var Partitions; s: PSym; info: TLineInfo) =
|
||||||
let id = variableId(v, s)
|
let id = variableId(v, s)
|
||||||
if id >= 0:
|
if id >= 0:
|
||||||
let r = root(v, id)
|
let r = root(v, id)
|
||||||
|
let flags = if s.kind == skParam and isConstParam(s):
|
||||||
|
{isMutated, isMutatedDirectly}
|
||||||
|
else:
|
||||||
|
{isMutated}
|
||||||
|
|
||||||
case v.s[r].con.kind
|
case v.s[r].con.kind
|
||||||
of isEmptyRoot:
|
of isEmptyRoot:
|
||||||
v.s[r].con = Connection(kind: isRootOf, graphIndex: v.graphs.len)
|
v.s[r].con = Connection(kind: isRootOf, graphIndex: v.graphs.len)
|
||||||
v.graphs.add MutationInfo(param: if isConstParam(s): s else: nil, mutatedHere: info,
|
v.graphs.add MutationInfo(param: if isConstParam(s): s else: nil, mutatedHere: info,
|
||||||
connectedVia: unknownLineInfo, flags: {isMutated},
|
connectedVia: unknownLineInfo, flags: flags,
|
||||||
maxMutation: v.abstractTime, minConnection: MaxTime,
|
maxMutation: v.abstractTime, minConnection: MaxTime,
|
||||||
mutations: @[v.abstractTime])
|
mutations: @[v.abstractTime])
|
||||||
of isRootOf:
|
of isRootOf:
|
||||||
|
|
@ -187,7 +194,7 @@ proc potentialMutation(v: var Partitions; s: PSym; info: TLineInfo) =
|
||||||
if v.abstractTime > g.maxMutation:
|
if v.abstractTime > g.maxMutation:
|
||||||
g.mutatedHere = info
|
g.mutatedHere = info
|
||||||
g.maxMutation = v.abstractTime
|
g.maxMutation = v.abstractTime
|
||||||
g.flags.incl isMutated
|
g.flags.incl flags
|
||||||
g.mutations.add v.abstractTime
|
g.mutations.add v.abstractTime
|
||||||
else:
|
else:
|
||||||
assert false, "cannot happen"
|
assert false, "cannot happen"
|
||||||
|
|
|
||||||
21
tests/effects/tfuncs_cannot_mutate_simple.nim
Normal file
21
tests/effects/tfuncs_cannot_mutate_simple.nim
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
discard """
|
||||||
|
errormsg: "'edit' can have side effects"
|
||||||
|
nimout: '''an object reachable from 'x' is potentially mutated
|
||||||
|
tfuncs_cannot_mutate_simple.nim(17, 4) the mutation is here'''
|
||||||
|
line: 16
|
||||||
|
"""
|
||||||
|
|
||||||
|
{.experimental: "strictFuncs".}
|
||||||
|
|
||||||
|
# bug #15508
|
||||||
|
|
||||||
|
type
|
||||||
|
MyType = ref object
|
||||||
|
data: string
|
||||||
|
|
||||||
|
func edit(x: MyType) =
|
||||||
|
x.data = "hello"
|
||||||
|
|
||||||
|
let x = MyType()
|
||||||
|
x.edit()
|
||||||
|
echo x.data
|
||||||
Loading…
Add table
Add a link
Reference in a new issue