diff options
-rw-r--r-- | compiler/ast.nim | 8 | ||||
-rw-r--r-- | compiler/injectdestructors.nim | 2 | ||||
-rw-r--r-- | compiler/semexprs.nim | 4 | ||||
-rw-r--r-- | compiler/semstmts.nim | 12 | ||||
-rw-r--r-- | compiler/types.nim | 5 | ||||
-rw-r--r-- | tests/ccgbugs/t5701.nim | 27 | ||||
-rw-r--r-- | tests/ccgbugs/tccgissues.nim | 14 | ||||
-rw-r--r-- | tests/errmsgs/ttypeAllowed.nim | 28 | ||||
-rw-r--r-- | tests/iter/titerassignerr.nim | 8 |
9 files changed, 54 insertions, 54 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index f24008b30..fdf01cb77 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1810,11 +1810,11 @@ template getBody*(s: PSym): PNode = s.ast[bodyPos] template detailedInfo*(sym: PSym): string = sym.name.s -proc isInlineIterator*(s: PSym): bool {.inline.} = - s.kind == skIterator and s.typ.callConv != ccClosure +proc isInlineIterator*(typ: PType): bool {.inline.} = + typ.kind == tyProc and tfIterator in typ.flags and typ.callConv != ccClosure -proc isClosureIterator*(s: PSym): bool {.inline.} = - s.kind == skIterator and s.typ.callConv == ccClosure +proc isClosureIterator*(typ: PType): bool {.inline.} = + typ.kind == tyProc and tfIterator in typ.flags and typ.callConv == ccClosure proc isSinkParam*(s: PSym): bool {.inline.} = s.kind == skParam and (s.typ.kind == tySink or tfHasOwned in s.typ.flags) diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index 95de5777e..5765721d7 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -636,7 +636,7 @@ proc reverseDestroys(destroys: seq[PNode]): seq[PNode] = result.add destroys[i] proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode = - if sfGeneratedOp in owner.flags or isInlineIterator(owner): return n + if sfGeneratedOp in owner.flags or (owner.kind == skIterator and isInlineIterator(owner.typ)): return n var c: Con c.owner = owner c.destroys = newNodeI(nkStmtList, n.info) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 7a72f1602..019c30226 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1724,7 +1724,7 @@ proc semReturn(c: PContext, n: PNode): PNode = result = n checkSonsLen(n, 1, c.config) if c.p.owner.kind in {skConverter, skMethod, skProc, skFunc, skMacro} or - isClosureIterator(c.p.owner): + isClosureIterator(c.p.owner.typ): if n.sons[0].kind != nkEmpty: # transform ``return expr`` to ``result = expr; return`` if c.p.resultSym != nil: @@ -1771,7 +1771,7 @@ proc semProcBody(c: PContext, n: PNode): PNode = else: localError(c.config, c.p.resultSym.info, errCannotInferReturnType % c.p.owner.name.s) - if isInlineIterator(c.p.owner) and c.p.owner.typ.sons[0] != nil and + if isInlineIterator(c.p.owner.typ) and c.p.owner.typ.sons[0] != nil and c.p.owner.typ.sons[0].kind == tyUntyped: localError(c.config, c.p.owner.info, errCannotInferReturnType % c.p.owner.name.s) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 8acc5ce2f..f5a82b910 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -38,7 +38,6 @@ const errPragmaOnlyInHeaderOfProcX = "pragmas are only allowed in the header of a proc; redefinition of $1" errCannotAssignMacroSymbol = "cannot assign macro symbol to $1 here. Forgot to invoke the macro with '()'?" errInvalidTypeDescAssign = "'typedesc' metatype is not valid here; typed '=' instead of ':'?" - errInlineIteratorNotFirstClass = "inline iterators are not first-class / cannot be assigned to variables" proc semDiscard(c: PContext, n: PNode): PNode = result = n @@ -456,9 +455,6 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = if def.sym.kind == skMacro: localError(c.config, def.info, errCannotAssignMacroSymbol % "variable") def.typ = errorType(c) - elif isInlineIterator(def.sym): - localError(c.config, def.info, errInlineIteratorNotFirstClass) - def.typ = errorType(c) elif def.typ.kind == tyTypeDesc and c.p.owner.kind != skMacro: # prevent the all too common 'var x = int' bug: localError(c.config, def.info, errInvalidTypeDescAssign) @@ -601,9 +597,6 @@ proc semConst(c: PContext, n: PNode): PNode = if def.sym.kind == skMacro: localError(c.config, def.info, errCannotAssignMacroSymbol % "constant") def.typ = errorType(c) - elif isInlineIterator(def.sym): - localError(c.config, def.info, errInlineIteratorNotFirstClass) - def.typ = errorType(c) elif def.typ.kind == tyTypeDesc and c.p.owner.kind != skMacro: # prevent the all too common 'const x = int' bug: localError(c.config, def.info, errInvalidTypeDescAssign) @@ -1589,7 +1582,7 @@ proc maybeAddResult(c: PContext, s: PSym, n: PNode) = let resultType = sysTypeFromName(c.graph, n.info, "NimNode") addResult(c, resultType, n.info, s.kind) addResultNode(c, n) - elif s.typ.sons[0] != nil and not isInlineIterator(s): + elif s.typ.sons[0] != nil and not isInlineIterator(s.typ): addResult(c, s.typ.sons[0], n.info, s.kind) addResultNode(c, n) @@ -1969,7 +1962,6 @@ proc determineType(c: PContext, s: PSym) = proc semIterator(c: PContext, n: PNode): PNode = # gensym'ed iterator? - let isAnon = n[namePos].kind == nkEmpty if n[namePos].kind == nkSym: # gensym'ed iterators might need to become closure iterators: n[namePos].sym.owner = getCurrOwner(c) @@ -1983,8 +1975,6 @@ proc semIterator(c: PContext, n: PNode): PNode = var t = s.typ if t.sons[0] == nil and s.typ.callConv != ccClosure: localError(c.config, n.info, "iterator needs a return type") - if isAnon and s.typ.callConv == ccInline: - localError(c.config, n.info, errInlineIteratorNotFirstClass) # iterators are either 'inline' or 'closure'; for backwards compatibility, # we require first class iterators to be marked with 'closure' explicitly # -- at least for 0.9.2. diff --git a/compiler/types.nim b/compiler/types.nim index 8ff109b37..dc5068d0e 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -1280,10 +1280,13 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind, if kind notin {skParam, skResult}: result = t else: result = typeAllowedAux(marker, t2, kind, flags) of tyProc: + if isInlineIterator(typ) and kind in {skVar, skLet, skConst, skParam, skResult}: + # only closure iterators my be assigned to anything. + result = t let f = if kind in {skProc, skFunc}: flags+{taNoUntyped} else: flags for i in 1 ..< len(t): - result = typeAllowedAux(marker, t.sons[i], skParam, f-{taIsOpenArray}) if result != nil: break + result = typeAllowedAux(marker, t.sons[i], skParam, f-{taIsOpenArray}) if result.isNil and t.sons[0] != nil: result = typeAllowedAux(marker, t.sons[0], skResult, flags) of tyTypeDesc: diff --git a/tests/ccgbugs/t5701.nim b/tests/ccgbugs/t5701.nim deleted file mode 100644 index 19d64a230..000000000 --- a/tests/ccgbugs/t5701.nim +++ /dev/null @@ -1,27 +0,0 @@ -discard """ - output: '''(1, 1) -(2, 2) -(3, 3) -@[1, 2, 3, 4] -''' -""" - -iterator zip[T1, T2](a: openarray[T1], b: openarray[T2]): iterator() {.inline.} = - let len = min(a.len, b.len) - for i in 0..<len: - echo (a[i], b[i]) - -proc foo(args: varargs[int]) = - for i in zip(args,args): - discard - -foo(1,2,3) - -# 10999 - -proc varargsToSeq(vals: varargs[int32]): seq[int32] = - result = newSeqOfCap[int32](vals.len) - for v in vals: - result.add v - -echo varargsToSeq(1, 2, 3, 4) diff --git a/tests/ccgbugs/tccgissues.nim b/tests/ccgbugs/tccgissues.nim new file mode 100644 index 000000000..8207ccbba --- /dev/null +++ b/tests/ccgbugs/tccgissues.nim @@ -0,0 +1,14 @@ +discard """ + output: ''' +@[1, 2, 3, 4] +''' +""" + +# issue #10999 + +proc varargsToSeq(vals: varargs[int32]): seq[int32] = + result = newSeqOfCap[int32](vals.len) + for v in vals: + result.add v + +echo varargsToSeq(1, 2, 3, 4) diff --git a/tests/errmsgs/ttypeAllowed.nim b/tests/errmsgs/ttypeAllowed.nim new file mode 100644 index 000000000..a5b335faa --- /dev/null +++ b/tests/errmsgs/ttypeAllowed.nim @@ -0,0 +1,28 @@ +discard """ +cmd: "nim check $file" +errmsg: "" +nimout: ''' +ttypeAllowed.nim(13, 5) Error: invalid type: 'iterator (a: int, b: int, step: Positive): int{.inline, noSideEffect, gcsafe, locks: 0.}' for let +ttypeAllowed.nim(17, 7) Error: invalid type for const: iterator (a: int, b: int, step: Positive): int{.inline, noSideEffect, gcsafe, locks: 0.} +ttypeAllowed.nim(21, 5) Error: invalid type: 'iterator (a: int, b: int, step: Positive): int{.inline, noSideEffect, gcsafe, locks: 0.}' for var +ttypeAllowed.nim(26, 10) Error: invalid type: 'iterator (a: int, b: int, step: Positive): int{.inline, noSideEffect, gcsafe, locks: 0.}' for result +''' +""" + + +let f1 = case true + of true: countup[int] + of false: countdown[int] + +const f2 = case true + of true: countup[int] + of false: countdown[int] + +var f3 = case true + of true: countup[int] + of false: countdown[int] + +proc foobar(): auto = + result = case true + of true: countup[int] + of false: countdown[int] diff --git a/tests/iter/titerassignerr.nim b/tests/iter/titerassignerr.nim deleted file mode 100644 index caa56c4ad..000000000 --- a/tests/iter/titerassignerr.nim +++ /dev/null @@ -1,8 +0,0 @@ -discard """ - errormsg: "inline iterators are not first-class / cannot be assigned to variables" - line: 8 -""" - -iterator foo: int = - yield 2 -let x = foo |