Skip to content

Commit

Permalink
templates/macros use no expected types when return types are specified (
Browse files Browse the repository at this point in the history
#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 80e6b35)
  • Loading branch information
ringabout authored and narimiran committed Oct 23, 2024
1 parent d3f7fb3 commit fd9d2f5
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 1 deletion.
2 changes: 1 addition & 1 deletion compiler/sem.nim
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,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[0]))
dec(c.config.evalTemplateCounter)
Expand Down
22 changes: 22 additions & 0 deletions tests/types/ttopdowninference.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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()

0 comments on commit fd9d2f5

Please sign in to comment.