summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2015-01-18 02:33:28 +0100
committerAraq <rumpf_a@web.de>2015-01-18 02:33:44 +0100
commitabb738146aea1b9692362bf8048ca23a93bd9fa5 (patch)
treedc5c498ed813ca7ab80ad5ae45bae8abb02f1e6f
parenta2b7e6c3925f1320fe178b135fa3d64c62c3e5ef (diff)
downloadNim-abb738146aea1b9692362bf8048ca23a93bd9fa5.tar.gz
revert to old behaviour: tuple field names are not ignored anymore; fixes #1920
-rw-r--r--compiler/semexprs.nim18
-rw-r--r--compiler/sigmatch.nim2
-rw-r--r--compiler/types.nim9
-rw-r--r--doc/manual/type_rel.txt1
-rw-r--r--doc/manual/types.txt6
-rw-r--r--tests/tuples/tanontuples.nim7
-rw-r--r--tests/tuples/tdifferent_instantiations.nim9
-rw-r--r--todo.txt2
-rw-r--r--web/news.txt3
9 files changed, 40 insertions, 17 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index a3ae0263d..8f958c9bf 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -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:
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 3c6cd248e..549f1f9ad 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -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
diff --git a/compiler/types.nim b/compiler/types.nim
index a07698012..e7841a9ab 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -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:
diff --git a/doc/manual/type_rel.txt b/doc/manual/type_rel.txt
index 805b8637f..74539f907 100644
--- a/doc/manual/type_rel.txt
+++ b/doc/manual/type_rel.txt
@@ -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
diff --git a/doc/manual/types.txt b/doc/manual/types.txt
index ff4b9044f..e2595cb71 100644
--- a/doc/manual/types.txt
+++ b/doc/manual/types.txt
@@ -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.
diff --git a/tests/tuples/tanontuples.nim b/tests/tuples/tanontuples.nim
index 80bd32b7b..49803e5ac 100644
--- a/tests/tuples/tanontuples.nim
+++ b/tests/tuples/tanontuples.nim
@@ -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]
diff --git a/tests/tuples/tdifferent_instantiations.nim b/tests/tuples/tdifferent_instantiations.nim
new file mode 100644
index 000000000..9538f67ca
--- /dev/null
+++ b/tests/tuples/tdifferent_instantiations.nim
@@ -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
diff --git a/todo.txt b/todo.txt
index 04994d5ca..c7a3118ba 100644
--- a/todo.txt
+++ b/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
diff --git a/web/news.txt b/web/news.txt
index e077fb53a..53815ab2c 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -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