From 41145210a83fe54345e1acf748faf9c920f85442 Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Mon, 14 Oct 2024 01:54:30 +0800 Subject: [PATCH] templates/macros use no expected types when return types are specified (#24298) fixes #24296 fixes #24295 Templates use `expectedType` for type inference. It's justified that when templates don't have an actual return type, i.e., `untyped` etc. When the return type of templates is specified, we should not infer the type ```nim template g(): string = "" let c: cstring = g() ``` In this example, it is not reasonable to annotate the templates expression with the `cstring` type before the `fitNode` check with its specified return type. (cherry picked from commit 80e6b357216cdc3f320e57cf6e11c4a738bb9159) --- compiler/sem.nim | 2 +- tests/types/ttopdowninference.nim | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/compiler/sem.nim b/compiler/sem.nim index 699bcbb948..1866d85fcb 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -494,7 +494,7 @@ proc semAfterMacroCall(c: PContext, call, macroResult: PNode, if retType.kind == tyVoid: result = semStmt(c, result, flags) else: - result = semExpr(c, result, flags, expectedType) + result = semExpr(c, result, flags) result = fitNode(c, retType, result, result.info) #globalError(s.info, errInvalidParamKindX, typeToString(s.typ.returnType)) dec(c.config.evalTemplateCounter) diff --git a/tests/types/ttopdowninference.nim b/tests/types/ttopdowninference.nim index 765761e993..303effdf7b 100644 --- a/tests/types/ttopdowninference.nim +++ b/tests/types/ttopdowninference.nim @@ -331,3 +331,25 @@ block: # issue #24164, related regression template bar(x: untyped = nil) = foo(x) bar() + +block: # bug #24296 + # Either changing the template to `proc`/`func` or using `$""`, not a string + # literal alone, allows any version of Nim 2.x to compile this. + template g(): string = "" + + # Alternatively: don't retrieve the string through g(), but directly, also + # allows compilation across Nim 2.x versions. + const d: cstring = "" + const f: cstring = $"" + const b = cstring g() + const m = cstring "" + const p = cstring $"" + + # But this does not compile across Nim 2.x/devel. + const c: cstring = g() + let e: cstring = g() + +block: # bug #24295 + template g(_: int): string = "" + const c: cstring = 0.g() +