summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorArne Döring <arne.doering@gmx.net>2019-05-15 17:59:06 +0200
committerAndreas Rumpf <rumpf_a@web.de>2019-05-15 17:59:06 +0200
commit2339542832f754cffda5905b3ed6fdbf8766cad7 (patch)
tree8218a289a8e59da6f7941606b18554c17bc0d091
parentde6b2e88d23e2a697cd772958463aa2201bece1d (diff)
downloadNim-2339542832f754cffda5905b3ed6fdbf8766cad7.tar.gz
Tuple error message (#11141); fixes #3211
-rw-r--r--compiler/semexprs.nim41
-rw-r--r--tests/errmsgs/tmake_tuple_visible.nim7
-rw-r--r--tests/tuples/ttypedesc_in_tuple_a.nim5
-rw-r--r--tests/tuples/ttypedesc_in_tuple_b.nim5
4 files changed, 36 insertions, 22 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index c0aaccf56..db26e385d 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -2343,7 +2343,7 @@ proc checkPar(c: PContext; n: PNode): TParKind =
     for i in 0 ..< length:
       if result == paTupleFields:
         if (n.sons[i].kind != nkExprColonExpr) or
-            not (n.sons[i].sons[0].kind in {nkSym, nkIdent}):
+            n.sons[i].sons[0].kind notin {nkSym, nkIdent}:
           localError(c.config, n.sons[i].info, errNamedExprExpected)
           return paNone
       else:
@@ -2366,6 +2366,11 @@ proc semTupleFieldsConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
       localError(c.config, n.sons[i].info, errFieldInitTwice % id.s)
     n.sons[i].sons[1] = semExprWithType(c, n.sons[i].sons[1],
                                         flags*{efAllowDestructor})
+
+    if n.sons[i].sons[1].typ.kind == tyTypeDesc:
+      localError(c.config, n.sons[i].sons[1].info, "typedesc not allowed as tuple field.")
+      n.sons[i].sons[1].typ = errorType(c)
+
     var f = newSymS(skField, n.sons[i].sons[0], c)
     f.typ = skipIntLit(n.sons[i].sons[1].typ)
     f.position = i
@@ -2384,14 +2389,6 @@ proc semTuplePositionsConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
     addSonSkipIntLit(typ, n.sons[i].typ)
   result.typ = typ
 
-proc isTupleType(n: PNode): bool =
-  if n.len == 0:
-    return false # don't interpret () as type
-  for i in 0 ..< n.len:
-    if n[i].typ == nil or n[i].typ.kind != tyTypeDesc:
-      return false
-  return true
-
 include semobjconstr
 
 proc semBlock(c: PContext, n: PNode; flags: TExprFlags): PNode =
@@ -2462,6 +2459,23 @@ proc semExport(c: PContext, n: PNode): PNode =
           strTableAdd(c.module.tab, s)
         s = nextOverloadIter(o, c, a)
 
+proc semTupleConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
+  var tupexp = semTuplePositionsConstr(c, n, flags)
+  var isTupleType: bool
+  if tupexp.len > 0: # don't interpret () as type
+    isTupleType = tupexp[0].typ.kind == tyTypeDesc
+    # check if either everything or nothing is tyTypeDesc
+    for i in 1 ..< tupexp.len:
+      if isTupleType != (tupexp[i].typ.kind == tyTypeDesc):
+        localError(c.config, tupexp[i].info, "Mixing types and values in tuples is not allowed.")
+        return(errorNode(c,n))
+  if isTupleType: # expressions as ``(int, string)`` are reinterpret as type expressions
+    result = n
+    var typ = semTypeNode(c, n, nil).skipTypes({tyTypeDesc})
+    result.typ = makeTypeDesc(c, typ)
+  else:
+    result = tupexp
+
 proc shouldBeBracketExpr(n: PNode): bool =
   assert n.kind in nkCallKinds
   let a = n.sons[0]
@@ -2641,14 +2655,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
   of nkPar, nkTupleConstr:
     case checkPar(c, n)
     of paNone: result = errorNode(c, n)
-    of paTuplePositions:
-      var tupexp = semTuplePositionsConstr(c, n, flags)
-      if isTupleType(tupexp):
-        # reinterpret as type
-        var typ = semTypeNode(c, n, nil).skipTypes({tyTypeDesc})
-        result.typ = makeTypeDesc(c, typ)
-      else:
-        result = tupexp
+    of paTuplePositions: result = semTupleConstr(c, n, flags)
     of paTupleFields: result = semTupleFieldsConstr(c, n, flags)
     of paSingle: result = semExpr(c, n.sons[0], flags)
   of nkCurly: result = semSetConstr(c, n)
diff --git a/tests/errmsgs/tmake_tuple_visible.nim b/tests/errmsgs/tmake_tuple_visible.nim
index e059368ad..90b965c64 100644
--- a/tests/errmsgs/tmake_tuple_visible.nim
+++ b/tests/errmsgs/tmake_tuple_visible.nim
@@ -1,9 +1,6 @@
 discard """
-  errormsg: '''got <tuple of (type NimEdAppWindow, int)>'''
-  line: 22
-  nimout: '''got <tuple of (type NimEdAppWindow, int)>
-but expected one of:
-template xxx(tn: typedesc; i: int)'''
+  errormsg: '''Mixing types and values in tuples is not allowed.'''
+  line: 19
 """
 
 type
diff --git a/tests/tuples/ttypedesc_in_tuple_a.nim b/tests/tuples/ttypedesc_in_tuple_a.nim
new file mode 100644
index 000000000..7727bb35e
--- /dev/null
+++ b/tests/tuples/ttypedesc_in_tuple_a.nim
@@ -0,0 +1,5 @@
+discard """
+errormsg: "typedesc not allowed as tuple field."
+"""
+
+var bar = (a: int, b: 1)
diff --git a/tests/tuples/ttypedesc_in_tuple_b.nim b/tests/tuples/ttypedesc_in_tuple_b.nim
new file mode 100644
index 000000000..b393d877c
--- /dev/null
+++ b/tests/tuples/ttypedesc_in_tuple_b.nim
@@ -0,0 +1,5 @@
+discard """
+errormsg: "Mixing types and values in tuples is not allowed."
+"""
+
+var bar = (int, 1)