summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2019-08-29 07:49:58 +0200
committerGitHub <noreply@github.com>2019-08-29 07:49:58 +0200
commit9203d3a982446990467f4ddcfdc33d2cc5d91882 (patch)
tree79546400e461068eff54aec54322a02b09dd962d
parentcd106cf68071a3249d32d4ffc2948cd5fe6c1795 (diff)
downloadNim-9203d3a982446990467f4ddcfdc33d2cc5d91882.tar.gz
fixes 5870 (#11704)
* fixes #5870
* make tclosure test green again
* this check is correct but breaks some Nimble packages
-rw-r--r--compiler/semstmts.nim2
-rw-r--r--compiler/types.nim50
-rw-r--r--lib/system/iterators.nim4
-rw-r--r--tests/errmsgs/t5870.nim17
4 files changed, 47 insertions, 26 deletions
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index 5a9c92647..b22dc7952 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -1880,7 +1880,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
     else:
       pushProcCon(c, s)
       if n.sons[genericParamsPos].kind == nkEmpty or usePseudoGenerics:
-        if not usePseudoGenerics: paramsTypeCheck(c, s.typ)
+        if not usePseudoGenerics and s.magic == mNone: paramsTypeCheck(c, s.typ)
 
         c.p.wasForwarded = proto != nil
         maybeAddResult(c, s, n)
diff --git a/compiler/types.nim b/compiler/types.nim
index 61fbffd60..5e157272e 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -1188,7 +1188,9 @@ type
   TTypeAllowedFlag* = enum
     taField,
     taHeap,
-    taConcept
+    taConcept,
+    taIsOpenArray,
+    taNoUntyped
 
   TTypeAllowedFlags* = set[TTypeAllowedFlag]
 
@@ -1204,8 +1206,8 @@ proc typeAllowedNode(marker: var IntSet, n: PNode, kind: TSymKind,
       of nkNone..nkNilLit:
         discard
       else:
-        if n.kind == nkRecCase and kind in {skProc, skFunc, skConst}:
-          return n[0].typ
+        #if n.kind == nkRecCase and kind in {skProc, skFunc, skConst}:
+        #  return n[0].typ
         for i in 0 ..< sonsLen(n):
           let it = n.sons[i]
           result = typeAllowedNode(marker, it, kind, flags)
@@ -1240,28 +1242,29 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
       case t2.kind
       of tyVar, tyLent:
         if taHeap notin flags: result = t2 # ``var var`` is illegal on the heap
-      of tyOpenArray, tyUncheckedArray:
+      of tyOpenArray:
+        if kind != skParam or taIsOpenArray in flags: result = t
+        else: result = typeAllowedAux(marker, t2.sons[0], kind, flags+{taIsOpenArray})
+      of tyUncheckedArray:
         if kind != skParam: result = t
-        else: result = typeAllowedAux(marker, t2.sons[0], skParam, flags)
+        else: result = typeAllowedAux(marker, t2.sons[0], kind, flags)
       else:
         if kind notin {skParam, skResult}: result = t
         else: result = typeAllowedAux(marker, t2, kind, flags)
   of tyProc:
-    if kind == skConst and t.callConv == ccClosure:
-      result = t
-    else:
-      for i in 1 ..< sonsLen(t):
-        result = typeAllowedAux(marker, t.sons[i], skParam, flags)
-        if result != nil: break
-      if result.isNil and t.sons[0] != nil:
-        result = typeAllowedAux(marker, t.sons[0], skResult, flags)
+    let f = if kind in {skProc, skFunc}: flags+{taNoUntyped} else: flags
+    for i in 1 ..< sonsLen(t):
+      result = typeAllowedAux(marker, t.sons[i], skParam, f)
+      if result != nil: break
+    if result.isNil and t.sons[0] != nil:
+      result = typeAllowedAux(marker, t.sons[0], skResult, flags)
   of tyTypeDesc:
     # XXX: This is still a horrible idea...
     result = nil
+  of tyUntyped, tyTyped:
+    if kind notin {skParam, skResult} or taNoUntyped in flags: result = t
   of tyStatic:
     if kind notin {skParam}: result = t
-  of tyUntyped, tyTyped:
-    if kind notin {skParam, skResult}: result = t
   of tyVoid:
     if taField notin flags: result = t
   of tyTypeClasses:
@@ -1286,30 +1289,31 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
     if skipTypes(t.sons[0], abstractInst-{tyTypeDesc}).kind notin
       {tyChar, tyEnum, tyInt..tyFloat128, tyUInt8..tyUInt32}: result = t
   of tyOpenArray, tyVarargs, tySink:
-    if kind != skParam:
+    # you cannot nest openArrays/sinks/etc.
+    if kind != skParam or taIsOpenArray in flags:
       result = t
     else:
-      result = typeAllowedAux(marker, t.sons[0], skVar, flags)
+      result = typeAllowedAux(marker, t.sons[0], kind, flags+{taIsOpenArray})
   of tyUncheckedArray:
     if kind != skParam and taHeap notin flags:
       result = t
     else:
-      result = typeAllowedAux(marker, lastSon(t), kind, flags)
+      result = typeAllowedAux(marker, lastSon(t), kind, flags-{taHeap})
   of tySequence, tyOpt:
     if t.sons[0].kind != tyEmpty:
-      result = typeAllowedAux(marker, t.sons[0], skVar, flags+{taHeap})
+      result = typeAllowedAux(marker, t.sons[0], kind, flags+{taHeap})
     elif kind in {skVar, skLet}:
       result = t.sons[0]
   of tyArray:
     if t.sons[1].kind != tyEmpty:
-      result = typeAllowedAux(marker, t.sons[1], skVar, flags)
+      result = typeAllowedAux(marker, t.sons[1], kind, flags)
     elif kind in {skVar, skLet}:
       result = t.sons[1]
   of tyRef:
     if kind == skConst: result = t
-    else: result = typeAllowedAux(marker, t.lastSon, skVar, flags+{taHeap})
+    else: result = typeAllowedAux(marker, t.lastSon, kind, flags+{taHeap})
   of tyPtr:
-    result = typeAllowedAux(marker, t.lastSon, skVar, flags+{taHeap})
+    result = typeAllowedAux(marker, t.lastSon, kind, flags+{taHeap})
   of tySet:
     for i in 0 ..< sonsLen(t):
       result = typeAllowedAux(marker, t.sons[i], kind, flags)
@@ -1333,7 +1337,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
     result = nil
   of tyOwned:
     if t.len == 1 and t.sons[0].skipTypes(abstractInst).kind in {tyRef, tyPtr, tyProc}:
-      result = typeAllowedAux(marker, t.lastSon, skVar, flags+{taHeap})
+      result = typeAllowedAux(marker, t.lastSon, kind, flags+{taHeap})
     else:
       result = t
 
diff --git a/lib/system/iterators.nim b/lib/system/iterators.nim
index dafd56cb3..117ec123d 100644
--- a/lib/system/iterators.nim
+++ b/lib/system/iterators.nim
@@ -224,7 +224,7 @@ iterator fields*[T: tuple|object](x: T): RootObj {.
   ## **Warning**: This really transforms the 'for' and unrolls the loop.
   ## The current implementation also has a bug
   ## that affects symbol binding in the loop body.
-iterator fields*[S:tuple|object, T:tuple|object](x: S, y: T): tuple[a,b: untyped] {.
+iterator fields*[S:tuple|object, T:tuple|object](x: S, y: T): tuple[a, b: RootObj] {.
   magic: "Fields", noSideEffect.}
   ## Iterates over every field of `x` and `y`.
   ##
@@ -266,7 +266,7 @@ iterator fieldPairs*[T: tuple|object](x: T): RootObj {.
   ## loop body.
 
 iterator fieldPairs*[S: tuple|object, T: tuple|object](x: S, y: T): tuple[
-  a, b: untyped] {.
+  a, b: RootObj] {.
   magic: "FieldPairs", noSideEffect.}
   ## Iterates over every field of `x` and `y`.
   ##
diff --git a/tests/errmsgs/t5870.nim b/tests/errmsgs/t5870.nim
new file mode 100644
index 000000000..bcbc9cca9
--- /dev/null
+++ b/tests/errmsgs/t5870.nim
@@ -0,0 +1,17 @@
+discard """
+errormsg: "invalid type for const: seq[SomeRefObj]"
+line: 14
+"""
+
+# bug #5870
+type SomeRefObj = ref object of RootObj
+    someIntMember: int
+
+proc createSomeRefObj(v: int): SomeRefObj=
+    result.new()
+    result.someIntMember = v
+
+const compileTimeSeqOfRefObjs = @[createSomeRefObj(100500), createSomeRefObj(2)]
+
+for i in 0..1:
+  echo compileTimeSeqOfRefObjs[i].someIntMember