mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-28 13:55:14 +00:00
revert to old behaviour: tuple field names are not ignored anymore; fixes #1920
This commit is contained in:
@@ -439,12 +439,24 @@ proc changeType(n: PNode, newType: PType, check: bool) =
|
||||
let tup = newType.skipTypes({tyGenericInst})
|
||||
if tup.kind != tyTuple:
|
||||
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:
|
||||
for i in countup(0, sonsLen(n) - 1):
|
||||
var m = n.sons[i]
|
||||
if m.kind == nkExprColonExpr:
|
||||
m = m.sons[1]
|
||||
n.sons[i] = m
|
||||
var a = newNodeIT(nkExprColonExpr, m.info, newType.sons[i])
|
||||
addSon(a, newSymNode(newType.n.sons[i].sym))
|
||||
addSon(a, m)
|
||||
changeType(m, tup.sons[i], check)
|
||||
of nkCharLit..nkUInt64Lit:
|
||||
if check:
|
||||
|
||||
@@ -357,7 +357,7 @@ proc recordRel(c: var TCandidate, f, a: PType): TTypeRelation =
|
||||
var y = a.n.sons[i].sym
|
||||
if f.kind == tyObject and typeRel(c, x.typ, y.typ) < isSubtype:
|
||||
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.} =
|
||||
result = if tfNotNil notin f.flags: isSubtype else: isNone
|
||||
|
||||
@@ -781,6 +781,15 @@ proc sameTuple(a, b: PType, c: var TSameTypeClosure): bool =
|
||||
|
||||
result = sameTypeAux(x, y, c)
|
||||
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.} =
|
||||
if tfFromGeneric notin a.flags + b.flags:
|
||||
|
||||
@@ -31,7 +31,6 @@ algorithm (in pseudo-code) determines type equality:
|
||||
result = typeEqualsAux(a.baseType, b.baseType, s) and
|
||||
typeEqualsAux(a.indexType, b.indexType, s)
|
||||
of tuple:
|
||||
# Note: tuple field names are ignored
|
||||
if a.tupleLen == b.tupleLen:
|
||||
for i in 0..a.tupleLen-1:
|
||||
if not typeEqualsAux(a[i], b[i], s): return false
|
||||
|
||||
@@ -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 ``()``
|
||||
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
|
||||
*equivalent* if they specify the same types in the same
|
||||
order. The *names* of the fields are ignored.
|
||||
*equivalent* if they specify the same fields of the same type in the same
|
||||
order. The *names* of the fields also have to be identical.
|
||||
|
||||
The assignment operator for tuples copies each component.
|
||||
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)
|
||||
# the same, but less readable:
|
||||
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
|
||||
is compatible with the way the C compiler does it.
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
discard """
|
||||
output: '''61, 125
|
||||
89'''
|
||||
output: '''61, 125'''
|
||||
"""
|
||||
|
||||
proc `^` (a, b: int): int =
|
||||
@@ -13,7 +12,3 @@ var n = (56, 3)
|
||||
m = (n[0] + m[1], m[1] ^ n[1])
|
||||
|
||||
echo m[0], ", ", m[1]
|
||||
|
||||
var x = (bar: 38)
|
||||
x = (foo: 89)
|
||||
echo x[0]
|
||||
|
||||
9
tests/tuples/tdifferent_instantiations.nim
Normal file
9
tests/tuples/tdifferent_instantiations.nim
Normal 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
|
||||
2
todo.txt
2
todo.txt
@@ -7,9 +7,7 @@ version 0.10
|
||||
prevent 'not 4 == 5' from compiling. -> requires 'mixin' annotation for procs!
|
||||
- parameter lists without type end up in 'experimental'
|
||||
- iterators always require a return type
|
||||
- revert tuple behaviour
|
||||
|
||||
- c2nim depends on the compiler
|
||||
- make nimble part of the distribution
|
||||
- split idetools into separate tool
|
||||
- split docgen into separate tool
|
||||
|
||||
@@ -13,6 +13,9 @@ News
|
||||
- Parameter names are finally properly ``gensym``'ed. This can break
|
||||
templates though that used to rely on the fact that they are not. However
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user