Skip to content

Commit

Permalink
fix #14421 items uses lent T (#14447)
Browse files Browse the repository at this point in the history
* fix #14421 items uses lent T for seq + openArray
* add -d:nimWorkaround14447
* fix test
  • Loading branch information
timotheecour authored May 29, 2020
1 parent e646c16 commit 63d1a02
Show file tree
Hide file tree
Showing 11 changed files with 40 additions and 13 deletions.
1 change: 1 addition & 0 deletions compiler/condsyms.nim
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,4 @@ proc initDefines*(symbols: StringTableRef) =
defineSymbol("nimHasInvariant")
defineSymbol("nimHasStacktraceMsgs")
defineSymbol("nimDoesntTrackDefects")
defineSymbol("nimHasLentIterators")
3 changes: 2 additions & 1 deletion compiler/lambdalifting.nim
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,8 @@ proc markAsClosure(g: ModuleGraph; owner: PSym; n: PNode) =
if illegalCapture(s):
localError(g.config, n.info,
("'$1' is of type <$2> which cannot be captured as it would violate memory" &
" safety, declared here: $3") % [s.name.s, typeToString(s.typ), g.config$s.info])
" safety, declared here: $3; using '-d:nimWorkaround14447' helps in some cases") %
[s.name.s, typeToString(s.typ), g.config$s.info])
elif owner.typ.callConv notin {ccClosure, ccDefault}:
localError(g.config, n.info, "illegal capture '$1' because '$2' has the calling convention: <$3>" %
[s.name.s, owner.name.s, CallingConvToStr[owner.typ.callConv]])
Expand Down
31 changes: 28 additions & 3 deletions lib/system/iterators.nim
Original file line number Diff line number Diff line change
@@ -1,7 +1,32 @@
iterator items*[T](a: openArray[T]): T {.inline.} =
when defined(nimHasLentIterators) and not defined(nimWorkaround14447):
template lent2(T): untyped =
# xxx this should actually depend on T.sizeof >= thresLentSizeof
# with for example `thresLentSizeof ~= int.sizeof`:
# it may be faster to return by value for small sizes compared to
# forcing a deref; this could be adjusted using profiling.
# However, `simply using `when T.sizeof >= thresLentSizeof: lent T else: T`
# does not work, for a few reasons (eg importc types would cause CT error
# and we can't filter them out without compiles() or some magic.
lent T
else:
template lent2(T): untyped = T

iterator items*[T: not char](a: openArray[T]): lent2 T {.inline.} =
## Iterates over each item of `a`.
var i = 0
while i < len(a):
let n = len(a)
while i < n:
yield a[i]
inc(i)

iterator items*[T: char](a: openArray[T]): T {.inline.} =
## Iterates over each item of `a`.
# a VM bug currently prevents taking address of openArray[char]
# elements converted from a string (would fail in `tests/misc/thallo.nim`)
# in any case there's no performance advantage of returning char by address.
var i = 0
let n = len(a)
while i < n:
yield a[i]
inc(i)

Expand Down Expand Up @@ -179,7 +204,7 @@ iterator mpairs*(a: var cstring): tuple[key: int, val: var char] {.inline.} =
yield (i, a[i])
inc(i)

iterator items*[T](a: seq[T]): T {.inline.} =
iterator items*[T](a: seq[T]): lent2 T {.inline.} =
## Iterates over each item of `a`.
var i = 0
let L = len(a)
Expand Down
4 changes: 2 additions & 2 deletions testament/important_packages.nim
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pkg1 "elvis"
pkg1 "fidget", true, "nim c -d:release -r tests/runNative.nim"
pkg1 "fragments", false, "nim c -r fragments/dsl.nim"
pkg1 "gara"
pkg1 "ggplotnim", true, "nim c -d:noCairo -r tests/tests.nim"
pkg1 "ggplotnim", true, "nim c -d:noCairo -r -d:nimWorkaround14447 tests/tests.nim"
# pkg1 "gittyup", true, "nimble test", "https://github.com/disruptek/gittyup"
pkg1 "glob"
pkg1 "gnuplot"
Expand Down Expand Up @@ -134,4 +134,4 @@ pkg2 "websocket", false, "nim c websocket.nim"
pkg2 "with"
pkg2 "ws"
pkg2 "yaml"
pkg2 "zero_functional", false, "nim c -r test.nim"
pkg2 "zero_functional", false, "nim c -r -d:nimWorkaround14447 test.nim"
2 changes: 1 addition & 1 deletion tests/destructor/tbintree2.nim
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
discard """
cmd: '''nim c -d:nimAllocStats --newruntime $file'''
output: '''0
(allocCount: 6, deallocCount: 6)'''
(allocCount: 5, deallocCount: 5)'''
"""

import system / ansi_c
Expand Down
2 changes: 1 addition & 1 deletion tests/destructor/tgcdestructors.nim
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ a: @[4, 2, 3]
0
30
true
(allocCount: 36, deallocCount: 36)'''
(allocCount: 27, deallocCount: 27)'''
"""

include system / ansi_c
Expand Down
2 changes: 1 addition & 1 deletion tests/destructor/tnewruntime_misc.nim
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ axc
...
destroying GenericObj[T] GenericObj[system.int]
test
(allocCount: 17, deallocCount: 15)
(allocCount: 13, deallocCount: 11)
3'''
"""

Expand Down
2 changes: 1 addition & 1 deletion tests/destructor/towned_binary_tree.nim
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
discard """
cmd: '''nim c -d:nimAllocStats --newruntime $file'''
output: '''31665
(allocCount: 33335, deallocCount: 33335)'''
(allocCount: 33334, deallocCount: 33334)'''
"""

# bug #11053
Expand Down
2 changes: 1 addition & 1 deletion tests/destructor/tsimpleclosure.nim
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ discard """
hello
hello
hello
(allocCount: 4, deallocCount: 4)'''
(allocCount: 3, deallocCount: 3)'''
"""

import system / ansi_c
Expand Down
2 changes: 1 addition & 1 deletion tests/destructor/tv2_raise.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ discard """
valgrind: true
cmd: '''nim c -d:nimAllocStats --newruntime $file'''
output: '''OK 3
(allocCount: 8, deallocCount: 5)'''
(allocCount: 7, deallocCount: 4)'''
"""

import strutils, math
Expand Down
2 changes: 1 addition & 1 deletion tests/destructor/twidgets_unown.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ discard """
cmd: '''nim c -d:nimAllocStats --newruntime $file'''
output: '''button
clicked!
(allocCount: 7, deallocCount: 7)'''
(allocCount: 6, deallocCount: 6)'''
"""

import system / ansi_c
Expand Down

0 comments on commit 63d1a02

Please sign in to comment.