diff options
Diffstat (limited to 'tests/proc')
25 files changed, 1133 insertions, 3 deletions
diff --git a/tests/proc/mdefaultprocparam.nim b/tests/proc/mdefaultprocparam.nim new file mode 100644 index 000000000..4a17277c0 --- /dev/null +++ b/tests/proc/mdefaultprocparam.nim @@ -0,0 +1,5 @@ + + +proc p*(f = (proc(): string = "hi")) = + echo f() + diff --git a/tests/proc/t15949.nim b/tests/proc/t15949.nim new file mode 100644 index 000000000..6467ed5d3 --- /dev/null +++ b/tests/proc/t15949.nim @@ -0,0 +1,16 @@ +# bug #15949 and RFC #480 + +proc procWarn(a, b = 1): (int, int) = (a, b) #[tt.Warning + ^ a, b all have default value '1', this may be unintentional, either use ';' (semicolon) or explicitly write each default value [ImplicitDefaultValue]]# + +proc procGood(a = 1, b = 1): (int, int) = (a, b) + +doAssert procGood() == (1, 1) +doAssert procGood(b = 3) == (1, 3) +doAssert procGood(a = 2) == (2, 1) +doAssert procGood(a = 5, b = 6) == (5, 6) + +# The type (and default value propagation breaks in the below example +# as semicolon is used instead of comma. +proc procBad(a; b = 1): (int, int) = (a, b) #[tt.Error + ^ parameter 'a' requires a type]# diff --git a/tests/proc/t17157.nim b/tests/proc/t17157.nim new file mode 100644 index 000000000..020e93fce --- /dev/null +++ b/tests/proc/t17157.nim @@ -0,0 +1,6 @@ +discard """ + errormsg: "'untyped' is only allowed in templates and macros or magic procs" +""" + +template something(op: proc (v: untyped): void): void = + discard diff --git a/tests/proc/t19795.nim b/tests/proc/t19795.nim new file mode 100644 index 000000000..677ec0a63 --- /dev/null +++ b/tests/proc/t19795.nim @@ -0,0 +1,19 @@ +discard """ + matrix: "--mm:arc" +""" + +# bug #19795 +# bug #21085 + +type Vector = seq[int] + +var vect: Vector = newSeq[int](5) +doAssert vect == @[0, 0, 0, 0, 0] + +# Needed to get the problem. Could also use "var". +let vectCopy = vect + +# Then some procedure definition is needed to get the problem. +proc p(): int = 3 + +doAssert vect == @[0, 0, 0, 0, 0] \ No newline at end of file diff --git a/tests/proc/t23874.nim b/tests/proc/t23874.nim new file mode 100644 index 000000000..940bc4ac8 --- /dev/null +++ b/tests/proc/t23874.nim @@ -0,0 +1,26 @@ +block: + type Head[T] = object + wasc: bool + + proc `=destroy`[T](x: var Head[T]) = + discard + + proc `=copy`[T](x: var Head[T], y: Head[T]) = + x.wasc = true + + proc `=dup`[T](x: Head[T]): Head[T] = + result.wasc = true + + proc update(h: var Head) = + discard + + proc digest(h: sink Head) = + assert h.wasc + + var h = Head[int](wasc: false) + h.digest() # sink h + h.update() # use after sink + +block: + proc two(a: sink auto) =discard + assert typeof(two[int]) is proc(a: sink int) {.nimcall.} diff --git a/tests/proc/tcolonisproc.nim b/tests/proc/tcolonisproc.nim new file mode 100644 index 000000000..c10dabcf1 --- /dev/null +++ b/tests/proc/tcolonisproc.nim @@ -0,0 +1,19 @@ +discard """ +output: ''' +1 +2 +''' +""" + +proc p(a, b: int, c: proc ()) = + c() + +when false: + # language spec changed: + p(1, 3): + echo 1 + echo 3 + +p(1, 1, proc() = + echo 1 + echo 2) diff --git a/tests/proc/tdefaultprocparam.nim b/tests/proc/tdefaultprocparam.nim new file mode 100644 index 000000000..90edfa8c9 --- /dev/null +++ b/tests/proc/tdefaultprocparam.nim @@ -0,0 +1,90 @@ +discard """ +output: ''' +hi +hi +topLevel|topLevel| +topLevel2|topLevel2| +inProc|inProc| +inProc2|inProc2| +topLevel|9 +topLevel2|10 +inProc|7 +inProc2|8 +must have been the wind.. +I'm there +must have been the wind.. +I'm there +symbol'a'symbol'a' +symbol'b'symbol'b' +symbol'a'symbol'b' +symbol'a'9 +symbol'b'9 +symbol'a'0 +''' +""" +import mdefaultprocparam + +p() + +proc testP = + p() + +testP() + +proc p2(s: string, count = s): string = s & count + +proc testP2 = + echo p2 """inProc|""" + echo p2 """inProc2|""" + +echo p2 """topLevel|""" +echo p2 """topLevel2|""" + +testP2() + +import macros +macro dTT(a: typed) = echo a.treeRepr + +proc p3(s: string, count = len(s)): string = s & $count + +proc testP3 = + echo p3 """inProc|""" + echo p3 """inProc2|""" + +echo p3 """topLevel|""" +echo p3 """topLevel2|""" + +testP3() + +proc cut(s: string, c = len(s)): string = + s[0..<s.len-c] + +echo "must have been the wind.." & cut "I'm gone" +echo cut("I'm gone", 4) & "there" + +proc testCut = + echo "must have been the wind.." & cut "I'm gone" + echo cut("I'm gone", 4) & "there" + +testCut() + +var a = "symbol'a'" +var b = "symbol'b'" + +block: + echo p2(a) +block: + echo p2(b) +block: + echo p2(a, b) +block: + echo p3(a) + echo p3(b) + echo p3(a, 0) + +# bug #12252 +proc foo(a = 0, b = a.high, c = high(typeof(a))) = + discard + +foo() + diff --git a/tests/proc/texplicitgenericcount.nim b/tests/proc/texplicitgenericcount.nim new file mode 100644 index 000000000..8654a1d13 --- /dev/null +++ b/tests/proc/texplicitgenericcount.nim @@ -0,0 +1,24 @@ +discard """ + cmd: "nim check -d:testsConciseTypeMismatch $file" +""" + +proc foo[T, U](x: T, y: U): (T, U) = (x, y) + +let x = foo[int](1, 2) #[tt.Error + ^ type mismatch +Expression: foo[int](1, 2) + [1] 1: int literal(1) + [2] 2: int literal(2) + +Expected one of (first mismatch at [position]): +[2] proc foo[T, U](x: T; y: U): (T, U) + missing generic parameter: U]# +let y = foo[int, float, string](1, 2) #[tt.Error + ^ type mismatch +Expression: foo[int, float, string](1, 2) + [1] 1: int literal(1) + [2] 2: int literal(2) + +Expected one of (first mismatch at [position]): +[3] proc foo[T, U](x: T; y: U): (T, U) + extra generic param given]# diff --git a/tests/proc/texplicitgenericcountverbose.nim b/tests/proc/texplicitgenericcountverbose.nim new file mode 100644 index 000000000..76228eeaf --- /dev/null +++ b/tests/proc/texplicitgenericcountverbose.nim @@ -0,0 +1,22 @@ +discard """ + cmd: "nim check $file" +""" + +proc foo[T, U](x: T, y: U): (T, U) = (x, y) + +let x = foo[int](1, 2) #[tt.Error + ^ type mismatch: got <int literal(1), int literal(2)> +but expected one of: +proc foo[T, U](x: T; y: U): (T, U) + first type mismatch at position: 2 in generic parameters + missing generic parameter: U + +expression: foo[int](1, 2)]# +let y = foo[int, float, string](1, 2) #[tt.Error + ^ type mismatch: got <int literal(1), int literal(2)> +but expected one of: +proc foo[T, U](x: T; y: U): (T, U) + first type mismatch at position: 3 in generic parameters + extra generic param given + +expression: foo[int, float, string](1, 2)]# diff --git a/tests/proc/texplicitgenerics.nim b/tests/proc/texplicitgenerics.nim new file mode 100644 index 000000000..833d77b3b --- /dev/null +++ b/tests/proc/texplicitgenerics.nim @@ -0,0 +1,55 @@ +block: # issue #16376 + type + Matrix[T] = object + data: T + proc randMatrix[T](m, n: int, max: T): Matrix[T] = discard + proc randMatrix[T](m, n: int, x: Slice[T]): Matrix[T] = discard + template randMatrix[T](m, n: int): Matrix[T] = randMatrix[T](m, n, T(1.0)) + let B = randMatrix[float32](20, 10) + +block: # different generic param counts + type + Matrix[T] = object + data: T + proc randMatrix[T](m: T, n: T): Matrix[T] = Matrix[T](data: T(1.0)) + proc randMatrix[T; U: not T](m: T, n: U): (Matrix[T], U) = (Matrix[T](data: T(1.0)), default(U)) + let b = randMatrix[float32](20, 10) + doAssert b == Matrix[float32](data: 1.0) + +block: # above for templates + type + Matrix[T] = object + data: T + template randMatrix[T](m: T, n: T): Matrix[T] = Matrix[T](data: T(1.0)) + template randMatrix[T; U: not T](m: T, n: U): (Matrix[T], U) = (Matrix[T](data: T(1.0)), default(U)) + let b = randMatrix[float32](20, 10) + doAssert b == Matrix[float32](data: 1.0) + +block: # sigmatch can't handle this without pre-instantiating the type: + # minimized from numericalnim + type Foo[T] = proc (x: T) + proc foo[T](x: T) = discard + proc bar[T](f: Foo[T]) = discard + bar[int](foo) + +block: # ditto but may be wrong minimization + # minimized from measuremancer + type Foo[T] = object + proc foo[T](): Foo[T] = Foo[T]() + # this is the actual issue but there are other instantiation problems + proc bar[T](x = foo[T]()) = discard + bar[int](Foo[int]()) + bar[int]() + # alternative version, also causes instantiation issue + proc baz[T](x: typeof(foo[T]())) = discard + baz[int](Foo[int]()) + +block: # issue #21346 + type K[T] = object + template s[T](x: int) = doAssert T is K[K[int]] + proc b1(n: bool | bool) = s[K[K[int]]](3) + proc b2(n: bool) = s[K[K[int]]](3) + template b3(n: bool) = s[K[K[int]]](3) + b1(false) # Error: cannot instantiate K; got: <T> but expected: <T> + b2(false) # Builds, on its own + b3(false) diff --git a/tests/proc/tfunc_type.nim b/tests/proc/tfunc_type.nim index 2a583fcb9..93697acb1 100644 --- a/tests/proc/tfunc_type.nim +++ b/tests/proc/tfunc_type.nim @@ -1,6 +1,6 @@ discard """ - errmsg: "func keyword is not allowed in type descriptions, use proc with {.noSideEffect.} pragma instead" + errormsg: "func keyword is not allowed in type descriptions, use proc with {.noSideEffect.} pragma instead" """ type diff --git a/tests/proc/tgenericdefaultparam.nim b/tests/proc/tgenericdefaultparam.nim new file mode 100644 index 000000000..7bce591ce --- /dev/null +++ b/tests/proc/tgenericdefaultparam.nim @@ -0,0 +1,98 @@ +block: # issue #16700 + type MyObject[T] = object + x: T + proc initMyObject[T](value = T.default): MyObject[T] = + MyObject[T](x: value) + var obj = initMyObject[int]() + +block: # issue #20916 + type + SomeX = object + v: int + var val = 0 + proc f(_: type int, x: SomeX, v = x.v) = + doAssert v == 42 + val = v + proc a(): proc() = + let v = SomeX(v: 42) + var tmp = proc() = + int.f(v) + tmp + a()() + doAssert val == 42 + +import std/typetraits + +block: # issue #24099, original example + type + ColorRGBU = distinct array[3, uint8] ## RGB range 0..255 + ColorRGBAU = distinct array[4, uint8] ## RGB range 0..255 + ColorRGBUAny = ColorRGBU | ColorRGBAU + template componentType(t: typedesc[ColorRGBUAny]): typedesc = + ## Returns component type of a given color type. + arrayType distinctBase t + func `~=`[T: ColorRGBUAny](a, b: T, e = componentType(T)(1.0e-11)): bool = + ## Compares colors with given accuracy. + abs(a[0] - b[0]) < e and abs(a[1] - b[1]) < e and abs(a[2] - b[2]) < e + +block: # issue #24099, modified to actually work + type + ColorRGBU = distinct array[3, uint8] ## RGB range 0..255 + ColorRGBAU = distinct array[4, uint8] ## RGB range 0..255 + ColorRGBUAny = ColorRGBU | ColorRGBAU + template arrayType[I, T](t: typedesc[array[I, T]]): typedesc = + T + template `[]`(a: ColorRGBUAny, i: untyped): untyped = distinctBase(a)[i] + proc abs(a: uint8): uint8 = a + template componentType(t: typedesc[ColorRGBUAny]): typedesc = + ## Returns component type of a given color type. + arrayType distinctBase t + func `~=`[T: ColorRGBUAny](a, b: T, e = componentType(T)(1.0e-11)): bool = + ## Compares colors with given accuracy. + abs(a[0] - b[0]) <= e and abs(a[1] - b[1]) <= e and abs(a[2] - b[2]) <= e + doAssert ColorRGBU([1.uint8, 1, 1]) ~= ColorRGBU([1.uint8, 1, 1]) + +block: # issue #24099, modified to work but using float32 + type + ColorRGBU = distinct array[3, float32] ## RGB range 0..255 + ColorRGBAU = distinct array[4, float32] ## RGB range 0..255 + ColorRGBUAny = ColorRGBU | ColorRGBAU + template arrayType[I, T](t: typedesc[array[I, T]]): typedesc = + T + template `[]`(a: ColorRGBUAny, i: untyped): untyped = distinctBase(a)[i] + template componentType(t: typedesc[ColorRGBUAny]): typedesc = + ## Returns component type of a given color type. + arrayType distinctBase t + func `~=`[T: ColorRGBUAny](a, b: T, e = componentType(T)(1.0e-11)): bool = + ## Compares colors with given accuracy. + abs(a[0] - b[0]) < e and abs(a[1] - b[1]) < e and abs(a[2] - b[2]) < e + doAssert ColorRGBU([1.float32, 1, 1]) ~= ColorRGBU([1.float32, 1, 1]) + +block: # issue #13270 + type + A = object + B = object + proc f(a: A) = discard + proc g[T](value: T, cb: (proc(a: T)) = f) = + cb value + g A() + # This should fail because there is no f(a: B) overload available + doAssert not compiles(g B()) + +block: # issue #24121 + type + Foo = distinct int + Bar = distinct int + FooBar = Foo | Bar + + proc foo[T: distinct](x: T): string = "a" + proc foo(x: Foo): string = "b" + proc foo(x: Bar): string = "c" + + proc bar(x: FooBar, y = foo(x)): string = y + doAssert bar(Foo(123)) == "b" + doAssert bar(Bar(123)) == "c" + + proc baz[T: FooBar](x: T, y = foo(x)): string = y + doAssert baz(Foo(123)) == "b" + doAssert baz(Bar(123)) == "c" diff --git a/tests/proc/tillegalreturntype.nim b/tests/proc/tillegalreturntype.nim index e26c44bea..1076f7f75 100644 --- a/tests/proc/tillegalreturntype.nim +++ b/tests/proc/tillegalreturntype.nim @@ -1,6 +1,6 @@ discard """ - cmd: "nim check $file" - errmsg: "" + cmd: "nim check --hints:off $file" + errormsg: "" nimout: ''' tillegalreturntype.nim(11, 11) Error: return type 'typed' is only valid for macros and templates tillegalreturntype.nim(14, 11) Error: return type 'untyped' is only valid for macros and templates diff --git a/tests/proc/tinferlambdareturn.nim b/tests/proc/tinferlambdareturn.nim new file mode 100644 index 000000000..e9e592871 --- /dev/null +++ b/tests/proc/tinferlambdareturn.nim @@ -0,0 +1,36 @@ +import std/[sugar, sequtils] + +block: # issue #23200 + proc dosomething(iter: int -> (iterator: int)) = + discard + proc dosomething(iter: int -> seq[int]) = + discard + proc makeSeq(x: int): seq[int] = + @[x] + # Works fine with 1.6.12 and 1.6.14 + dosomething(makeSeq) + # Works with 1.6.12, fails with 1.6.14 + dosomething((y) => makeSeq(y)) + dosomething(proc (y: auto): auto = makeSeq(y)) + proc foo(y: auto): auto = makeSeq(y) + dosomething(foo) + +block: # issue #18866 + proc somefn[T](list: openarray[T], op: proc (v: T): float) = + discard op(list[0]) + + type TimeD = object + year: Natural + month: 1..12 + day: 1..31 + + doAssert not compiles(@[TimeD()].somefn(proc (v: auto): auto = + v + )) + @[TimeD()].somefn(proc (v: auto): auto = + v.year.float + ) + proc foo(v: auto): auto = v + doAssert not compiles(@[TimeD()].somefn(foo)) + proc bar(v: auto): auto = v.year.float + @[TimeD()].somefn(bar) diff --git a/tests/proc/tlambdadonotation.nim b/tests/proc/tlambdadonotation.nim new file mode 100644 index 000000000..3160c0972 --- /dev/null +++ b/tests/proc/tlambdadonotation.nim @@ -0,0 +1,78 @@ +discard """ +output: ''' +issue #11812 +issue #10899 +123 +issue #11367 +event consumed! +''' +""" + +echo "issue #11812" + +proc run(a: proc()) = a() + +proc main() = + var test: int + run(proc() = test = 0) + run do: + test = 0 + +main() + + +echo "issue #10899" + +proc foo(x: proc {.closure.}) = + x() + +proc bar = + var x = 123 + # foo proc = echo x #[ ok ]# + foo: echo x #[ SIGSEGV: Illegal storage access. (Attempt to read from nil?) ]# + +bar() + +echo "issue #11367" + +type + + EventCB = proc() + + Emitter = object + cb: EventCB + + Subscriber = object + discard + +proc newEmitter(): Emitter = + result + +proc on_event(self: var Emitter, cb: EventCB) = + self.cb = cb + +proc emit(self: Emitter) = + self.cb() + +proc newSubscriber(): Subscriber = + result + +proc consume(self: Subscriber) = + echo "event consumed!" + +proc main2() = + var emitter = newEmitter() + var subscriber = newSubscriber() + + proc foo() = + subscriber.consume() + + emitter.on_event() do (): + subscriber.consume() + + # this works + # emitter.on_event(foo) + + emitter.emit() + +main2() diff --git a/tests/proc/tlambdapragma.nim b/tests/proc/tlambdapragma.nim new file mode 100644 index 000000000..daa952b1e --- /dev/null +++ b/tests/proc/tlambdapragma.nim @@ -0,0 +1,7 @@ +discard """ + errormsg: "invalid pragma: exportc" +""" + +let _ = proc () {.exportc.} = + # this would previously cause a codegen error + discard diff --git a/tests/proc/tnamedparams.nim b/tests/proc/tnamedparams.nim new file mode 100644 index 000000000..d0774f0d8 --- /dev/null +++ b/tests/proc/tnamedparams.nim @@ -0,0 +1,12 @@ +discard """ + errormsg: "type mismatch: got <input: string, filename: string, line: int literal(1), col: int literal(23)>" + file: "tnamedparams.nim" + line: 8 +""" +import pegs + +discard parsePeg( + input = "input", + filename = "filename", + line = 1, + col = 23) diff --git a/tests/proc/tnamedparams2.nim b/tests/proc/tnamedparams2.nim new file mode 100644 index 000000000..9acdeed87 --- /dev/null +++ b/tests/proc/tnamedparams2.nim @@ -0,0 +1,15 @@ +import pegs + +discard parsePeg( + pattern = "input", + filename = "filename", + line = 1, + col = 23) + +# bug #12196 +type + Renderer = object + +var xs0, x0, xs1, x1: int +proc init(xs=xs0; x=x0; renderer: Renderer; r: byte) = discard +init(xs=xs1, x=x1, r=3, renderer=Renderer()) diff --git a/tests/proc/tnamedparams3.nim b/tests/proc/tnamedparams3.nim new file mode 100644 index 000000000..e736c338c --- /dev/null +++ b/tests/proc/tnamedparams3.nim @@ -0,0 +1,10 @@ +discard """ + errormsg: "type mismatch: got <int literal(5), b: bool>" + line: 10 +""" + +# bug #2993 +proc test(i: int, a, b: bool) = discard +#test(5, b = false) #Missing param a + +5.test(b = false) #Missing param a diff --git a/tests/proc/tparamsindefault.nim b/tests/proc/tparamsindefault.nim new file mode 100644 index 000000000..3fe917f2b --- /dev/null +++ b/tests/proc/tparamsindefault.nim @@ -0,0 +1,120 @@ +discard """ +output: ''' +@[1, 2, 3]@[1, 2, 3] +a +a +1 +3 is an int +2 is an int +miau is a string +f1 1 1 1 +f1 2 3 3 +f1 10 20 30 +f2 100 100 100 +f2 200 300 300 +f2 300 400 400 +f3 10 10 20 +f3 10 15 25 +true true +false true +world +typedescDefault +''' +""" + +template reject(x) = + assert(not compiles(x)) + +block: + # https://github.com/nim-lang/Nim/issues/7756 + proc foo[T](x: seq[T], y: seq[T] = x) = + echo x, y + + let a = @[1, 2, 3] + foo(a) + +block: + # https://github.com/nim-lang/Nim/issues/1201 + proc issue1201(x: char|int = 'a') = echo x + + issue1201() + issue1201('a') + issue1201(1) + + # https://github.com/nim-lang/Nim/issues/7000 + proc test(a: int|string = 2) = + when a is int: + echo a, " is an int" + elif a is string: + echo a, " is a string" + + test(3) # works + test() # works + test("miau") + +block: + # https://github.com/nim-lang/Nim/issues/3002 and similar + proc f1(a: int, b = a, c = b) = + echo "f1 ", a, " ", b, " ", c + + proc f2(a: int, b = a, c: int = b) = + echo "f2 ", a, " ", b, " ", c + + proc f3(a: int, b = a, c = a + b) = + echo "f3 ", a, " ", b, " ", c + + f1 1 + f1(2, 3) + f1 10, 20, 30 + 100.f2 + 200.f2 300 + 300.f2(400) + + 10.f3() + 10.f3(15) + + reject: + # This is a type mismatch error: + proc f4(a: int, b = a, c: float = b) = discard + + reject: + # undeclared identifier + proc f5(a: int, b = c, c = 10) = discard + + reject: + # undeclared identifier + proc f6(a: int, b = b) = discard + + reject: + # undeclared identifier + proc f7(a = a) = discard + +block: + proc f(a: var int, b: ptr int, c = addr(a)) = + echo addr(a) == b, " ", b == c + + var x = 10 + f(x, addr(x)) + f(x, nil, nil) + +block: + # https://github.com/nim-lang/Nim/issues/1046 + proc pySubstr(s: string, start: int, endd = s.len()): string = + var + revStart = start + revEnd = endd + + if start < 0: + revStart = s.len() + start + if endd < 0: + revEnd = s.len() + endd + + return s[revStart .. revEnd-1] + + echo pySubstr("Hello world", -5) + + +# bug #11660 + +func typedescDefault(T: typedesc; arg: T = 0) = debugEcho "typedescDefault" +typedescDefault(int) diff --git a/tests/proc/tprocvar.nim b/tests/proc/tprocvar.nim new file mode 100644 index 000000000..14f24efdc --- /dev/null +++ b/tests/proc/tprocvar.nim @@ -0,0 +1,39 @@ +discard """ + output: ''' +papbpcpdpe7 +''' +""" + +block genericprocvar: + proc foo[T](thing: T) = + discard thing + var a: proc (thing: int) {.nimcall.} = foo[int] + + +block tprocvar2: + proc pa() {.cdecl.} = write(stdout, "pa") + proc pb() {.cdecl.} = write(stdout, "pb") + proc pc() {.cdecl.} = write(stdout, "pc") + proc pd() {.cdecl.} = write(stdout, "pd") + proc pe() {.cdecl.} = write(stdout, "pe") + + const algos = [pa, pb, pc, pd, pe] + var x: proc (a, b: int): int {.cdecl.} + + proc ha(c, d: int): int {.cdecl.} = + echo(c + d) + result = c + d + + for a in items(algos): + a() + + x = ha + discard x(3, 4) + + +block tprocvars: + proc doSomething(v: int, x: proc(v:int):int): int = return x(v) + proc doSomething(v: int, x: proc(v:int)) = x(v) + + doAssert doSomething(10, proc(v: int): int = return v div 2) == 5 + diff --git a/tests/proc/tprocvarmismatch.nim b/tests/proc/tprocvarmismatch.nim new file mode 100644 index 000000000..4d6be9be6 --- /dev/null +++ b/tests/proc/tprocvarmismatch.nim @@ -0,0 +1,18 @@ +discard """ + errormsg: "type mismatch" + line: 17 + file: "tprocvarmismatch.nim" +""" + +type + TCallback = proc (a, b: int) + +proc huh(x, y: var int) = + x = 0 + y = x+1 + +proc so(c: TCallback) = + c(2, 4) + +so(huh) + diff --git a/tests/proc/tstaticsignature.nim b/tests/proc/tstaticsignature.nim new file mode 100644 index 000000000..25aa09c5d --- /dev/null +++ b/tests/proc/tstaticsignature.nim @@ -0,0 +1,268 @@ +block: # issue #4228 + template seqType(t: typedesc): typedesc = + when t is int: + seq[int] + else: + seq[string] + + proc mkSeq[T: int|string](v: T): seqType(T) = + result = newSeq[T](1) + result[0] = v + + doAssert mkSeq("a") == @["a"] + doAssert mkSeq(1) == @[1] + +block: # expanded version of t8545 + template bar(a: static[bool]): untyped = + when a: + int + else: + float + + proc main() = + proc foo1(a: static[bool]): auto = 1 + doAssert foo1(true) == 1 + + proc foo2(a: static[bool]): bar(a) = 1 + doAssert foo2(true) == 1 + doAssert foo2(true) is int + doAssert foo2(false) == 1.0 + doAssert foo2(false) is float + + proc foo3(a: static[bool]): bar(cast[bool](a)) = 1 + doAssert foo3(true) == 1 + doAssert foo3(true) is int + doAssert foo3(false) == 1.0 + doAssert foo3(false) is float + + proc foo4(a: static[bool]): bar(static(a)) = 1 + doAssert foo4(true) == 1 + doAssert foo4(true) is int + doAssert foo4(false) == 1.0 + doAssert foo4(false) is float + + static: main() + main() + +block: # issue #8406 + macro f(x: static[int]): untyped = discard + proc g[X: static[int]](v: f(X)) = discard + +import macros + +block: # issue #8551 + macro distinctBase2(T: typedesc): untyped = + let typeNode = getTypeImpl(T) + expectKind(typeNode, nnkBracketExpr) + if typeNode[0].typeKind != ntyTypeDesc: + error "expected typeDesc, got " & $typeNode[0] + var typeSym = typeNode[1] + + typeSym = getTypeImpl(typeSym) + + if typeSym.typeKind != ntyDistinct: + error "type is not distinct: " & $typeSym.typeKind + + typeSym = typeSym[0] + typeSym + + func distinctBase[T](a: T): distinctBase2(T) = distinctBase2(T)(a) + + type T = distinct int + doAssert distinctBase(T(0)) is int + +block: + type Foo[T] = object + x: T + + proc foo(x: Foo): Foo[x.T] = + doAssert typeof(result) is typeof(x) + + var a: Foo[int] + let b: Foo[int] = foo(a) + doAssert b.x is int + +block: + type Foo[T: static int] = object + x: array[T, int] + + proc double(x: int): int = x * 2 + + proc foo[T: static int](x: Foo[T]): Foo[T.double] = + doAssert typeof(result).T == double(typeof(x).T) + + var a: Foo[3] + let b: Foo[6] = foo(a) + doAssert $typeof(foo(a)) == "Foo[6]" + +block: + type Foo[T: static int] = object + x: array[T, int] + + proc foo(x: Foo): Foo[x.T] = + doAssert typeof(result).T == typeof(x).T + doAssert typeof(result) is typeof(x) + + var a: Foo[3] + let b: Foo[3] = foo(a) + doAssert $typeof(foo(a)) == "Foo[3]" + +block: # issue #7006 + type + Node[T] = object + val: T + next: ref Node[T] + HHSet[T, Key] = object + data: seq[Node[T]] + proc rawGet(hhs:HHSet; key: hhs.Key): ptr Node[hhs.T] = + return nil # body doesn't matter + var hhs: HHSet[string, cstring] + discard hhs.rawGet("hello".cstring) + +block: # issue #7008 + type Node[T] = object + val: T + # Compiles fine + proc concreteProc(s: Node[cstring]; key: s.T) = discard + # Also fine + proc implicitGenericProc1(s: Node; key: s.T) = discard + # still fine + proc explicitGenericProc1[T](s: Node[T]; key: T) = discard + # Internal Compiler Error! + proc explicitGenericProc2[T](s: Node[T]; key: s.T) = discard + let n = Node[int](val: 5) + implicitGenericProc1(n, 5) # works + explicitGenericProc1(n, 5) # works + explicitGenericProc2(n, 5) # doesn't + +block: # issue #20027 + block: + type Test[T] = object + proc run(self: Test): self.T = discard + discard run(Test[int]()) + block: + type Test[T] = object + proc run[T](self: Test[T]): self.T = discard + discard run(Test[int]()) + block: + type Test[T] = object + proc run(self: Test[auto]): self.T = discard + discard run(Test[int]()) + +block: # issue #11112 + proc foo[A, B]: type(A.default + B.default) = + discard + doAssert foo[int, int]() is int + +block: # tyStatic and tyFromExpr instantiation mid-match + proc bar(x: int): int = x * 3 + proc bar2(x: static int): int = x * 4 + type Foo[T: static int] = distinct array[T, int] + proc foo[T: static int](x: Foo[T], y: Foo[bar(T)]) = discard + proc foo2[T: static int](x: Foo[T], y: Foo[bar2(T)]) = discard + foo(Foo[1]([1]), Foo[3]([1, 2, 3])) + foo2(Foo[1]([1]), Foo[4]([1, 2, 3, 4])) + +block: # issue #4990 + type Foo[I: static[int], A: static[array[I, int]]] = object + curIndex: int + + proc next[I: static[int], A: static[array[I, int]]](f: Foo[I, A]): string = + discard + const arr = [1, 2, 3] + var f: Foo[arr.len, arr] + discard next(f) + +block: # issue #4990 comment + type + Foo[A: static[int], B: static[int], TokenType: enum, EofToken: static[TokenType]] = object + curIndex: int + MyEnum = enum + meA, meB + Bar = Foo[2, 3, MyEnum, meA] + proc next[A: static[int], B: static[int], TokenType: enum, + EofToken: static[TokenType]](f: Foo[A, B, TokenType, EofToken], + a: static[(array[A, int], array[B, int])]): TokenType = + TokenType(a[0][f.curIndex]) + const + a = [1, 2] + b = [3, 4, 5] + template next(bar: Bar): MyEnum = + next(Foo[2, 3, MyEnum, meA](bar), (a, b)) + let bar = Bar(curIndex: 0) + doAssert bar.next() == meB + +block: # issue #14053 + template returnType(value: static[int]): typedesc = + when value == 1: + int + else: + float + proc fun(value: static[int]): returnType(value) = discard + doAssert fun(1) is int + template returnType2(value: static[int]): typedesc = + int + proc fun2(value: static[int]): returnType2(value) = discard + doAssert fun2(1) is int + +block: # issue #7547 + macro foo(N: static[int]): untyped = + result = getType(int) + type + Foo[N: static[int]] = foo(N) + ContainsFoo[N: static[int]] = object + Ffoo: Foo[N] + proc initFoo(N: static[int]): Foo[N] = discard + proc initContainsFoo(size: static[int]): ContainsFoo[size] = discard + var a: Foo[10] # Works + doAssert a is int + let b = initFoo(10) # Works + doAssert b is int + let c = ContainsFoo[5]() # Works + doAssert c.Ffoo is int + let z = initContainsFoo(5) # Error: undeclared identifier: 'N' + doAssert z.Ffoo is int + +block: # issue #22607, needs nkWhenStmt to be handled like nkRecWhen + proc test[x: static bool]( + t: ( + when x: + int + else: + float + ) + ) = discard + test[true](1.int) + test[false](1.0) + doAssert not compiles(test[]) + +block: # `when` in static signature + template ctAnd(a, b): bool = + when a: + when b: true + else: false + else: false + template test(): untyped = + when ctAnd(declared(SharedTable), typeof(result) is SharedTable): + result = SharedTable() + else: + result = 123 + proc foo[T](): T = test() + proc bar[T](x = foo[T]()): T = x + doAssert bar[int]() == 123 + +block: # issue #22276 + type Foo = enum A, B + macro test(y: static[Foo]): untyped = + if y == A: + result = parseExpr("proc (x: int)") + else: + result = parseExpr("proc (x: float)") + proc foo(y: static[Foo], x: test(y)) = # We want to make the type of `x` depend on what `y` is + x(9) + foo(A, proc (x: int) = doAssert x == 9) + var a: int + foo(A, proc (x: int) = + a = x * 2) + doAssert a == 18 + foo(B, proc (x: float) = doAssert x == 9) diff --git a/tests/proc/tunderscoreparam.nim b/tests/proc/tunderscoreparam.nim new file mode 100644 index 000000000..8d60603f1 --- /dev/null +++ b/tests/proc/tunderscoreparam.nim @@ -0,0 +1,122 @@ +discard """ + targets: "c cpp js" +""" + +import std/[assertions, sequtils] + +proc test() = + block: + proc ok(_, _, a: int): int = + doAssert not compiles(_) + a + doassert ok(4, 2, 5) == 5 + + block: + proc ok(_: int, _: int, a: int): int = a + doAssert ok(4, 2, 5) == 5 + + block: + proc ok(_: int, _: float, a: int): int = a + doAssert ok(1, 2.0, 5) == 5 + + block: + proc ok(_: int, _: float, _: string, a: int): int = a + doAssert ok(1, 2.6, "5", 5) == 5 + + block: + proc ok[T](_, _, a: T): T = + doAssert not compiles(_) + a + doAssert ok(4, 2, 5) == 5 + doAssert ok("a", "b", "c") == "c" + doAssert not compiles(ok(1, 2, "a")) + + block: + let ok = proc (_, _, a: int): int = + doAssert not compiles(_) + a + doAssert ok(4, 2, 5) == 5 + + block: + proc foo(lam: proc (_, _, a: int): int): int = + lam(4, 2, 5) + doAssert foo(proc (_, _, a: auto): auto = + doAssert not compiles(_) + a) == 5 + + block: + iterator fn(_, _: int, c: int): int = yield c + doAssert toSeq(fn(1,2,3)) == @[3] + + block: + template ok(_, _, a: int): int = a + doAssert ok(4, 2, 5) == 5 + + block: + doAssert not (compiles do: + template bad(_: int): int = _ + discard bad(3)) + + block: + template ok(_: int, _: int, a: int): int = a + doAssert ok(4, 2, 5) == 5 + + block: + template ok(_: int, _: float, a: int): int = a + doAssert ok(1, 2.0, 5) == 5 + + block: + template ok(_: int, _: float, _: string, a: int): int = a + doAssert ok(1, 2.6, "5", 5) == 5 + + block: + template main2() = + iterator fn(_, _: int, c: int): int = yield c + main2() + + block: + template main = + proc foo(_: int) = + let a = _ + doAssert not compiles(main()) + + block: # generic params + doAssert not (compiles do: + proc foo[_](t: typedesc[_]): seq[_] = @[default(_)] + doAssert foo[int]() == 0) + + block: + proc foo[_, _](): int = 123 + doAssert foo[int, bool]() == 123 + + block: + proc foo[T; U](_: typedesc[T]; _: typedesc[U]): (T, U) = (default(T), default(U)) + doAssert foo(int, bool) == (0, false) + +proc closureTest() = + var x = 0 + + block: + proc foo(_, _: int) = x += 5 + + foo(1, 2) + doAssert x == 5 + + block: + proc foo(_: int, _: float) = x += 5 + + foo(1, 2) + doAssert x == 10 + + block: + proc foo(_: int, _: float, _: string) = x += 5 + + foo(1, 2, "5") + doAssert x == 15 + +static: test() +test() + +when not defined(js): + static: closureTest() +closureTest() diff --git a/tests/proc/twrongdefaultvalue.nim b/tests/proc/twrongdefaultvalue.nim new file mode 100644 index 000000000..2c36c2247 --- /dev/null +++ b/tests/proc/twrongdefaultvalue.nim @@ -0,0 +1,25 @@ +discard """ + cmd: "nim check $file" + action: reject + nimout: ''' +twrongdefaultvalue.nim(20, 12) template/generic instantiation of `doit` from here +twrongdefaultvalue.nim(17, 37) Error: type mismatch: got <proc (p: int): Item[initItem.T]> but expected 'Item[system.string]' +twrongdefaultvalue.nim(25, 3) template/generic instantiation of `foo` from here +twrongdefaultvalue.nim(23, 33) Error: type mismatch: got <string> but expected 'int' +''' +""" + +block: # issue #21258 + type Item[T] = object + pos: int + proc initItem[T](p:int=10000) : Item[T] = + result = Item[T](p) + proc doit[T](x:Item[T], s:Item[T]=initItem) : string = + return $x.pos + let x = Item[string](pos:100) + echo doit(x) + +block: # issue #21258, reduced case + proc foo[T](x: seq[T], y: T = "foo") = + discard + foo @[1, 2, 3] |