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
parent cd106cf680
commit 9203d3a982
4 changed files with 47 additions and 26 deletions

View File

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

View File

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

View File

@@ -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`.
##

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