fixes 5870 (#11704)
* fixes #5870 * make tclosure test green again * this check is correct but breaks some Nimble packages
This commit is contained in:
parent
cd106cf680
commit
9203d3a982
4 changed files with 47 additions and 26 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
else:
|
|
||||||
for i in 1 ..< sonsLen(t):
|
for i in 1 ..< sonsLen(t):
|
||||||
result = typeAllowedAux(marker, t.sons[i], skParam, flags)
|
result = typeAllowedAux(marker, t.sons[i], skParam, f)
|
||||||
if result != nil: break
|
if result != nil: break
|
||||||
if result.isNil and t.sons[0] != nil:
|
if result.isNil and t.sons[0] != nil:
|
||||||
result = typeAllowedAux(marker, t.sons[0], skResult, flags)
|
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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
17
tests/errmsgs/t5870.nim
Normal 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
|
||||||
Loading…
Add table
Add a link
Reference in a new issue