Fix typeSym.getImpl for ref types (#13752)
* Fix typeSym.getImpl for ref types * Fix a codegen issue affecting the test suite of nim-beacon-chain * Fix tests/stdlib/tjsonmacro To understand the fix better it may help to take a look at the history of the replaced code. The nil check that is removed in this commit was introduced in another fix that failed to identify the root cause of the issue - namely that we allow an object type to exist for which no ast is present: https://github.com/nim-lang/Nim/pull/9601/files The original intention of the code is more obvious here: https://github.com/nim-lang/Nim/pull/9538/files
This commit is contained in:
parent
1b31e08917
commit
e50441ab33
4 changed files with 88 additions and 8 deletions
|
|
@ -2950,7 +2950,7 @@ proc genBracedInit(p: BProc, n: PNode; isConst: bool): Rope =
|
||||||
else:
|
else:
|
||||||
internalError(p.config, n.info, "node has no type")
|
internalError(p.config, n.info, "node has no type")
|
||||||
else:
|
else:
|
||||||
ty = skipTypes(n.typ, abstractInstOwned).kind
|
ty = skipTypes(n.typ, abstractInstOwned + {tyStatic}).kind
|
||||||
case ty
|
case ty
|
||||||
of tySet:
|
of tySet:
|
||||||
var cs: TBitSet
|
var cs: TBitSet
|
||||||
|
|
|
||||||
|
|
@ -1279,12 +1279,12 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
|
||||||
incl st.flags, tfRefsAnonObj
|
incl st.flags, tfRefsAnonObj
|
||||||
let obj = newSym(skType, getIdent(c.cache, s.name.s & ":ObjectType"),
|
let obj = newSym(skType, getIdent(c.cache, s.name.s & ":ObjectType"),
|
||||||
getCurrOwner(c), s.info)
|
getCurrOwner(c), s.info)
|
||||||
|
obj.ast = a
|
||||||
if sfPure in s.flags:
|
if sfPure in s.flags:
|
||||||
obj.flags.incl sfPure
|
obj.flags.incl sfPure
|
||||||
obj.typ = st.lastSon
|
obj.typ = st.lastSon
|
||||||
st.lastSon.sym = obj
|
st.lastSon.sym = obj
|
||||||
|
|
||||||
|
|
||||||
proc checkForMetaFields(c: PContext; n: PNode) =
|
proc checkForMetaFields(c: PContext; n: PNode) =
|
||||||
proc checkMeta(c: PContext; n: PNode; t: PType) =
|
proc checkMeta(c: PContext; n: PNode; t: PType) =
|
||||||
if t != nil and t.isMetaType and tfGenericTypeParam notin t.flags:
|
if t != nil and t.isMetaType and tfGenericTypeParam notin t.flags:
|
||||||
|
|
|
||||||
|
|
@ -159,10 +159,10 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo;
|
||||||
of tyObject:
|
of tyObject:
|
||||||
if inst:
|
if inst:
|
||||||
result = newNodeX(nkObjectTy)
|
result = newNodeX(nkObjectTy)
|
||||||
if t.sym.ast != nil:
|
var objectDef = t.sym.ast[2]
|
||||||
result.add t.sym.ast[2][0].copyTree # copy object pragmas
|
if objectDef.kind == nkRefTy:
|
||||||
else:
|
objectDef = objectDef[0]
|
||||||
result.add newNodeI(nkEmpty, info)
|
result.add objectDef[0].copyTree # copy object pragmas
|
||||||
if t[0] == nil:
|
if t[0] == nil:
|
||||||
result.add newNodeI(nkEmpty, info)
|
result.add newNodeI(nkEmpty, info)
|
||||||
else: # handle parent object
|
else: # handle parent object
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,40 @@ void; ntyVoid; void; void
|
||||||
int; ntyInt; int; int
|
int; ntyInt; int; int
|
||||||
proc (); ntyProc; proc[void]; proc ()
|
proc (); ntyProc; proc[void]; proc ()
|
||||||
voidProc; ntyProc; proc[void]; proc ()
|
voidProc; ntyProc; proc[void]; proc ()
|
||||||
|
listing fields for ObjType
|
||||||
|
a: string
|
||||||
|
b: int
|
||||||
|
listing fields for ObjRef
|
||||||
|
skipping ref type
|
||||||
|
a: string
|
||||||
|
b: int
|
||||||
|
listing fields for RefType
|
||||||
|
skipping ref type
|
||||||
|
a: int
|
||||||
|
b: float
|
||||||
|
listing fields for typeof(a)
|
||||||
|
skipping ref type
|
||||||
|
a: string
|
||||||
|
b: int
|
||||||
|
listing fields for typeof(b)
|
||||||
|
skipping ref type
|
||||||
|
a: string
|
||||||
|
b: int
|
||||||
|
listing fields for typeof(c)
|
||||||
|
skipping ref type
|
||||||
|
a: int
|
||||||
|
b: float
|
||||||
|
listing fields for typeof(x)
|
||||||
|
a: string
|
||||||
|
b: int
|
||||||
|
listing fields for typeof(x)
|
||||||
|
a: int
|
||||||
|
b: float
|
||||||
typeDesc[range[1 .. 5]]; ntyTypeDesc; typeDesc[range[1, 5]]; typeDesc[range[1 .. 5]]
|
typeDesc[range[1 .. 5]]; ntyTypeDesc; typeDesc[range[1, 5]]; typeDesc[range[1 .. 5]]
|
||||||
typeDesc[range]; ntyTypeDesc; typeDesc[range[T]]; typeDesc[range]'''
|
typeDesc[range]; ntyTypeDesc; typeDesc[range[T]]; typeDesc[range]'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import macros
|
import macros, typetraits
|
||||||
|
|
||||||
macro checkType(ex: typed): untyped =
|
macro checkType(ex: typed): untyped =
|
||||||
echo ex.getTypeInst.repr, "; ", ex.typeKind, "; ", ex.getType.repr, "; ", ex.getTypeImpl.repr
|
echo ex.getTypeInst.repr, "; ", ex.typeKind, "; ", ex.getType.repr, "; ", ex.getTypeImpl.repr
|
||||||
|
|
@ -17,7 +46,6 @@ macro checkProcType(fn: typed): untyped =
|
||||||
let fn_sym = if fn.kind == nnkProcDef: fn[0] else: fn
|
let fn_sym = if fn.kind == nnkProcDef: fn[0] else: fn
|
||||||
echo fn_sym, "; ", fn_sym.typeKind, "; ", fn_sym.getType.repr, "; ", fn_sym.getTypeImpl.repr
|
echo fn_sym, "; ", fn_sym.typeKind, "; ", fn_sym.getType.repr, "; ", fn_sym.getTypeImpl.repr
|
||||||
|
|
||||||
|
|
||||||
proc voidProc = echo "hello"
|
proc voidProc = echo "hello"
|
||||||
proc intProc(a: int, b: float): int {.checkProcType.} = 10
|
proc intProc(a: int, b: float): int {.checkProcType.} = 10
|
||||||
|
|
||||||
|
|
@ -26,6 +54,58 @@ checkType(intProc(10, 20.0))
|
||||||
checkType(voidProc)
|
checkType(voidProc)
|
||||||
checkProcType(voidProc)
|
checkProcType(voidProc)
|
||||||
|
|
||||||
|
macro listFields(T: typed) =
|
||||||
|
echo "listing fields for ", repr(T)
|
||||||
|
let inputExprType = getType(T)
|
||||||
|
|
||||||
|
var objType = inputExprType[1]
|
||||||
|
if objType.kind == nnkBracketExpr and objType.len > 1:
|
||||||
|
if ((objType[0].kind == nnkRefTy) or
|
||||||
|
(objType[0].kind == nnkSym and eqIdent(objType[0], "ref"))):
|
||||||
|
echo "skipping ref type"
|
||||||
|
objType = objType[1]
|
||||||
|
|
||||||
|
let typeAst = objType.getImpl
|
||||||
|
|
||||||
|
var objectDef = typeAst[2]
|
||||||
|
if objectDef.kind == nnkRefTy:
|
||||||
|
objectDef = objectDef[0]
|
||||||
|
|
||||||
|
let recList = objectDef[2]
|
||||||
|
for rec in recList:
|
||||||
|
echo $rec[0], ": ", $rec[1]
|
||||||
|
|
||||||
|
type
|
||||||
|
ObjType* = object of RootObj
|
||||||
|
a: string
|
||||||
|
b: int
|
||||||
|
|
||||||
|
ObjRef = ref ObjType
|
||||||
|
|
||||||
|
RefType* = ref object of RootObj
|
||||||
|
a: int
|
||||||
|
b: float
|
||||||
|
|
||||||
|
listFields ObjType
|
||||||
|
listFields ObjRef
|
||||||
|
listFields RefType
|
||||||
|
|
||||||
|
let
|
||||||
|
a = new ObjType
|
||||||
|
b = new ObjRef
|
||||||
|
c = new RefType
|
||||||
|
|
||||||
|
listFields typeOf(a)
|
||||||
|
listFields typeOf(b)
|
||||||
|
listFields typeOf(c)
|
||||||
|
|
||||||
|
proc genericProc(x: object) =
|
||||||
|
listFields typeOf(x)
|
||||||
|
|
||||||
|
genericProc a[]
|
||||||
|
genericProc b[]
|
||||||
|
genericProc c[]
|
||||||
|
|
||||||
# bug #10548
|
# bug #10548
|
||||||
block:
|
block:
|
||||||
var c {.compileTime.} = 0
|
var c {.compileTime.} = 0
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue