revert to old behaviour: tuple field names are not ignored anymore; fixes #1920

This commit is contained in:
Araq 2015-01-18 02:33:28 +01:00
commit abb738146a
9 changed files with 40 additions and 17 deletions

View file

@ -439,12 +439,24 @@ proc changeType(n: PNode, newType: PType, check: bool) =
let tup = newType.skipTypes({tyGenericInst}) let tup = newType.skipTypes({tyGenericInst})
if tup.kind != tyTuple: if tup.kind != tyTuple:
internalError(n.info, "changeType: no tuple type for constructor") internalError(n.info, "changeType: no tuple type for constructor")
elif newType.n == nil: discard
elif sonsLen(n) > 0 and n.sons[0].kind == nkExprColonExpr:
for i in countup(0, sonsLen(n) - 1):
var m = n.sons[i].sons[0]
if m.kind != nkSym:
internalError(m.info, "changeType(): invalid tuple constr")
return
var f = getSymFromList(newType.n, m.sym.name)
if f == nil:
internalError(m.info, "changeType(): invalid identifier")
return
changeType(n.sons[i].sons[1], f.typ, check)
else: else:
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
var m = n.sons[i] var m = n.sons[i]
if m.kind == nkExprColonExpr: var a = newNodeIT(nkExprColonExpr, m.info, newType.sons[i])
m = m.sons[1] addSon(a, newSymNode(newType.n.sons[i].sym))
n.sons[i] = m addSon(a, m)
changeType(m, tup.sons[i], check) changeType(m, tup.sons[i], check)
of nkCharLit..nkUInt64Lit: of nkCharLit..nkUInt64Lit:
if check: if check:

View file

@ -357,7 +357,7 @@ proc recordRel(c: var TCandidate, f, a: PType): TTypeRelation =
var y = a.n.sons[i].sym var y = a.n.sons[i].sym
if f.kind == tyObject and typeRel(c, x.typ, y.typ) < isSubtype: if f.kind == tyObject and typeRel(c, x.typ, y.typ) < isSubtype:
return isNone return isNone
if x.name.id != y.name.id and f.kind != tyTuple: return isNone if x.name.id != y.name.id: return isNone
proc allowsNil(f: PType): TTypeRelation {.inline.} = proc allowsNil(f: PType): TTypeRelation {.inline.} =
result = if tfNotNil notin f.flags: isSubtype else: isNone result = if tfNotNil notin f.flags: isSubtype else: isNone

View file

@ -781,6 +781,15 @@ proc sameTuple(a, b: PType, c: var TSameTypeClosure): bool =
result = sameTypeAux(x, y, c) result = sameTypeAux(x, y, c)
if not result: return if not result: return
if a.n != nil and b.n != nil and IgnoreTupleFields notin c.flags:
for i in countup(0, sonsLen(a.n) - 1):
# check field names:
if a.n.sons[i].kind == nkSym and b.n.sons[i].kind == nkSym:
var x = a.n.sons[i].sym
var y = b.n.sons[i].sym
result = x.name.id == y.name.id
if not result: break
else: internalError(a.n.info, "sameTuple")
template ifFastObjectTypeCheckFailed(a, b: PType, body: stmt) {.immediate.} = template ifFastObjectTypeCheckFailed(a, b: PType, body: stmt) {.immediate.} =
if tfFromGeneric notin a.flags + b.flags: if tfFromGeneric notin a.flags + b.flags:

View file

@ -31,7 +31,6 @@ algorithm (in pseudo-code) determines type equality:
result = typeEqualsAux(a.baseType, b.baseType, s) and result = typeEqualsAux(a.baseType, b.baseType, s) and
typeEqualsAux(a.indexType, b.indexType, s) typeEqualsAux(a.indexType, b.indexType, s)
of tuple: of tuple:
# Note: tuple field names are ignored
if a.tupleLen == b.tupleLen: if a.tupleLen == b.tupleLen:
for i in 0..a.tupleLen-1: for i in 0..a.tupleLen-1:
if not typeEqualsAux(a[i], b[i], s): return false if not typeEqualsAux(a[i], b[i], s): return false

View file

@ -508,8 +508,8 @@ defines an *order* of the fields. Tuples are meant for heterogeneous storage
types with no overhead and few abstraction possibilities. The constructor ``()`` types with no overhead and few abstraction possibilities. The constructor ``()``
can be used to construct tuples. The order of the fields in the constructor can be used to construct tuples. The order of the fields in the constructor
must match the order of the tuple's definition. Different tuple-types are must match the order of the tuple's definition. Different tuple-types are
*equivalent* if they specify the same types in the same *equivalent* if they specify the same fields of the same type in the same
order. The *names* of the fields are ignored. order. The *names* of the fields also have to be identical.
The assignment operator for tuples copies each component. The assignment operator for tuples copies each component.
The default assignment operator for objects copies each component. Overloading The default assignment operator for objects copies each component. Overloading
@ -527,8 +527,6 @@ in future versions of the compiler.
person = (name: "Peter", age: 30) person = (name: "Peter", age: 30)
# the same, but less readable: # the same, but less readable:
person = ("Peter", 30) person = ("Peter", 30)
# the same, but with confusing tuple field names:
person = (creditCard: "Peter", id: 20)
The implementation aligns the fields for best access performance. The alignment The implementation aligns the fields for best access performance. The alignment
is compatible with the way the C compiler does it. is compatible with the way the C compiler does it.

View file

@ -1,6 +1,5 @@
discard """ discard """
output: '''61, 125 output: '''61, 125'''
89'''
""" """
proc `^` (a, b: int): int = proc `^` (a, b: int): int =
@ -13,7 +12,3 @@ var n = (56, 3)
m = (n[0] + m[1], m[1] ^ n[1]) m = (n[0] + m[1], m[1] ^ n[1])
echo m[0], ", ", m[1] echo m[0], ", ", m[1]
var x = (bar: 38)
x = (foo: 89)
echo x[0]

View file

@ -0,0 +1,9 @@
# bug #1920
import tables
var p: OrderedTable[tuple[a:int], int]
var q: OrderedTable[tuple[x:int], int]
for key in p.keys:
echo key.a
for key in q.keys:
echo key.x

View file

@ -7,9 +7,7 @@ version 0.10
prevent 'not 4 == 5' from compiling. -> requires 'mixin' annotation for procs! prevent 'not 4 == 5' from compiling. -> requires 'mixin' annotation for procs!
- parameter lists without type end up in 'experimental' - parameter lists without type end up in 'experimental'
- iterators always require a return type - iterators always require a return type
- revert tuple behaviour
- c2nim depends on the compiler
- make nimble part of the distribution - make nimble part of the distribution
- split idetools into separate tool - split idetools into separate tool
- split docgen into separate tool - split docgen into separate tool

View file

@ -13,6 +13,9 @@ News
- Parameter names are finally properly ``gensym``'ed. This can break - Parameter names are finally properly ``gensym``'ed. This can break
templates though that used to rely on the fact that they are not. However templates though that used to rely on the fact that they are not. However
we found none such beast in the wild. (Bug #1915.) we found none such beast in the wild. (Bug #1915.)
- Tuple field names are not ignored anymore, this caused too many problems
in practice so now the behaviour as it was for version 0.9.6: If field
names exist for the tuple type, they are checked.
Language Additions Language Additions