diff options
-rw-r--r-- | compiler/sem.nim | 6 | ||||
-rw-r--r-- | compiler/semexprs.nim | 33 | ||||
-rw-r--r-- | compiler/sempass2.nim | 1 | ||||
-rw-r--r-- | tests/types/temptyseqs.nim | 2 |
4 files changed, 25 insertions, 17 deletions
diff --git a/compiler/sem.nim b/compiler/sem.nim index 214f471d6..2d69d4213 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -130,9 +130,11 @@ proc commonType*(x, y: PType): PType = elif a.kind == tyTuple and b.kind == tyTuple and a.len == b.len: var nt: PType for i in 0.. <a.len: - if isEmptyContainer(a.sons[i]) and not isEmptyContainer(b.sons[i]): + let aEmpty = isEmptyContainer(a.sons[i]) + let bEmpty = isEmptyContainer(b.sons[i]) + if aEmpty != bEmpty: if nt.isNil: nt = copyType(a, a.owner, false) - nt.sons[i] = b.sons[i] + nt.sons[i] = if aEmpty: b.sons[i] else: a.sons[i] if not nt.isNil: result = nt #elif b.sons[idx].kind == tyEmpty: return x elif a.kind == tyRange and b.kind == tyRange: diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 40413e3eb..55d2656e0 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -448,25 +448,30 @@ 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): + elif sonsLen(n) > 0 and n.sons[0].kind == nkExprColonExpr: + # named tuple? + for i in countup(0, sonsLen(n) - 1): var m = n.sons[i].sons[0] - if m.kind != nkSym: + 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) + if tup.n != nil: + 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: + changeType(n.sons[i].sons[1], tup.sons[i], check) else: for i in countup(0, sonsLen(n) - 1): - var m = n.sons[i] - 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) + changeType(n.sons[i], tup.sons[i], check) + when false: + var m = n.sons[i] + 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: let value = n.intVal diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index ede556a70..5434f4f8e 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -683,6 +683,7 @@ proc track(tracked: PEffects, n: PNode) = for child in n: let last = lastSon(child) if child.kind == nkIdentDefs and last.kind != nkEmpty: + # prevent the all too common 'var x = int' bug: XXX track(tracked, last) for i in 0 .. child.len-3: initVar(tracked, child.sons[i], volatileCheck=false) diff --git a/tests/types/temptyseqs.nim b/tests/types/temptyseqs.nim index f8d22bdb8..2b07ba679 100644 --- a/tests/types/temptyseqs.nim +++ b/tests/types/temptyseqs.nim @@ -5,7 +5,7 @@ discard """ # bug #1708 let foo = { "1" : (bar: @["1"]), - "2" : (baz: @[]) + "2" : (bar: @[]) } # bug #871 |