diff options
-rw-r--r-- | compiler/ccgexprs.nim | 3 | ||||
-rw-r--r-- | compiler/ccgtrav.nim | 11 | ||||
-rw-r--r-- | compiler/ccgtypes.nim | 11 | ||||
-rw-r--r-- | compiler/cgen.nim | 2 | ||||
-rw-r--r-- | compiler/sighashes.nim | 6 |
5 files changed, 25 insertions, 8 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index ad88e9750..f8b0ac6cf 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -744,6 +744,7 @@ proc genRecordField(p: BProc, e: PNode, d: var TLoc) = putIntoDest(p, d, f.typ, r, a.s) else: let field = lookupFieldAgain(p, ty, f, r) + if field.loc.r == nil: fillObjectFields(p.module, ty) if field.loc.r == nil: internalError(e.info, "genRecordField 3 " & typeToString(ty)) addf(r, ".$1", [field.loc.r]) putIntoDest(p, d, field.typ, r, a.s) @@ -792,6 +793,7 @@ proc genCheckedRecordField(p: BProc, e: PNode, d: var TLoc) = var r = rdLoc(a) let f = e.sons[0].sons[1].sym let field = lookupFieldAgain(p, ty, f, r) + if field.loc.r == nil: fillObjectFields(p.module, ty) if field.loc.r == nil: internalError(e.info, "genCheckedRecordField") # generate the checks: genFieldCheck(p, e, r, field, ty) @@ -1156,6 +1158,7 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) = var tmp2: TLoc tmp2.r = r let field = lookupFieldAgain(p, ty, it.sons[0].sym, tmp2.r) + if field.loc.r == nil: fillObjectFields(p.module, ty) if field.loc.r == nil: internalError(e.info, "genObjConstr") if it.len == 3 and optFieldCheck in p.options: genFieldCheck(p, it.sons[2], r, field, ty) diff --git a/compiler/ccgtrav.nim b/compiler/ccgtrav.nim index 052f2ccbd..731dc55a0 100644 --- a/compiler/ccgtrav.nim +++ b/compiler/ccgtrav.nim @@ -21,12 +21,13 @@ proc genTraverseProc(c: var TTraversalClosure, accessor: Rope, typ: PType) proc genCaseRange(p: BProc, branch: PNode) proc getTemp(p: BProc, t: PType, result: var TLoc; needsInit=false) -proc genTraverseProc(c: var TTraversalClosure, accessor: Rope, n: PNode) = +proc genTraverseProc(c: var TTraversalClosure, accessor: Rope, n: PNode; + typ: PType) = if n == nil: return case n.kind of nkRecList: for i in countup(0, sonsLen(n) - 1): - genTraverseProc(c, accessor, n.sons[i]) + genTraverseProc(c, accessor, n.sons[i], typ) of nkRecCase: if (n.sons[0].kind != nkSym): internalError(n.info, "genTraverseProc") var p = c.p @@ -39,11 +40,13 @@ proc genTraverseProc(c: var TTraversalClosure, accessor: Rope, n: PNode) = genCaseRange(c.p, branch) else: lineF(p, cpsStmts, "default:$n", []) - genTraverseProc(c, accessor, lastSon(branch)) + genTraverseProc(c, accessor, lastSon(branch), typ) lineF(p, cpsStmts, "break;$n", []) lineF(p, cpsStmts, "} $n", []) of nkSym: let field = n.sym + if field.typ.kind == tyVoid: return + if field.loc.r == nil: fillObjectFields(c.p.module, typ) if field.loc.t == nil: internalError(n.info, "genTraverseProc()") genTraverseProc(c, "$1.$2" % [accessor, field.loc.r], field.loc.t) @@ -75,7 +78,7 @@ proc genTraverseProc(c: var TTraversalClosure, accessor: Rope, typ: PType) = var x = typ.sons[i] if x != nil: x = x.skipTypes(skipPtrs) genTraverseProc(c, accessor.parentObj(c.p.module), x) - if typ.n != nil: genTraverseProc(c, accessor, typ.n) + if typ.n != nil: genTraverseProc(c, accessor, typ.n, typ) of tyTuple: let typ = getUniqueType(typ) for i in countup(0, sonsLen(typ) - 1): diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 82d655eac..822d69150 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -466,6 +466,12 @@ proc genRecordFieldsAux(m: BModule, n: PNode, proc getRecordFields(m: BModule, typ: PType, check: var IntSet): Rope = result = genRecordFieldsAux(m, typ.n, nil, typ, check) +proc fillObjectFields*(m: BModule; typ: PType) = + # sometimes generic objects are not consistently merged. We patch over + # this fact here. + var check = initIntSet() + discard getRecordFields(m, typ, check) + proc getRecordDesc(m: BModule, typ: PType, name: Rope, check: var IntSet): Rope = # declare the record: @@ -725,11 +731,11 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope = result = getTypeName(m, origTyp, sig) m.forwTypeCache[sig] = result if not isImportedType(t): - addf(m.s[cfsForwardTypes], "/* tyObject: $1 $2 $3 */", [rope typeToString t, + addf(m.s[cfsForwardTypes], "/* tyObject: $1 $2 $3 */", [rope typeToString origTyp, rope t.id, rope m.module.id]) addf(m.s[cfsForwardTypes], getForwardStructFormat(m), [structOrUnion(t), result]) - doAssert m.forwTypeCache[sig] == result + assert m.forwTypeCache[sig] == result m.typeCache[sig] = result # always call for sideeffects: let recdesc = if t.kind != tyTuple: getRecordDesc(m, t, result, check) else: getTupleDesc(m, t, result, check) @@ -752,6 +758,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope = excl(check, t.id) proc getTypeDesc(m: BModule, typ: PType): Rope = + echo "getTypeDesc called!" var check = initIntSet() result = getTypeDescAux(m, typ, check) diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 526a7b590..db7070941 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -361,7 +361,7 @@ proc localVarDecl(p: BProc; s: PSym): Rope = if s.loc.k == locNone: fillLoc(s.loc, locLocalVar, s.typ, mangleName(p.module, s), OnStack) if s.kind == skLet: incl(s.loc.flags, lfNoDeepCopy) - result = getTypeDesc(p.module, s.loc.t) + result = getTypeDesc(p.module, s.typ) if s.constraint.isNil: if sfRegister in s.flags: add(result, " register") #elif skipTypes(s.typ, abstractInst).kind in GcTypeKinds: diff --git a/compiler/sighashes.nim b/compiler/sighashes.nim index 178023fcb..a2d67ea24 100644 --- a/compiler/sighashes.nim +++ b/compiler/sighashes.nim @@ -13,7 +13,7 @@ import ast, md5 from hashes import Hash from astalgo import debug from types import typeToString -from strutils import startsWith +from strutils import startsWith, contains when false: type @@ -159,6 +159,10 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) = # Every cyclic type in Nim need to be constructed via some 't.sym', so this # is actually safe without an infinite recursion check: if t.sym != nil: + if "Future:" in t.sym.name.s: + writeStackTrace() + echo "yes ", t.sym.name.s + #quit 1 c.hashSym(t.sym) else: lowlevel(t.id) |