fixes #21377; fixes @[] and {} type inference as returns in generics (#21475)

* fixes `@[]` type inference in generics

* add issue links

* fixes macros and iterators

* refactor

* add one more test

(cherry picked from commit 64a0355f3f)
This commit is contained in:
ringabout
2023-03-06 22:30:22 +08:00
committed by narimiran
parent c5d1dc5f69
commit 770a3889fd
4 changed files with 51 additions and 5 deletions

View File

@@ -973,7 +973,7 @@ proc afterCallActions(c: PContext; n, orig: PNode, flags: TExprFlags; expectedTy
fixAbstractType(c, result)
analyseIfAddressTakenInCall(c, result)
if callee.magic != mNone:
result = magicsAfterOverloadResolution(c, result, flags)
result = magicsAfterOverloadResolution(c, result, flags, expectedType)
when false:
if result.typ != nil and
not (result.typ.kind == tySequence and result.typ[0].kind == tyEmpty):

View File

@@ -146,11 +146,18 @@ proc instantiateBody(c: PContext, n, params: PNode, result, orig: PSym) =
if sfGenSym in param.flags:
idTablePut(symMap, params[i].sym, result.typ.n[param.position+1].sym)
freshGenSyms(c, b, result, orig, symMap)
if sfBorrow notin orig.flags:
# We do not want to generate a body for generic borrowed procs.
# As body is a sym to the borrowed proc.
b = semProcBody(c, b)
let resultType = # todo probably refactor it into a function
if result.kind == skMacro:
sysTypeFromName(c.graph, n.info, "NimNode")
elif not isInlineIterator(result.typ):
result.typ[0]
else:
nil
b = semProcBody(c, b, resultType)
result.ast[bodyPos] = hloBody(c, b)
excl(result.flags, sfForward)
trackProc(c, result, result.ast[bodyPos])

View File

@@ -460,7 +460,7 @@ proc semPrivateAccess(c: PContext, n: PNode): PNode =
result = newNodeIT(nkEmpty, n.info, getSysType(c.graph, n.info, tyVoid))
proc magicsAfterOverloadResolution(c: PContext, n: PNode,
flags: TExprFlags): PNode =
flags: TExprFlags; expectedType: PType = nil): PNode =
## This is the preferred code point to implement magics.
## ``c`` the current module, a symbol table to a very good approximation
## ``n`` the ast like it would be passed to a real macro
@@ -583,5 +583,9 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
result = n
of mPrivateAccess:
result = semPrivateAccess(c, n)
of mArrToSeq:
result = n
if result.typ != nil and expectedType != nil and result.typ.kind == tySequence and expectedType.kind == tySequence and result.typ[0].kind == tyEmpty:
result.typ = expectedType # type inference for empty sequence # bug #21377
else:
result = n

View File

@@ -245,7 +245,7 @@ block: # bug #11777
var s: S = {1, 2}
doAssert 1 in s
block: # regression #20807
block: # bug #20807
var s: seq[string]
template fail =
s = @[]
@@ -255,3 +255,38 @@ block: # regression #20807
test: fail()
doAssert not (compiles do:
let x: seq[int] = `@`[string]([]))
block: # bug #21377
proc b[T](v: T): seq[int] =
let x = 0
@[]
doAssert b(0) == @[]
block: # bug #21377
proc b[T](v: T): seq[T] =
let x = 0
@[]
doAssert b(0) == @[]
block: # bug #21377
proc b[T](v: T): set[bool] =
let x = 0
{}
doAssert b(0) == {}
block: # bug #21377
proc b[T](v: T): array[0, int] =
let x = 0
[]
doAssert b(0) == []
block: # bug #21377
proc b[T](v: T): array[0, (string, string)] =
let x = 0
{:}
doAssert b(0) == {:}