Tuple error message (#11141); fixes #3211

This commit is contained in:
Arne Döring
2019-05-15 17:59:06 +02:00
committed by Andreas Rumpf
parent de6b2e88d2
commit 2339542832
4 changed files with 36 additions and 22 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -0,0 +1,5 @@
discard """
errormsg: "typedesc not allowed as tuple field."
"""
var bar = (a: int, b: 1)

View File

@@ -0,0 +1,5 @@
discard """
errormsg: "Mixing types and values in tuples is not allowed."
"""
var bar = (int, 1)