diff options
Diffstat (limited to 'tests/tuples')
24 files changed, 526 insertions, 195 deletions
diff --git a/tests/tuples/mnimsconstunpack.nim b/tests/tuples/mnimsconstunpack.nim new file mode 100644 index 000000000..65fafc12f --- /dev/null +++ b/tests/tuples/mnimsconstunpack.nim @@ -0,0 +1,4 @@ +proc foo(): tuple[a, b: string] = + result = ("a", "b") + +const (a, b*) = foo() diff --git a/tests/tuples/t12892.nim b/tests/tuples/t12892.nim new file mode 100644 index 000000000..d69e99c7f --- /dev/null +++ b/tests/tuples/t12892.nim @@ -0,0 +1,8 @@ +discard """ + disabled: i386 +""" + +template works[T](): auto = T.high - 1 +template breaks[T](): auto = (T.high - 1, true) +doAssert $works[uint]() == "18446744073709551614" +doAssert $breaks[uint]() == "(18446744073709551614, true)" diff --git a/tests/tuples/t18125_1.nim b/tests/tuples/t18125_1.nim new file mode 100644 index 000000000..74fdfe8f5 --- /dev/null +++ b/tests/tuples/t18125_1.nim @@ -0,0 +1,14 @@ +# issue #18125 solved with type inference + +type + Parent = ref object of RootObj + + Child = ref object of Parent + c: char + +func foo(c: char): (Parent, int) = + # Works if you use (Parent(Child(c: c)), 0) + (Child(c: c), 0) + +let x = foo('x')[0] +doAssert Child(x).c == 'x' diff --git a/tests/tuples/t18125_2.nim b/tests/tuples/t18125_2.nim new file mode 100644 index 000000000..fe0a4a8bb --- /dev/null +++ b/tests/tuples/t18125_2.nim @@ -0,0 +1,20 @@ +discard """ + errormsg: "type mismatch: got <(Child, int)> but expected '(Parent, int)'" + line: 17 +""" + +# issue #18125 solved with correct type relation + +type + Parent = ref object of RootObj + + Child = ref object of Parent + c: char + +func foo(c: char): (Parent, int) = + # Works if you use (Parent(Child(c: c)), 0) + let x = (Child(c: c), 0) + x + +let x = foo('x')[0] +doAssert Child(x).c == 'x' diff --git a/tests/tuples/t7012.nim b/tests/tuples/t7012.nim new file mode 100644 index 000000000..32d441ddd --- /dev/null +++ b/tests/tuples/t7012.nim @@ -0,0 +1,7 @@ +discard """ + errormsg: "illegal recursion in type 'Node'" +""" + +type Node[T] = tuple + next: ref Node[T] +var n: Node[int] \ No newline at end of file diff --git a/tests/tuples/t9177.nim b/tests/tuples/t9177.nim new file mode 100644 index 000000000..e6dd0cb1d --- /dev/null +++ b/tests/tuples/t9177.nim @@ -0,0 +1,15 @@ +discard """ + action: run +""" + +block: + var x = (a: 5, b: 1) + x = (3 * x.a + 2 * x.b, x.a + x.b) + doAssert x.a == 17 + doAssert x.b == 6 +block: + # Transformation of a tuple constructor with named arguments + var x = (a: 5, b: 1) + x = (a: 3 * x.a + 2 * x.b, b: x.a + x.b) + doAssert x.a == 17 + doAssert x.b == 6 diff --git a/tests/tuples/tanontuples.nim b/tests/tuples/tanontuples.nim deleted file mode 100644 index 49803e5ac..000000000 --- a/tests/tuples/tanontuples.nim +++ /dev/null @@ -1,14 +0,0 @@ -discard """ - output: '''61, 125''' -""" - -proc `^` (a, b: int): int = - result = 1 - for i in 1..b: result = result * a - -var m = (0, 5) -var n = (56, 3) - -m = (n[0] + m[1], m[1] ^ n[1]) - -echo m[0], ", ", m[1] diff --git a/tests/tuples/tconver_tuple.nim b/tests/tuples/tconver_tuple.nim deleted file mode 100644 index 306da77fe..000000000 --- a/tests/tuples/tconver_tuple.nim +++ /dev/null @@ -1,23 +0,0 @@ -# Bug 4479 - -type - MyTuple = tuple - num: int - strings: seq[string] - ints: seq[int] - -var foo = MyTuple(( - num: 7, - strings: @[], - ints: @[], -)) - -var bar = ( - num: 7, - strings: @[], - ints: @[], -).MyTuple - -var fooUnnamed = MyTuple((7, @[], @[])) -var n = 7 -var fooSym = MyTuple((num: n, strings: @[], ints: @[])) diff --git a/tests/tuples/tdifferent_instantiations.nim b/tests/tuples/tdifferent_instantiations.nim deleted file mode 100644 index 93b1777b5..000000000 --- a/tests/tuples/tdifferent_instantiations.nim +++ /dev/null @@ -1,9 +0,0 @@ -# bug #1910 -import tables - -var p: OrderedTable[tuple[a:int], int] -var q: OrderedTable[tuple[x:int], int] -for key in p.keys: - echo key.a -for key in q.keys: - echo key.x diff --git a/tests/tuples/tfortupleunpack.nim b/tests/tuples/tfortupleunpack.nim new file mode 100644 index 000000000..e222a1ae6 --- /dev/null +++ b/tests/tuples/tfortupleunpack.nim @@ -0,0 +1,52 @@ +discard """ +output: ''' +123 +113283 +0 +123 +1 +113283 +@[(88, 99, 11), (88, 99, 11)] +@[(7, 6, -28), (7, 6, -28)] +12 +110100 +''' +""" + +let t1 = (1, 2, 3) +let t2 = (11, 32, 83) +let s = @[t1, t2] + +for (a, b, c) in s: + echo a, b, c + +for i, (a, b, c) in s: + echo i + echo a, b, c + +var x = @[(1,2,3), (4,5,6)] + +for (a, b, c) in x.mitems: + a = 88 + b = 99 + c = 11 +echo x + +for i, (a, b, c) in x.mpairs: + a = 7 + b = 6 + c = -28 +echo x + +proc test[n]() = + for (a,b) in @[(1,2)]: + echo a,b +test[string]() + +iterator tuples: (int, (int, int)) = yield (1,(10, 100)) + +template t11164 = + for i, (a, b) in tuples(): + echo i, a , b + +t11164() diff --git a/tests/tuples/tgeneric_tuple.nim b/tests/tuples/tgeneric_tuple.nim deleted file mode 100644 index 32f081596..000000000 --- a/tests/tuples/tgeneric_tuple.nim +++ /dev/null @@ -1,9 +0,0 @@ -# bug #2121 - -type - Item[K,V] = tuple - key: K - value: V - -var q = newseq[Item[int,int]](0) -let (x,y) = q[0] diff --git a/tests/tuples/tgeneric_tuple2.nim b/tests/tuples/tgeneric_tuple2.nim deleted file mode 100644 index c0c292388..000000000 --- a/tests/tuples/tgeneric_tuple2.nim +++ /dev/null @@ -1,17 +0,0 @@ - -# bug #2369 - -type HashedElem[T] = tuple[num: int, storedVal: ref T] - -proc append[T](tab: var seq[HashedElem[T]], n: int, val: ref T) = - #tab.add((num: n, storedVal: val)) - var he: HashedElem[T] = (num: n, storedVal: val) - #tab.add(he) - -var g: seq[HashedElem[int]] = @[] - -proc foo() = - var x: ref int - new(x) - x[] = 77 - g.append(44, x) diff --git a/tests/tuples/tinferred_generic_const.nim b/tests/tuples/tinferred_generic_const.nim new file mode 100644 index 000000000..5ab730c38 --- /dev/null +++ b/tests/tuples/tinferred_generic_const.nim @@ -0,0 +1,14 @@ +discard """ + action: run +""" +block: + proc something(a: string or int or float) = + const (c, d) = (default a.type, default a.type) + +block: + proc something(a: string or int) = + const c = default a.type + +block: + proc something(a: string or int) = + const (c, d, e) = (default a.type, default a.type, default a.type) diff --git a/tests/tuples/tnimsconstunpack.nim b/tests/tuples/tnimsconstunpack.nim new file mode 100644 index 000000000..7860fc0a4 --- /dev/null +++ b/tests/tuples/tnimsconstunpack.nim @@ -0,0 +1,8 @@ +discard """ + action: compile + cmd: "nim e $file" +""" + +import mnimsconstunpack + +doAssert b == "b" diff --git a/tests/tuples/ttuples_issues.nim b/tests/tuples/ttuples_issues.nim new file mode 100644 index 000000000..70defdfce --- /dev/null +++ b/tests/tuples/ttuples_issues.nim @@ -0,0 +1,133 @@ +discard """ + targets: "c cpp js" +""" + +# targets include `cpp` because in the past, there were several cpp-specific bugs with tuples. + +import std/tables + +template main() = + block: # bug #4479 + type + MyTuple = tuple + num: int + strings: seq[string] + ints: seq[int] + + var foo = MyTuple(( + num: 7, + strings: @[], + ints: @[], + )) + + var bar = MyTuple ( + num: 7, + strings: @[], + ints: @[], + ) + + var fooUnnamed = MyTuple((7, @[], @[])) + var n = 7 + var fooSym = MyTuple((num: n, strings: @[], ints: @[])) + + block: # bug #1910 + var p = newOrderedTable[tuple[a:int], int]() + var q = newOrderedTable[tuple[x:int], int]() + for key in p.keys: + echo key.a + for key in q.keys: + echo key.x + + block: # bug #2121 + type + Item[K,V] = tuple + key: K + value: V + + var q = newseq[Item[int,int]](1) + let (x,y) = q[0] + + block: # bug #2369 + type HashedElem[T] = tuple[num: int, storedVal: ref T] + + proc append[T](tab: var seq[HashedElem[T]], n: int, val: ref T) = + #tab.add((num: n, storedVal: val)) + var he: HashedElem[T] = (num: n, storedVal: val) + #tab.add(he) + + var g: seq[HashedElem[int]] = @[] + + proc foo() = + var x: ref int + new(x) + x[] = 77 + g.append(44, x) + + block: # bug #1986 + proc test(): int64 = + return 0xdeadbeef.int64 + + const items = [ + (var1: test(), var2: 100'u32), + (var1: test(), var2: 192'u32) + ] + + block: # bug #14911 + doAssert $(a: 1) == "(a: 1)" # works + doAssert $(`a`: 1) == "(a: 1)" # works + doAssert $(`a`: 1, `b`: 2) == "(a: 1, b: 2)" # was: Error: named expression expected + + block: # bug #16822 + var scores: seq[(set[char], int)] = @{{'/'} : 10} + + var x1: set[char] + for item in items(scores): + x1 = item[0] + + doAssert x1 == {'/'} + + var x2: set[char] + for (chars, value) in items(scores): + x2 = chars + + doAssert x2 == {'/'} + + block: # bug #14574 + proc fn(): auto = + let a = @[("foo", (12, 13))] + for (k,v) in a: + return (k,v) + doAssert fn() == ("foo", (12, 13)) + + block: # bug #14574 + iterator fn[T](a:T): lent T = yield a + let a = (10, (11,)) + proc bar(): auto = + for (x,y) in fn(a): + return (x,y) + doAssert bar() == (10, (11,)) + + block: # bug #16331 + type T1 = tuple[a, b: int] + + proc p(b: bool): T1 = + var x: T1 = (10, 20) + x = if b: (x.b, x.a) else: (-x.b, -x.a) + x + + doAssert p(false) == (-20, -10) + doAssert p(true) == (20, 10) + + +proc mainProc() = + # other tests should be in `main` + block: + type A = tuple[x: int, y: int] + doAssert (x: 1, y: 2).A == A (x: 1, y: 2) # MCS => can't use a template + +static: + main() + mainProc() + +main() +mainProc() diff --git a/tests/tuples/ttuples_various.nim b/tests/tuples/ttuples_various.nim new file mode 100644 index 000000000..e392731d2 --- /dev/null +++ b/tests/tuples/ttuples_various.nim @@ -0,0 +1,211 @@ +discard """ +output: ''' +it's nil +@[1, 2, 3] +''' +""" + +import macros + + +block anontuples: + proc `^` (a, b: int): int = + result = 1 + for i in 1..b: result = result * a + + var m = (0, 5) + var n = (56, 3) + + m = (n[0] + m[1], m[1] ^ n[1]) + + doAssert m == (61, 125) + + # also test we can produce unary anon tuples in a macro: + macro mm(): untyped = + result = newTree(nnkTupleConstr, newLit(13)) + + proc nowTuple(): (int,) = + result = (0,) + + doAssert nowTuple() == (Field0: 0) + doAssert mm() == (Field0: 13) + + + +block unpack_asgn: + proc foobar(): (int, int) = (2, 4) + + # test within a proc: + proc pp(x: var int) = + var y: int + (y, x) = foobar() + + template pt(x) = + var y: int + (x, y) = foobar() + + # test within a generic: + proc pg[T](x, y: var T) = + pt(x) + + # test as a top level statement: + var x, y, a, b: int + # test for regression: + (x, y) = (1, 2) + (x, y) = fooBar() + + doAssert x == 2 + doAssert y == 4 + + pp(a) + doAssert a == 4 + + pg(a, b) + doAssert a == 2 + doAssert b == 0 + + + +block unpack_const: + const (a, ) = (1, ) + doAssert a == 1 + + const (b, c) = (2, 3) + doAssert b == 2 + doAssert c == 3 + + # bug #10098 + const (x, y, z) = (4, 5, 6) + doAssert x == 4 + doAssert y == 5 + doAssert z == 6 + + +# bug #10724 +block unpack_const_named: + const (a, ) = (x: 1, ) + doAssert a == 1 + + const (b, c) = (x: 2, y: 3) + doAssert b == 2 + doAssert c == 3 + + const (d, e, f) = (x: 4, y: 5, z: 6) + doAssert d == 4 + doAssert e == 5 + doAssert f == 6 + +block const_named: + const x = block: + (a: 1, b: 2, c: 3) + doAssert x.a == 1 + doAssert x.b == 2 + doAssert x.c == 3 + + +block tuple_subscript: + proc`[]` (t: tuple, key: string): string = + for name, field in fieldPairs(t): + if name == key: + return $field + return "" + + proc`[]` [A,B](t: tuple, key: string, op: (proc(x: A): B)): B = + for name, field in fieldPairs(t): + when field is A: + if name == key: + return op(field) + + proc`[]=`[T](t: var tuple, key: string, val: T) = + for name, field in fieldPairs(t): + when field is T: + if name == key: + field = val + + var tt = (a: 1, b: "str1") + + # test built in operator + tt[0] = 5 + + doAssert tt[0] == 5 + doAssert `[]`(tt, 0) == 5 + + # test overloaded operator + tt["b"] = "str2" + doAssert tt["b"] == "str2" + doAssert `[]`(tt, "b") == "str2" + doAssert tt["b", proc(s: string): int = s.len] == 4 + + + +block tuple_with_seq: + template foo(s: string = "") = + if s.len == 0: + echo "it's nil" + else: + echo s + foo + + # bug #2632 + proc takeTup(x: tuple[s: string;x: seq[int]]) = + discard + takeTup(("foo", @[])) + + #proc foobar(): () = + proc f(xs: seq[int]) = + discard + + proc g(t: tuple[n:int, xs:seq[int]]) = + discard + + when true: + f(@[]) # OK + g((1,@[1])) # OK + g((0,@[])) # NG + + # bug #2630 + type T = tuple[a: seq[int], b: int] + var t: T = (@[1,2,3], 7) + + proc test(s: seq[int]): T = + echo s + (s, 7) + t = test(t.a) + +block: # bug #22049 + type A = object + field: tuple[a, b, c: seq[int]] + + func value(v: var A): var tuple[a, b, c: seq[int]] = + v.field + template get(v: A): tuple[a, b, c: seq[int]] = v.value + + var v = A(field: (@[1], @[2], @[3])) + var (a, b, c) = v.get() + + doAssert a == @[1] + doAssert b == @[2] + doAssert c == @[3] + +block: # bug #22054 + type A = object + field: tuple[a: int] + + func value(v: var A): var tuple[a: int] = + v.field + template get(v: A): tuple[a: int] = v.value + + var v = A(field: (a: 1314)) + doAssert get(v)[0] == 1314 + +block: # tuple unpacking assignment with underscore + var + a = 1 + b = 2 + doAssert (a, b) == (1, 2) + (a, _) = (3, 4) + doAssert (a, b) == (3, 2) + (_, a) = (5, 6) + doAssert (a, b) == (6, 2) + (b, _) = (7, 8) + doAssert (a, b) == (6, 7) diff --git a/tests/tuples/ttypedesc_in_tuple_a.nim b/tests/tuples/ttypedesc_in_tuple_a.nim new file mode 100644 index 000000000..7727bb35e --- /dev/null +++ b/tests/tuples/ttypedesc_in_tuple_a.nim @@ -0,0 +1,5 @@ +discard """ +errormsg: "typedesc not allowed as tuple field." +""" + +var bar = (a: int, b: 1) diff --git a/tests/tuples/ttypedesc_in_tuple_b.nim b/tests/tuples/ttypedesc_in_tuple_b.nim new file mode 100644 index 000000000..b393d877c --- /dev/null +++ b/tests/tuples/ttypedesc_in_tuple_b.nim @@ -0,0 +1,5 @@ +discard """ +errormsg: "Mixing types and values in tuples is not allowed." +""" + +var bar = (int, 1) diff --git a/tests/tuples/tuint_tuple.nim b/tests/tuples/tuint_tuple.nim deleted file mode 100644 index 24bcead5e..000000000 --- a/tests/tuples/tuint_tuple.nim +++ /dev/null @@ -1,10 +0,0 @@ -# bug #1986 found by gdmoore - -proc test(): int64 = - return 0xdeadbeef.int64 - -const items = [ - (var1: test(), var2: 100'u32), - (var1: test(), var2: 192'u32) -] - diff --git a/tests/tuples/tunpack_asgn.nim b/tests/tuples/tunpack_asgn.nim deleted file mode 100644 index a48fcff5d..000000000 --- a/tests/tuples/tunpack_asgn.nim +++ /dev/null @@ -1,32 +0,0 @@ -discard """ - output: '''2 4 -4 -2 0''' -""" - -proc foobar(): (int, int) = (2, 4) - -# test within a proc: -proc pp(x: var int) = - var y: int - (y, x) = foobar() - -template pt(x) = - var y: int - (x, y) = foobar() - -# test within a generic: -proc pg[T](x, y: var T) = - pt(x) - -# test as a top level statement: -var x, y, a, b: int -(x, y) = fooBar() - -echo x, " ", y - -pp(a) -echo a - -pg(a, b) -echo a, " ", b diff --git a/tests/tuples/tuple_with_nil.nim b/tests/tuples/tuple_with_nil.nim index 9b5d583d3..9cad6eccd 100644 --- a/tests/tuples/tuple_with_nil.nim +++ b/tests/tuples/tuple_with_nil.nim @@ -1,24 +1,16 @@ import macros -from strutils import IdentStartChars import parseutils import unicode import math -import fenv -#import unsigned import pegs import streams type - FormatError = object of Exception ## Error in the format string. + FormatError = object of CatchableError ## Error in the format string. Writer = concept W ## Writer to output a character `c`. - when (NimMajor, NimMinor, NimPatch) > (0, 10, 2): - write(W, 'c') - else: - block: - var x: W - write(x, char) + write(W, 'c') FmtAlign = enum ## Format alignment faDefault ## default for given format type @@ -50,7 +42,7 @@ type precision: int ## floating point precision width: int ## minimal width fill: string ## the fill character, UTF8 - align: FmtAlign ## aligment + align: FmtAlign ## alignment sign: FmtSign ## sign notation baseprefix: bool ## whether binary, octal, hex should be prefixed by 0b, 0x, 0o upcase: bool ## upper case letters in hex or exponential formats @@ -73,7 +65,7 @@ type const DefaultPrec = 6 ## Default precision for floating point numbers. - DefaultFmt: Format = (ftDefault, -1, -1, nil, faDefault, fsMinus, false, false, false, nil) + DefaultFmt: Format = (ftDefault, -1, -1, "", faDefault, fsMinus, false, false, false, "") ## Default format corresponding to the empty format string, i.e. ## `x.format("") == x.format(DefaultFmt)`. round_nums = [0.5, 0.05, 0.005, 0.0005, 0.00005, 0.000005, 0.0000005, 0.00000005] @@ -88,7 +80,7 @@ proc has(c: Captures; i: range[0..pegs.MaxSubpatterns-1]): bool {.nosideeffect, result = b.first <= b.last proc get(str: string; c: Captures; i: range[0..MaxSubpatterns-1]; def: char): char {.nosideeffect, inline.} = - ## If capture `i` is non-empty return that portion of `str` casted + ## If capture `i` is non-empty return that portion of `str` cast ## to `char`, otherwise return `def`. result = if c.has(i): str[c.bounds(i).first] else: def @@ -124,7 +116,7 @@ proc parse(fmt: string): Format {.nosideeffect.} = if fmt.rawmatch(p, 0, caps) < 0: raise newException(FormatError, "Invalid format string") - result.fill = fmt.get(caps, 0, nil) + result.fill = fmt.get(caps, 0, "") case fmt.get(caps, 1, 0.char) of '<': result.align = faLeft @@ -144,7 +136,7 @@ proc parse(fmt: string): Format {.nosideeffect.} = result.width = fmt.get(caps, 4, -1) if caps.has(4) and fmt[caps.bounds(4).first] == '0': - if result.fill != nil: + if result.fill != "": raise newException(FormatError, "Leading 0 in with not allowed with explicit fill character") if result.align != faDefault: raise newException(FormatError, "Leading 0 in with not allowed with explicit alignment") @@ -171,7 +163,7 @@ proc parse(fmt: string): Format {.nosideeffect.} = of '%': result.typ = ftPercent else: result.typ = ftDefault - result.arysep = fmt.get(caps, 8, nil, 1) + result.arysep = fmt.get(caps, 8, "", 1) proc getalign(fmt: Format; defalign: FmtAlign; slen: int) : tuple[left, right:int] {.nosideeffect.} = ## Returns the number of left and right padding characters for a @@ -208,7 +200,7 @@ proc writefill(o: var Writer; fmt: Format; n: int; signum: int = 0) = ## `add` ## output function ## `fmt` - ## format to be used (important for padding aligment) + ## format to be used (important for padding alignment) ## `n` ## the number of filling characters to be written ## `signum` @@ -218,7 +210,7 @@ proc writefill(o: var Writer; fmt: Format; n: int; signum: int = 0) = elif fmt.sign == fsPlus: write(o, '+') elif fmt.sign == fsSpace: write(o, ' ') - if fmt.fill == nil: + if fmt.fill.len == 0: for i in 1..n: write(o, ' ') else: for i in 1..n: @@ -345,7 +337,7 @@ proc writeformat(o: var Writer; p: pointer; fmt: Format) = ## Write pointer `i` according to format `fmt` using output object ## `o` and output function `add`. ## - ## Pointers are casted to unsigned int and formatted as hexadecimal + ## Pointers are cast to unsigned int and formatted as hexadecimal ## with prefix unless specified otherwise. var f = fmt if f.typ == 0.char: @@ -353,7 +345,7 @@ proc writeformat(o: var Writer; p: pointer; fmt: Format) = f.baseprefix = true writeformat(o, add, cast[uint](p), f) -proc writeformat(o: var Writer; x: SomeReal; fmt: Format) = +proc writeformat(o: var Writer; x: SomeFloat; fmt: Format) = ## Write real number `x` according to format `fmt` using output ## object `o` and output function `add`. var fmt = fmt @@ -401,8 +393,8 @@ proc writeformat(o: var Writer; x: SomeReal; fmt: Format) = else: len += 4 # exponent # shift y so that 1 <= abs(y) < 2 - if exp > 0: y /= pow(10.SomeReal, abs(exp).SomeReal) - elif exp < 0: y *= pow(10.SomeReal, abs(exp).SomeReal) + if exp > 0: y /= pow(10.SomeFloat, abs(exp).SomeFloat) + elif exp < 0: y *= pow(10.SomeFloat, abs(exp).SomeFloat) elif fmt.typ == ftPercent: len += 1 # percent sign @@ -413,7 +405,7 @@ proc writeformat(o: var Writer; x: SomeReal; fmt: Format) = var mult = 1'i64 for i in 1..prec: mult *= 10 var num = y.int64 - var fr = ((y - num.SomeReal) * mult.SomeReal).int64 + var fr = ((y - num.SomeFloat) * mult.SomeFloat).int64 # build integer part string while num != 0: numstr[numlen] = ('0'.int + (num mod 10)).char @@ -485,7 +477,7 @@ proc writeformat(o: var Writer; b: bool; fmt: Format) = else: raise newException(FormatError, "Boolean values must of one of the following types: s,b,o,x,X,d,n") -proc writeformat(o: var Writer; ary: openarray[any]; fmt: Format) = +proc writeformat(o: var Writer; ary: openArray[system.any]; fmt: Format) = ## Write array `ary` according to format `fmt` using output object ## `o` and output function `add`. if ary.len == 0: return @@ -626,19 +618,19 @@ proc splitfmt(s: string): seq[Part] {.compiletime, nosideeffect.} = else: lvl.dec let clpos = pos - var fmtpart = Part(kind: pkFmt, arg: -1, fmt: s.substr(oppos+1, clpos-1), field: nil, index: int.high, nested: nested) + var fmtpart = Part(kind: pkFmt, arg: -1, fmt: s.substr(oppos+1, clpos-1), field: "", index: int.high, nested: nested) if fmtpart.fmt.len > 0: var m: array[0..3, string] if not fmtpart.fmt.match(subpeg, m): error("invalid format string") - if m[1] != nil and m[1].len > 0: + if m[1].len > 0: fmtpart.field = m[1].substr(1) - if m[2] != nil and m[2].len > 0: + if m[2].len > 0: discard parseInt(m[2].substr(1, m[2].len-2), fmtpart.index) if m[0].len > 0: discard parseInt(m[0], fmtpart.arg) - if m[3] == nil or m[3].len == 0: + if m[3].len == 0: fmtpart.fmt = "" elif m[3][0] == ':': fmtpart.fmt = m[3].substr(1) @@ -650,7 +642,7 @@ proc splitfmt(s: string): seq[Part] {.compiletime, nosideeffect.} = proc literal(s: string): NimNode {.compiletime, nosideeffect.} = ## Return the nim literal of string `s`. This handles the case if ## `s` is nil. - result = if s == nil: newNilLit() else: newLit(s) + result = newLit(s) proc literal(b: bool): NimNode {.compiletime, nosideeffect.} = ## Return the nim literal of boolean `b`. This is either `true` @@ -665,7 +657,7 @@ proc literal[T](x: T): NimNode {.compiletime, nosideeffect.} = result = newLit(x) proc generatefmt(fmtstr: string; - args: var openarray[tuple[arg:NimNode, cnt:int]]; + args: var openArray[tuple[arg:NimNode, cnt:int]]; arg: var int;): seq[tuple[val, fmt:NimNode]] {.compiletime.} = ## fmtstr ## the format string @@ -713,7 +705,7 @@ proc generatefmt(fmtstr: string; args[arg].cnt = args[arg].cnt + 1 arg.inc # possible field access - if part.field != nil and part.field.len > 0: + if part.field.len > 0: argexpr = newDotExpr(argexpr, part.field.ident) # possible array access if part.index < int.high: @@ -724,7 +716,7 @@ proc generatefmt(fmtstr: string; # nested format string. Compute the format string by # concatenating the parts of the substring. for e in generatefmt(part.fmt, args, arg): - var newexpr = if part.fmt == nil: e.val else: newCall(bindsym"format", e.val, e.fmt) + var newexpr = if part.fmt.len == 0: e.val else: newCall(bindsym"format", e.val, e.fmt) if fmtexpr != nil and fmtexpr.kind != nnkNilLit: fmtexpr = infix(fmtexpr, "&", newexpr) else: @@ -758,7 +750,7 @@ proc addfmtfmt(fmtstr: string; args: NimNode; retvar: NimNode): NimNode {.compil if arg.cnt == 0: warning("Argument " & $(i+1) & " `" & args[i].repr & "` is not used in format string") -macro addfmt(s: var string, fmtstr: string{lit}, args: varargs[expr]): expr = +macro addfmt(s: var string, fmtstr: string{lit}, args: varargs[typed]): untyped = ## The same as `s.add(fmtstr.fmt(args...))` but faster. result = addfmtfmt($fmtstr, args, s) diff --git a/tests/tuples/tuple_with_seq.nim b/tests/tuples/tuple_with_seq.nim deleted file mode 100644 index 39edb500f..000000000 --- a/tests/tuples/tuple_with_seq.nim +++ /dev/null @@ -1,46 +0,0 @@ -discard """ - output: '''it's nil -@[1, 2, 3]''' -""" - -template foo(s: string = nil) = - if isNil(s): - echo "it's nil" - else: - echo s - -foo - - -# bug #2632 - -proc takeTup(x: tuple[s: string;x: seq[int]]) = - discard - -takeTup(("foo", @[])) - - -#proc foobar(): () = - -proc f(xs: seq[int]) = - discard - -proc g(t: tuple[n:int, xs:seq[int]]) = - discard - -when isMainModule: - f(@[]) # OK - g((1,@[1])) # OK - g((0,@[])) # NG - - -# bug #2630 -type T = tuple[a: seq[int], b: int] - -var t: T = (@[1,2,3], 7) - -proc test(s: seq[int]): T = - echo s - (s, 7) - -t = test(t.a) diff --git a/tests/tuples/twrong_generic_caching.nim b/tests/tuples/twrong_generic_caching.nim new file mode 100644 index 000000000..32ef344d2 --- /dev/null +++ b/tests/tuples/twrong_generic_caching.nim @@ -0,0 +1,4 @@ + +import parsecfg + +import asynchttpserver diff --git a/tests/tuples/twrongtupleaccess.nim b/tests/tuples/twrongtupleaccess.nim index b1684b097..591716a2e 100644 --- a/tests/tuples/twrongtupleaccess.nim +++ b/tests/tuples/twrongtupleaccess.nim @@ -1,10 +1,9 @@ discard """ + errormsg: "attempting to call undeclared routine: \'setBLAH\'" file: "twrongtupleaccess.nim" line: 9 - errormsg: "attempting to call undeclared routine: \'setBLAH\'" """ # Bugfix var v = (5.0, 10.0) v.setBLAH(10) - |