combine PR#16009 and PR#16012 (#16024)

* fix #15623
* add testcase for #15623
* add testcase
* combine #16009
* support casting nil to NilableTypes in VM
This commit is contained in:
flywind
2020-11-18 15:28:05 +08:00
committed by GitHub
parent 0869d2a477
commit e6e1e9574d
3 changed files with 50 additions and 1 deletions

View File

@@ -674,7 +674,7 @@ proc getConstExpr(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode
of nkCast:
var a = getConstExpr(m, n[1], idgen, g)
if a == nil: return
if n.typ != nil and n.typ.kind in NilableTypes:
if n.typ != nil and n.typ.kind in NilableTypes and a.kind != nkNilLit:
# we allow compile-time 'cast' for pointer types:
result = a
result.typ = n.typ

View File

@@ -901,6 +901,11 @@ proc genCastIntFloat(c: PCtx; n: PNode; dest: var TDest) =
c.gABx(n, opcSetType, dest, c.genType(dst))
c.gABC(n, opcCastIntToPtr, dest, tmp)
c.freeTemp(tmp)
elif src.kind == tyNil and dst.kind in NilableTypes:
# supports casting nil literals to NilableTypes in VM
# see #16024
if dest < 0: dest = c.getTemp(n[0].typ)
genLit(c, n[1], dest)
else:
# todo: support cast from tyInt to tyRef
globalError(c.config, n.info, "VM does not support 'cast' from " & $src.kind & " to " & $dst.kind)

View File

@@ -29,3 +29,47 @@ reject: discard cast[enum](0)
proc a = echo "hi"
reject: discard cast[ptr](a)
# bug #15623
block:
if false:
echo cast[ptr int](nil)[]
block:
if false:
var x: ref int = nil
echo cast[ptr int](x)[]
block:
doAssert cast[int](cast[ptr int](nil)) == 0
block:
var x: ref int = nil
doAssert cast[int](cast[ptr int](x)) == 0
block:
block:
static:
let a = cast[pointer](nil)
doAssert a.repr == "nil"
block:
static:
doAssert cast[ptr int](nil).repr == "nil"
block:
const str = cast[ptr int](nil)
static:
doAssert str.repr == "nil"
block:
static:
doAssert cast[ptr int](nil).repr == "nil"
block:
static:
doAssert cast[RootRef](nil).repr == "nil"
block:
static:
doAssert cast[cstring](nil).repr == "nil"