From 05a7a48a2bcc21c772bd35703fa52e374d25febe Mon Sep 17 00:00:00 2001 From: metagn Date: Thu, 19 Sep 2024 08:20:29 +0300 Subject: 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. --- compiler/sigmatch.nim | 6 +++--- tests/proc/tstaticsignature.nim | 16 ++++++++++++++++ 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) -- cgit 1.4.1-2-gfad0