From 2339542832f754cffda5905b3ed6fdbf8766cad7 Mon Sep 17 00:00:00 2001 From: Arne Döring Date: Wed, 15 May 2019 17:59:06 +0200 Subject: Tuple error message (#11141); fixes #3211 --- compiler/semexprs.nim | 41 ++++++++++++++++++++--------------- tests/errmsgs/tmake_tuple_visible.nim | 7 ++---- tests/tuples/ttypedesc_in_tuple_a.nim | 5 +++++ tests/tuples/ttypedesc_in_tuple_b.nim | 5 +++++ 4 files changed, 36 insertions(+), 22 deletions(-) create mode 100644 tests/tuples/ttypedesc_in_tuple_a.nim create mode 100644 tests/tuples/ttypedesc_in_tuple_b.nim 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 ''' - line: 22 - nimout: '''got -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) -- cgit 1.4.1-2-gfad0