diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2019-08-29 07:49:58 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-08-29 07:49:58 +0200 |
commit | 9203d3a982446990467f4ddcfdc33d2cc5d91882 (patch) | |
tree | 79546400e461068eff54aec54322a02b09dd962d | |
parent | cd106cf68071a3249d32d4ffc2948cd5fe6c1795 (diff) | |
download | Nim-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.nim | 2 | ||||
-rw-r--r-- | compiler/types.nim | 50 | ||||
-rw-r--r-- | lib/system/iterators.nim | 4 | ||||
-rw-r--r-- | tests/errmsgs/t5870.nim | 17 |
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 |