From 9d65507d202afcfdf9421fc1e2c9cba3325059ba Mon Sep 17 00:00:00 2001 From: metagn Date: Mon, 23 Sep 2024 18:18:22 +0300 Subject: [PATCH] fix `nil` literal giving itself type `untyped`/`typed` [backport] (#24165) fixes #24164, regression from #20091 The expression `nil` as the default value of template parameter `x: untyped` is typechecked with expected type `untyped` since #20091. The expected type is checked if it matches the `nil` literal with a match better than a subtype match, and the type is set to it if it does. However `untyped` matches with a generic match which is better, so the `nil` literal has type `untyped`. This breaks type matching for the literal. So if the expected type is `untyped` or `typed`, it is now ignored and the `nil` literal just has the `nil` type. (cherry picked from commit b9de2bb4f3864d264c3aeffdc630227448ad8c14) --- compiler/semexprs.nim | 2 +- tests/types/ttopdowninference.nim | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 82ef27a191d38..3b081b827e22b 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -3231,7 +3231,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}, expectedType: PType of nkNilLit: if result.typ == nil: result.typ = getNilType(c) - if expectedType != nil: + if expectedType != nil and expectedType.kind notin {tyUntyped, tyTyped}: var m = newCandidate(c, result.typ) if typeRel(m, expectedType, result.typ) >= isSubtype: result.typ = expectedType diff --git a/tests/types/ttopdowninference.nim b/tests/types/ttopdowninference.nim index 2a26e0e34e09d..765761e993ffd 100644 --- a/tests/types/ttopdowninference.nim +++ b/tests/types/ttopdowninference.nim @@ -325,3 +325,9 @@ block: # bug #22180 else: (ref A)(nil) doAssert y.isNil + +block: # issue #24164, related regression + proc foo(x: proc ()) = discard + template bar(x: untyped = nil) = + foo(x) + bar()