fixes tproctypecache_falsepositive.nim test case

This commit is contained in:
Araq 2017-06-08 18:35:37 +02:00
commit 4033929127
4 changed files with 28 additions and 3 deletions

View file

@ -88,7 +88,8 @@ proc sameInstantiation(a, b: TInstantiation): bool =
if a.concreteTypes.len == b.concreteTypes.len: if a.concreteTypes.len == b.concreteTypes.len:
for i in 0..a.concreteTypes.high: for i in 0..a.concreteTypes.high:
if not compareTypes(a.concreteTypes[i], b.concreteTypes[i], if not compareTypes(a.concreteTypes[i], b.concreteTypes[i],
flags = {ExactTypeDescValues}): return flags = {ExactTypeDescValues,
ExactGcSafety}): return
result = true result = true
proc genericCacheGet(genericSym: PSym, entry: TInstantiation; proc genericCacheGet(genericSym: PSym, entry: TInstantiation;

View file

@ -243,6 +243,7 @@ proc instCopyType*(cl: var TReplTypeVars, t: PType): PType =
proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType = proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
# tyGenericInvocation[A, tyGenericInvocation[A, B]] # tyGenericInvocation[A, tyGenericInvocation[A, B]]
# is difficult to handle: # is difficult to handle:
const eqFlags = eqTypeFlags + {tfGcSafe}
var body = t.sons[0] var body = t.sons[0]
if body.kind != tyGenericBody: internalError(cl.info, "no generic body") if body.kind != tyGenericBody: internalError(cl.info, "no generic body")
var header: PType = t var header: PType = t
@ -252,7 +253,7 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
else: else:
result = searchInstTypes(t) result = searchInstTypes(t)
if result != nil and eqTypeFlags*result.flags == eqTypeFlags*t.flags: return if result != nil and eqFlags*result.flags == eqFlags*t.flags: return
for i in countup(1, sonsLen(t) - 1): for i in countup(1, sonsLen(t) - 1):
var x = t.sons[i] var x = t.sons[i]
if x.kind in {tyGenericParam}: if x.kind in {tyGenericParam}:
@ -267,7 +268,7 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
if header != t: if header != t:
# search again after first pass: # search again after first pass:
result = searchInstTypes(header) result = searchInstTypes(header)
if result != nil and eqTypeFlags*result.flags == eqTypeFlags*t.flags: return if result != nil and eqFlags*result.flags == eqFlags*t.flags: return
else: else:
header = instCopyType(cl, t) header = instCopyType(cl, t)

View file

@ -139,6 +139,9 @@ proc getProcHeader*(sym: PSym; prefer: TPreferedDesc = preferName): string =
add(result, ')') add(result, ')')
if n.sons[0].typ != nil: if n.sons[0].typ != nil:
result.add(": " & typeToString(n.sons[0].typ, prefer)) result.add(": " & typeToString(n.sons[0].typ, prefer))
result.add "[declared in "
result.add($sym.info)
result.add "]"
proc elemType*(t: PType): PType = proc elemType*(t: PType): PType =
assert(t != nil) assert(t != nil)
@ -688,6 +691,7 @@ type
ExactTypeDescValues ExactTypeDescValues
ExactGenericParams ExactGenericParams
ExactConstraints ExactConstraints
ExactGcSafety
AllowCommonBase AllowCommonBase
TTypeCmpFlags* = set[TTypeCmpFlag] TTypeCmpFlags* = set[TTypeCmpFlag]
@ -976,6 +980,8 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
cycleCheck() cycleCheck()
if a.kind == tyUserTypeClass and a.n != nil: return a.n == b.n if a.kind == tyUserTypeClass and a.n != nil: return a.n == b.n
result = sameChildrenAux(a, b, c) and sameFlags(a, b) result = sameChildrenAux(a, b, c) and sameFlags(a, b)
if result and ExactGcSafety in c.flags:
result = a.flags * {tfThread} == b.flags * {tfThread}
if result and a.kind == tyProc: if result and a.kind == tyProc:
result = ((IgnoreCC in c.flags) or a.callConv == b.callConv) and result = ((IgnoreCC in c.flags) or a.callConv == b.callConv) and
((ExactConstraints notin c.flags) or sameConstraints(a.n, b.n)) ((ExactConstraints notin c.flags) or sameConstraints(a.n, b.n))

View file

@ -0,0 +1,17 @@
import asyncdispatch
type
Callback = proc() {.closure, gcsafe.}
GameState = ref object
playerChangeHandlers: seq[Callback]
#proc dummy() =
# var x = newSeq[proc() {.cdecl, gcsafe.}]()
proc newGameState(): GameState =
result = GameState(
playerChangeHandlers: newSeq[Callback]() # this fails
)
#dummy()