fix #14421 items uses lent T (#14447)

* fix #14421 items uses lent T for seq + openArray
* add -d:nimWorkaround14447
* fix test
This commit is contained in:
Timothee Cour 2020-05-29 08:10:59 -07:00 • committed by GitHub
commit 63d1a0289e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 40 additions and 13 deletions

View file

@ -118,3 +118,4 @@ proc initDefines*(symbols: StringTableRef) =
defineSymbol("nimHasInvariant") defineSymbol("nimHasInvariant")
defineSymbol("nimHasStacktraceMsgs") defineSymbol("nimHasStacktraceMsgs")
defineSymbol("nimDoesntTrackDefects") defineSymbol("nimDoesntTrackDefects")
defineSymbol("nimHasLentIterators")

View file

@ -291,7 +291,8 @@ proc markAsClosure(g: ModuleGraph; owner: PSym; n: PNode) =
if illegalCapture(s): if illegalCapture(s):
localError(g.config, n.info, localError(g.config, n.info,
("'$1' is of type <$2> which cannot be captured as it would violate memory" & ("'$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}: elif owner.typ.callConv notin {ccClosure, ccDefault}:
localError(g.config, n.info, "illegal capture '$1' because '$2' has the calling convention: <$3>" % 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]]) [s.name.s, owner.name.s, CallingConvToStr[owner.typ.callConv]])

View file

@ -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`. ## Iterates over each item of `a`.
var i = 0 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] yield a[i]
inc(i) inc(i)
@ -179,7 +204,7 @@ iterator mpairs*(a: var cstring): tuple[key: int, val: var char] {.inline.} =
yield (i, a[i]) yield (i, a[i])
inc(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`. ## Iterates over each item of `a`.
var i = 0 var i = 0
let L = len(a) let L = len(a)

View file

@ -43,7 +43,7 @@ pkg1 "elvis"
pkg1 "fidget", true, "nim c -d:release -r tests/runNative.nim" pkg1 "fidget", true, "nim c -d:release -r tests/runNative.nim"
pkg1 "fragments", false, "nim c -r fragments/dsl.nim" pkg1 "fragments", false, "nim c -r fragments/dsl.nim"
pkg1 "gara" 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 "gittyup", true, "nimble test", "https://github.com/disruptek/gittyup"
pkg1 "glob" pkg1 "glob"
pkg1 "gnuplot" pkg1 "gnuplot"
@ -134,4 +134,4 @@ pkg2 "websocket", false, "nim c websocket.nim"
pkg2 "with" pkg2 "with"
pkg2 "ws" pkg2 "ws"
pkg2 "yaml" pkg2 "yaml"
pkg2 "zero_functional", false, "nim c -r test.nim" pkg2 "zero_functional", false, "nim c -r -d:nimWorkaround14447 test.nim"

View file

@ -1,7 +1,7 @@
discard """ discard """
cmd: '''nim c -d:nimAllocStats --newruntime $file''' cmd: '''nim c -d:nimAllocStats --newruntime $file'''
output: '''0 output: '''0
(allocCount: 6, deallocCount: 6)''' (allocCount: 5, deallocCount: 5)'''
""" """
import system / ansi_c import system / ansi_c

View file

@ -10,7 +10,7 @@ a: @[4, 2, 3]
0 0
30 30
true true
(allocCount: 36, deallocCount: 36)''' (allocCount: 27, deallocCount: 27)'''
""" """
include system / ansi_c include system / ansi_c

View file

@ -7,7 +7,7 @@ axc
... ...
destroying GenericObj[T] GenericObj[system.int] destroying GenericObj[T] GenericObj[system.int]
test test
(allocCount: 17, deallocCount: 15) (allocCount: 13, deallocCount: 11)
3''' 3'''
""" """

View file

@ -1,7 +1,7 @@
discard """ discard """
cmd: '''nim c -d:nimAllocStats --newruntime $file''' cmd: '''nim c -d:nimAllocStats --newruntime $file'''
output: '''31665 output: '''31665
(allocCount: 33335, deallocCount: 33335)''' (allocCount: 33334, deallocCount: 33334)'''
""" """
# bug #11053 # bug #11053

View file

@ -5,7 +5,7 @@ discard """
hello hello
hello hello
hello hello
(allocCount: 4, deallocCount: 4)''' (allocCount: 3, deallocCount: 3)'''
""" """
import system / ansi_c import system / ansi_c

View file

@ -2,7 +2,7 @@ discard """
valgrind: true valgrind: true
cmd: '''nim c -d:nimAllocStats --newruntime $file''' cmd: '''nim c -d:nimAllocStats --newruntime $file'''
output: '''OK 3 output: '''OK 3
(allocCount: 8, deallocCount: 5)''' (allocCount: 7, deallocCount: 4)'''
""" """
import strutils, math import strutils, math

View file

@ -2,7 +2,7 @@ discard """
cmd: '''nim c -d:nimAllocStats --newruntime $file''' cmd: '''nim c -d:nimAllocStats --newruntime $file'''
output: '''button output: '''button
clicked! clicked!
(allocCount: 7, deallocCount: 7)''' (allocCount: 6, deallocCount: 6)'''
""" """
import system / ansi_c import system / ansi_c