fixes 5870 (#11704)

* fixes #5870
* make tclosure test green again
* this check is correct but breaks some Nimble packages
This commit is contained in:
Andreas Rumpf 2019-08-29 07:49:58 +02:00 • committed by GitHub
commit 9203d3a982
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 47 additions and 26 deletions

View file

@ -1880,7 +1880,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
else: else:
pushProcCon(c, s) pushProcCon(c, s)
if n.sons[genericParamsPos].kind == nkEmpty or usePseudoGenerics: 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 c.p.wasForwarded = proto != nil
maybeAddResult(c, s, n) maybeAddResult(c, s, n)

View file

@ -1188,7 +1188,9 @@ type
TTypeAllowedFlag* = enum TTypeAllowedFlag* = enum
taField, taField,
taHeap, taHeap,
taConcept taConcept,
taIsOpenArray,
taNoUntyped
TTypeAllowedFlags* = set[TTypeAllowedFlag] TTypeAllowedFlags* = set[TTypeAllowedFlag]
@ -1204,8 +1206,8 @@ proc typeAllowedNode(marker: var IntSet, n: PNode, kind: TSymKind,
of nkNone..nkNilLit: of nkNone..nkNilLit:
discard discard
else: else:
if n.kind == nkRecCase and kind in {skProc, skFunc, skConst}: #if n.kind == nkRecCase and kind in {skProc, skFunc, skConst}:
return n[0].typ # return n[0].typ
for i in 0 ..< sonsLen(n): for i in 0 ..< sonsLen(n):
let it = n.sons[i] let it = n.sons[i]
result = typeAllowedNode(marker, it, kind, flags) result = typeAllowedNode(marker, it, kind, flags)
@ -1240,28 +1242,29 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
case t2.kind case t2.kind
of tyVar, tyLent: of tyVar, tyLent:
if taHeap notin flags: result = t2 # ``var var`` is illegal on the heap 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 if kind != skParam: result = t
else: result = typeAllowedAux(marker, t2.sons[0], skParam, flags) else: result = typeAllowedAux(marker, t2.sons[0], kind, flags)
else: else:
if kind notin {skParam, skResult}: result = t if kind notin {skParam, skResult}: result = t
else: result = typeAllowedAux(marker, t2, kind, flags) else: result = typeAllowedAux(marker, t2, kind, flags)
of tyProc: of tyProc:
if kind == skConst and t.callConv == ccClosure: let f = if kind in {skProc, skFunc}: flags+{taNoUntyped} else: flags
result = t for i in 1 ..< sonsLen(t):
else: result = typeAllowedAux(marker, t.sons[i], skParam, f)
for i in 1 ..< sonsLen(t): if result != nil: break
result = typeAllowedAux(marker, t.sons[i], skParam, flags) if result.isNil and t.sons[0] != nil:
if result != nil: break result = typeAllowedAux(marker, t.sons[0], skResult, flags)
if result.isNil and t.sons[0] != nil:
result = typeAllowedAux(marker, t.sons[0], skResult, flags)
of tyTypeDesc: of tyTypeDesc:
# XXX: This is still a horrible idea... # XXX: This is still a horrible idea...
result = nil result = nil
of tyUntyped, tyTyped:
if kind notin {skParam, skResult} or taNoUntyped in flags: result = t
of tyStatic: of tyStatic:
if kind notin {skParam}: result = t if kind notin {skParam}: result = t
of tyUntyped, tyTyped:
if kind notin {skParam, skResult}: result = t
of tyVoid: of tyVoid:
if taField notin flags: result = t if taField notin flags: result = t
of tyTypeClasses: of tyTypeClasses:
@ -1286,30 +1289,31 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
if skipTypes(t.sons[0], abstractInst-{tyTypeDesc}).kind notin if skipTypes(t.sons[0], abstractInst-{tyTypeDesc}).kind notin
{tyChar, tyEnum, tyInt..tyFloat128, tyUInt8..tyUInt32}: result = t {tyChar, tyEnum, tyInt..tyFloat128, tyUInt8..tyUInt32}: result = t
of tyOpenArray, tyVarargs, tySink: of tyOpenArray, tyVarargs, tySink:
if kind != skParam: # you cannot nest openArrays/sinks/etc.
if kind != skParam or taIsOpenArray in flags:
result = t result = t
else: else:
result = typeAllowedAux(marker, t.sons[0], skVar, flags) result = typeAllowedAux(marker, t.sons[0], kind, flags+{taIsOpenArray})
of tyUncheckedArray: of tyUncheckedArray:
if kind != skParam and taHeap notin flags: if kind != skParam and taHeap notin flags:
result = t result = t
else: else:
result = typeAllowedAux(marker, lastSon(t), kind, flags) result = typeAllowedAux(marker, lastSon(t), kind, flags-{taHeap})
of tySequence, tyOpt: of tySequence, tyOpt:
if t.sons[0].kind != tyEmpty: 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}: elif kind in {skVar, skLet}:
result = t.sons[0] result = t.sons[0]
of tyArray: of tyArray:
if t.sons[1].kind != tyEmpty: 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}: elif kind in {skVar, skLet}:
result = t.sons[1] result = t.sons[1]
of tyRef: of tyRef:
if kind == skConst: result = t 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: of tyPtr:
result = typeAllowedAux(marker, t.lastSon, skVar, flags+{taHeap}) result = typeAllowedAux(marker, t.lastSon, kind, flags+{taHeap})
of tySet: of tySet:
for i in 0 ..< sonsLen(t): for i in 0 ..< sonsLen(t):
result = typeAllowedAux(marker, t.sons[i], kind, flags) result = typeAllowedAux(marker, t.sons[i], kind, flags)
@ -1333,7 +1337,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
result = nil result = nil
of tyOwned: of tyOwned:
if t.len == 1 and t.sons[0].skipTypes(abstractInst).kind in {tyRef, tyPtr, tyProc}: 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: else:
result = t result = t

View file

@ -224,7 +224,7 @@ iterator fields*[T: tuple|object](x: T): RootObj {.
## **Warning**: This really transforms the 'for' and unrolls the loop. ## **Warning**: This really transforms the 'for' and unrolls the loop.
## The current implementation also has a bug ## The current implementation also has a bug
## that affects symbol binding in the loop body. ## 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.} magic: "Fields", noSideEffect.}
## Iterates over every field of `x` and `y`. ## Iterates over every field of `x` and `y`.
## ##
@ -266,7 +266,7 @@ iterator fieldPairs*[T: tuple|object](x: T): RootObj {.
## loop body. ## loop body.
iterator fieldPairs*[S: tuple|object, T: tuple|object](x: S, y: T): tuple[ iterator fieldPairs*[S: tuple|object, T: tuple|object](x: S, y: T): tuple[
a, b: untyped] {. a, b: RootObj] {.
magic: "FieldPairs", noSideEffect.} magic: "FieldPairs", noSideEffect.}
## Iterates over every field of `x` and `y`. ## Iterates over every field of `x` and `y`.
## ##

17
tests/errmsgs/t5870.nim Normal file
View file

@ -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