From 7679d4acdb80b072d32b09a849968082b7d8dd3a Mon Sep 17 00:00:00 2001 From: metagn Date: Sun, 29 Sep 2024 01:35:00 +0300 Subject: [PATCH] fix arraymancer, enable static conversions refs (fixes) #7611, #12559, #16969, #17423 but not #23343 --- compiler/evaltempl.nim | 6 ++- compiler/sigmatch.nim | 3 +- tests/proc/tdefaultvaluestatic.nim | 11 +++++ tests/statictypes/tparamconv.nim | 70 ++++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 tests/statictypes/tparamconv.nim diff --git a/compiler/evaltempl.nim b/compiler/evaltempl.nim index 77c136d632f8..a9ac24a709e3 100644 --- a/compiler/evaltempl.nim +++ b/compiler/evaltempl.nim @@ -143,7 +143,11 @@ proc evalTemplateArgs(n: PNode, s: PSym; conf: ConfigRef; fromHlo: bool): PNode result = newNodeI(nkArgList, n.info) for i in 1..givenRegularParams: - result.add n[i] + let arg = n[i] + if arg.typ != nil and arg.typ.kind == tyStatic and arg.typ.n != nil: + result.add arg.typ.n + else: + result.add arg # handle parameters with default values, which were # not supplied by the user diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index ece405a9e24f..bf529099764a 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -2029,6 +2029,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, result = isGeneric if result != isNone: put(c, f, aOrig) elif aOrig.n != nil and aOrig.n.typ != nil: + # XXX this should use paramTypesMatch result = if f.base.kind != tyNone: typeRel(c, f.last, aOrig.n.typ, flags) else: isGeneric @@ -2328,7 +2329,7 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType, elif arg.kind != nkEmpty: var evaluated = c.semTryConstExpr(c, arg) if evaluated != nil: - if false and f.kind == tyStatic: + if f.kind == tyStatic: let converted = paramTypesMatch(m, f.base, evaluated.typ, evaluated, argOrig) # if for some reason `evaluated` doesn't match `f.base`: if converted == nil: return nil diff --git a/tests/proc/tdefaultvaluestatic.nim b/tests/proc/tdefaultvaluestatic.nim index 10d9a430ce9a..5ca341d28974 100644 --- a/tests/proc/tdefaultvaluestatic.nim +++ b/tests/proc/tdefaultvaluestatic.nim @@ -32,3 +32,14 @@ block: doAssert foo(true) == "a" doAssert foo(false) == "b" doAssert foo() == "b" + +block: + proc foo(x: uint) = discard + proc bar(x: static int = 123) = + foo(x) + bar(123) + bar() + template baz(x: static int = 123) = + foo(x) + baz(123) + baz() diff --git a/tests/statictypes/tparamconv.nim b/tests/statictypes/tparamconv.nim new file mode 100644 index 000000000000..7f4d3eb8c545 --- /dev/null +++ b/tests/statictypes/tparamconv.nim @@ -0,0 +1,70 @@ +# test that static conversions work + +block: # issue #12559 + type T = ref object + x: int + proc f(arg: static T) = + static: + assert arg == nil or arg.x > 0 + discard arg.x + f nil + +block: # issue #16969 + proc foo(n: static[1..50]) = discard + + foo(1) + doAssert not compiles(foo(0)) + doAssert not compiles(foo(999)) + +block: # issue #7611 + type Foo[N: static[int8]] = object + + proc `$`[N: static[int8]](f: Foo[N]): string = + "Success" + + let a = Foo[10]() + doAssert $a == "Success" + +block: # issue #17423 + type NaturalArray[N: static[Natural]] = array[N, int] + + doAssert not (compiles do: + var a: NaturalArray[-1000]) + +block: # test from https://github.com/nim-works/nimskull/pull/1433 + proc foo(x: static pointer): pointer = x + proc foo(x: static array[0, int]): array[0, int] = x + proc foo(x: static seq[int]): seq[int] = x + proc foo(x: static set[char]): set[char] = x + + # simple case: empty-container typed expression is passed directly + doAssert foo(nil) == nil + doAssert foo([]) == [] + doAssert foo(@[]) == @[] + doAssert foo({}) == {} + +block: # generic version + proc foo[T](x: static[ptr T]): ptr T = x + proc foo[T](x: static array[0, T]): array[0, T] = x + proc foo[T](x: static seq[T]): seq[T] = x + proc foo[T](x: static set[T]): set[T] = x + doAssert foo[int8](nil) == nil + doAssert foo[int8]([]) == [] + doAssert foo[int8](@[]) == @[] + doAssert foo[int8]({}) == {} + +converter toInt(x: float): int = int(x) +block: # converter + proc test(x: static int) = + doAssert x == 1 + test(1.5) + +block: # subtype + type + A = ref object of RootObj + B = ref object of A + + proc test(x: static A) = discard + test(B()) + +# proc explicit generic params don't work yet because typeRel doesn't use paramTypesMatch, #23343