diff options
author | metagn <metagngn@gmail.com> | 2024-09-13 12:08:22 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-13 11:08:22 +0200 |
commit | 61e04ba0ed4b8c6567f4cfd5c48c2c2439c62371 (patch) | |
tree | bb7628b388a52c676f1b66bad611a2b72465c861 /tests | |
parent | 793cee4de1934fd1f6271cf5fed46f01c5abb19b (diff) | |
download | Nim-61e04ba0ed4b8c6567f4cfd5c48c2c2439c62371.tar.gz |
fix calls to untyped arbitrary expressions in generics (#24100)
fixes #24099 If an arbitrary expression without a proc type (in this case `tyFromExpr`) is called, the compiler [passes it to overload resolution](https://github.com/nim-lang/Nim/blob/793cee4de1934fd1f6271cf5fed46f01c5abb19b/compiler/semexprs.nim#L1223). But overload resolution also can't handle arbitrary expressions and treats them as not participating at all, matching with the state `csEmpty`. The compiler checks for this and gives an "identifier expected" error. Instead, now if we are in a generic context and an arbitrary expression call matched with `csEmpty`, we now return `csNoMatch` so that `semResolvedCall` can leave it untyped as appropriate. The expression flag `efNoDiagnostics` is replaced with this check. It's not checked anywhere else and the only place that uses it is `handleCaseStmtMacro`. Replacing it with `efNoUndeclared`, we just get `csEmpty` instead of `csNoMatch`, which is handled the same way here. So `efNoDiagnostics` is now removed and `efNoUndeclared` is used instead.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/proc/tgenericdefaultparam.nim | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/tests/proc/tgenericdefaultparam.nim b/tests/proc/tgenericdefaultparam.nim index f8e08e409..7f553ab37 100644 --- a/tests/proc/tgenericdefaultparam.nim +++ b/tests/proc/tgenericdefaultparam.nim @@ -20,3 +20,50 @@ block: # issue #20916 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]) |