diff options
-rwxr-xr-x | compiler/ccgexprs.nim | 36 | ||||
-rwxr-xr-x | compiler/ccgstmts.nim | 2 | ||||
-rwxr-xr-x | compiler/ccgtypes.nim | 9 | ||||
-rwxr-xr-x | compiler/ccgutils.nim | 9 | ||||
-rwxr-xr-x | compiler/types.nim | 8 |
5 files changed, 39 insertions, 25 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 34418f353..dbe528ab5 100755 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -283,7 +283,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = proc expr(p: BProc, e: PNode, d: var TLoc) proc initLocExpr(p: BProc, e: PNode, result: var TLoc) = - initLoc(result, locNone, getUniqueType(e.typ), OnUnknown) + initLoc(result, locNone, e.typ, OnUnknown) expr(p, e, result) proc getDestLoc(p: BProc, d: var TLoc, typ: PType) = @@ -543,17 +543,17 @@ proc genAddr(p: BProc, e: PNode, d: var TLoc) = proc genRecordFieldAux(p: BProc, e: PNode, d, a: var TLoc): PType = initLocExpr(p, e.sons[0], a) - if (e.sons[1].kind != nkSym): InternalError(e.info, "genRecordFieldAux") + if e.sons[1].kind != nkSym: InternalError(e.info, "genRecordFieldAux") if d.k == locNone: d.s = a.s discard getTypeDesc(p.module, a.t) # fill the record's fields.loc - result = getUniqueType(a.t) + result = a.t proc genRecordField(p: BProc, e: PNode, d: var TLoc) = var a: TLoc var ty = genRecordFieldAux(p, e, d, a) var r = rdLoc(a) var f = e.sons[1].sym - if ty.n == nil: + if ty.kind == tyTuple: # we found a unique tuple type which lacks field information # so we use Field$i appf(r, ".Field$1", [toRope(f.position)]) @@ -561,14 +561,14 @@ proc genRecordField(p: BProc, e: PNode, d: var TLoc) = else: var field: PSym = nil while ty != nil: - if not (ty.kind in {tyTuple, tyObject}): + if ty.kind notin {tyTuple, tyObject}: InternalError(e.info, "genRecordField") field = lookupInRecord(ty.n, f.name) if field != nil: break if gCmd != cmdCompileToCpp: app(r, ".Sup") ty = GetUniqueType(ty.sons[0]) - if field == nil: InternalError(e.info, "genRecordField") - if field.loc.r == nil: InternalError(e.info, "genRecordField") + if field == nil: InternalError(e.info, "genRecordField 2 ") + if field.loc.r == nil: InternalError(e.info, "genRecordField 3") appf(r, ".$1", [field.loc.r]) putIntoDest(p, d, field.typ, r) @@ -579,16 +579,17 @@ proc genTupleElem(p: BProc, e: PNode, d: var TLoc) = initLocExpr(p, e.sons[0], a) if d.k == locNone: d.s = a.s discard getTypeDesc(p.module, a.t) # fill the record's fields.loc - var ty = getUniqueType(a.t) + var ty = a.t var r = rdLoc(a) case e.sons[1].kind of nkIntLit..nkInt64Lit: i = int(e.sons[1].intVal) else: internalError(e.info, "genTupleElem") - if ty.n != nil: - var field = ty.n.sons[i].sym - if field == nil: InternalError(e.info, "genTupleElem") - if field.loc.r == nil: InternalError(e.info, "genTupleElem") - appf(r, ".$1", [field.loc.r]) + when false: + if ty.n != nil: + var field = ty.n.sons[i].sym + if field == nil: InternalError(e.info, "genTupleElem") + if field.loc.r == nil: InternalError(e.info, "genTupleElem") + appf(r, ".$1", [field.loc.r]) else: appf(r, ".Field$1", [toRope(i)]) putIntoDest(p, d, ty.sons[i], r) @@ -1508,11 +1509,10 @@ proc genTupleConstr(p: BProc, n: PNode, d: var TLoc) = for i in countup(0, sonsLen(n) - 1): var it = n.sons[i] if it.kind == nkExprColonExpr: it = it.sons[1] - if t.n == nil: - initLoc(rec, locExpr, it.typ, d.s) - rec.r = ropef("$1.Field$2", [rdLoc(d), toRope(i)]) - expr(p, it, rec) - else: + initLoc(rec, locExpr, it.typ, d.s) + rec.r = ropef("$1.Field$2", [rdLoc(d), toRope(i)]) + expr(p, it, rec) + when false: initLoc(rec, locExpr, it.typ, d.s) if (t.n.sons[i].kind != nkSym): InternalError(n.info, "genTupleConstr") rec.r = ropef("$1.$2", diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 891731533..46e4f75df 100755 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -32,7 +32,7 @@ proc genVarTuple(p: BProc, n: PNode) = assignLocalVar(p, v) initLocalVar(p, v, immediateAsgn=true) initLoc(field, locExpr, t.sons[i], tup.s) - if t.n == nil: + if t.kind == tyTuple: field.r = ropef("$1.Field$2", [rdLoc(tup), toRope(i)]) else: if (t.n.sons[i].kind != nkSym): InternalError(n.info, "genVarTuple") diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 1b3e84cc4..fc09d9a5d 100755 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -561,7 +561,7 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var TIntSet): PRope = appf(m.s[cfsForwardTypes], getForwardStructFormat(), [result]) IdTablePut(m.forwTypeCache, t, result) IdTablePut(m.typeCache, t, result) # always call for sideeffects: - if t.n != nil: recdesc = getRecordDesc(m, t, result, check) + if t.kind != tyTuple: recdesc = getRecordDesc(m, t, result, check) else: recdesc = getTupleDesc(m, t, result, check) if not isImportedType(t): app(m.s[cfsTypes], recdesc) of tySet: @@ -889,8 +889,11 @@ proc genTypeInfo(m: BModule, typ: PType): PRope = of tyEnum: genEnumInfo(gNimDat, t, result) of tyObject: genObjectInfo(gNimDat, t, result) of tyTuple: - if t.n != nil: genObjectInfo(gNimDat, t, result) - else: genTupleInfo(gNimDat, t, result) + # if t.n != nil: genObjectInfo(gNimDat, t, result) + # else: + # BUGFIX: use consistently RTTI without proper field names; otherwise + # results are not deterministic! + genTupleInfo(gNimDat, t, result) else: InternalError("genTypeInfo(" & $t.kind & ')') proc genTypeSection(m: BModule, n: PNode) = diff --git a/compiler/ccgutils.nim b/compiler/ccgutils.nim index 12795358a..5ba523070 100755 --- a/compiler/ccgutils.nim +++ b/compiler/ccgutils.nim @@ -87,14 +87,19 @@ proc GetUniqueType*(key: PType): PType = of tyGenericInst, tyDistinct, tyOrdinal, tyMutable, tyConst, tyIter: result = GetUniqueType(lastSon(key)) of tyArrayConstr, tyGenericInvokation, tyGenericBody, - tyOpenArray, tyArray, tyTuple, tySet, tyRange, + tyOpenArray, tyArray, tySet, tyRange, tyTuple, tyPtr, tyRef, tySequence, tyForward, tyVarargs, tyProxy, tyVar: + # tuples are quite horrible as C does not support them directly and + # tuple[string, string] is a (strange) subtype of + # tuple[nameA, nameB: string]. This bites us here, so we + # use 'sameBackendType' instead of 'sameType'. + # we have to do a slow linear search because types may need # to be compared by their structure: if IdTableHasObjectAsKey(gTypeTable[k], key): return key for h in countup(0, high(gTypeTable[k].data)): var t = PType(gTypeTable[k].data[h].key) - if t != nil and sameType(t, key): + if t != nil and sameBackendType(t, key): return t IdTablePut(gTypeTable[k], key, key) result = key diff --git a/compiler/types.nim b/compiler/types.nim index 15390bed7..61e42ac0a 100755 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -550,6 +550,7 @@ type TSameTypeClosure = object {.pure.} cmp: TDistinctCompare + ignoreTupleFields: bool recCheck: int s: seq[tuple[a,b: int]] # seq for a set as it's hopefully faster # (few elements expected) @@ -645,7 +646,7 @@ proc sameTuple(a, b: PType, c: var TSameTypeClosure): bool = for i in countup(0, sonsLen(a) - 1): result = SameTypeAux(a.sons[i], b.sons[i], c) if not result: return - if a.n != nil and b.n != nil: + if a.n != nil and b.n != nil and not c.ignoreTupleFields: for i in countup(0, sonsLen(a.n) - 1): # check field names: if a.n.sons[i].kind != nkSym: InternalError(a.n.info, "sameTuple") @@ -787,6 +788,11 @@ proc SameType*(x, y: PType): bool = var c = initSameTypeClosure() result = sameTypeAux(x, y, c) +proc sameBackendType*(x, y: PType): bool = + var c = initSameTypeClosure() + c.ignoreTupleFields = true + result = sameTypeAux(x, y, c) + proc compareTypes*(x, y: PType, cmp: TDistinctCompare): bool = ## compares two type for equality (modulo type distinction) var c = initSameTypeClosure() |