summary refs log tree commit diff stats
diff options
context:
space:
mode:
authormetagn <metagngn@gmail.com>2024-09-19 08:20:29 +0300
committerGitHub <noreply@github.com>2024-09-19 07:20:29 +0200
commit05a7a48a2bcc21c772bd35703fa52e374d25febe (patch)
tree6b02418bd9e9751b771ef7402d449ad6b35e1ded
parent84f5060e9478d1f627aadc1ff90228dc2f297028 (diff)
downloadNim-05a7a48a2bcc21c772bd35703fa52e374d25febe.tar.gz
fix inverted order of resolved `tyFromExpr` match (#24138)
fixes #22276

When matching against `tyFromExpr`, the compiler tries to instantiate it
then operates on the potentially instantiated type. But the way it does
this is inverted, it checks if the instantiated type matches the
argument type, not if the argument type matches the instantiated type.
This has been the case since
https://github.com/nim-lang/Nim/commit/ac271e76b18110bea8046af64ceccd6b804978dd#diff-251afcd01d239369019495096c187998dd6695b6457528953237a7e4a10f7138,
which doesn't comment on it, so I'm guessing this isn't intended. I
don't know if it would break anything though.
-rw-r--r--compiler/sigmatch.nim6
-rw-r--r--tests/proc/tstaticsignature.nim16
2 files changed, 19 insertions, 3 deletions
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 873eefd76..96cbc6359 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -2113,15 +2113,15 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
       # not resolved
       result = isNone
     of tyTypeDesc:
-      result = typeRel(c, a, reevaluated.base, flags)
+      result = typeRel(c, reevaluated.base, a, flags)
     of tyStatic:
-      result = typeRel(c, a, reevaluated.base, flags)
+      result = typeRel(c, reevaluated.base, a, flags)
       if result != isNone and reevaluated.n != nil:
         if not exprStructuralEquivalent(aOrig.n, reevaluated.n):
           result = isNone
     else:
       # bug #14136: other types are just like 'tyStatic' here:
-      result = typeRel(c, a, reevaluated, flags)
+      result = typeRel(c, reevaluated, a, flags)
       if result != isNone and reevaluated.n != nil:
         if not exprStructuralEquivalent(aOrig.n, reevaluated.n):
           result = isNone
diff --git a/tests/proc/tstaticsignature.nim b/tests/proc/tstaticsignature.nim
index 518c88ba5..25aa09c5d 100644
--- a/tests/proc/tstaticsignature.nim
+++ b/tests/proc/tstaticsignature.nim
@@ -250,3 +250,19 @@ block: # `when` in static signature
   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)