From 49471440eb4ca9d6afd1aed23c1581c0b8d262f1 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 10 Apr 2015 13:45:12 +0200 Subject: [PATCH] fixes #2481 --- compiler/semdata.nim | 3 ++- compiler/semexprs.nim | 2 +- compiler/sigmatch.nim | 7 ++++-- tests/overload/tstmtoverload.nim | 38 ++++++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 tests/overload/tstmtoverload.nim diff --git a/compiler/semdata.nim b/compiler/semdata.nim index cec39ff29..cf7a52ff5 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -43,7 +43,8 @@ type inst*: PInstantiation TExprFlag* = enum - efLValue, efWantIterator, efInTypeof, efWantStmt, efDetermineType, + efLValue, efWantIterator, efInTypeof, + efWantStmt, efAllowStmt, efDetermineType, efAllowDestructor, efWantValue, efOperand, efNoSemCheck TExprFlags* = set[TExprFlag] diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index accf90d8b..c5bfbfa92 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -31,7 +31,7 @@ proc semOperand(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = if result.typ != nil: # XXX tyGenericInst here? if result.typ.kind == tyVar: result = newDeref(result) - elif efWantStmt in flags: + elif {efWantStmt, efAllowStmt} * flags != {}: result.typ = newTypeS(tyEmpty, c) else: localError(n.info, errExprXHasNoType, diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 7e0820593..faa84de15 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1422,9 +1422,12 @@ proc prepareOperand(c: PContext; formal: PType; a: PNode): PNode = # a.typ == nil is valid result = a elif a.typ.isNil: + # XXX This is unsound! 'formal' can differ from overloaded routine to + # overloaded routine! let flags = if formal.kind == tyIter: {efDetermineType, efWantIterator} - elif formal.kind == tyStmt: {efDetermineType, efWantStmt} - else: {efDetermineType} + else: {efDetermineType, efAllowStmt} + #elif formal.kind == tyStmt: {efDetermineType, efWantStmt} + #else: {efDetermineType} result = c.semOperand(c, a, flags) else: result = a diff --git a/tests/overload/tstmtoverload.nim b/tests/overload/tstmtoverload.nim new file mode 100644 index 000000000..f1944b637 --- /dev/null +++ b/tests/overload/tstmtoverload.nim @@ -0,0 +1,38 @@ + +# bug #2481 +import math + +template test(loopCount: int, extraI: int, testBody: stmt): stmt = + block: + for i in 0..loopCount-1: + testBody + echo "done extraI=", extraI + +template test(loopCount: int, extraF: float, testBody: stmt): stmt = + block: + test(loopCount, round(extraF), testBody) + +template test(loopCount: int, testBody: stmt): stmt = + block: + test(loopCount, 0, testBody) + echo "done extraI passed 0" + +when isMainModule: + var + loops = 0 + + test 0, 0: + loops += 1 + echo "test 0 complete, loops=", loops + + test 1, 1.0: + loops += 1 + echo "test 1.0 complete, loops=", loops + + when true: + # when true we get the following compile time error: + # b.nim(35, 6) Error: expression 'loops += 1' has no type (or is ambiguous) + loops = 0 + test 2: + loops += 1 + echo "test no extra complete, loops=", loops