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.
This commit is contained in:
ringabout
2024-10-14 01:54:30 +08:00
committed by GitHub
parent 71515bf278
commit 80e6b35721
2 changed files with 23 additions and 1 deletions

View File

@@ -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)

View File

@@ -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()